Вопрос или проблема
Как правильно определить метки или имена целевых классов для classification_report?
У меня есть отчет, который выглядит так:
print(metrics.classification_report(twenty_test.target[:n_samples], predicted, target_names=twenty_test.target_names))
Я заметил, что получаю ошибку, как в заголовке, или что-то подобное, когда twenty_test.target[:n_samples] (или, возможно, также массив predicted) имеет другую длину, чем twenty_test.target_names…
Это не работает “из коробки”, если я просто предоставляю все имена целевых классов (также те, которые не включены в массив “target” или “predicted”, если я предоставляю их как параметр “target_names”).
Но если я предоставляю их как параметр “labels”, как намекнули, я просто вижу отчет, заполненный нулями.
Кстати, это вывод уникальных значений массива “target”:
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 25}
Это вывод массива predicted (уникальные значения):
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 25, 27, 30, 31, 32}
Я пытался получить более длинный список этих значений и построить список самого длинного значения так:
longer = max(max(set(predicted)), max(set(twenty_test.target[:n_samples])))+1
print(metrics.classification_report(twenty_test.target[:n_samples], predicted, target_names=twenty_test.target_names[:longer])
Не работает. Я ожидал, что все названия целевых классов, даже те, которые не включены, будут работать “из коробки”.
Я пытался исправить это таким образом, не уверен, правильно ли это.
from sklearn.utils.multiclass import unique_labels
target_names_filtered = [twenty_test.target_names[i] for i in unique_labels(twenty_test.target[:n_samples], predicted)]
Затем я использовал target_names_filtered как параметр target_names.
Ответ или решение
Ошибка, с которой вы столкнулись, возникает из-за несоответствия между количеством классов, которые вы используете в своем отчете, и количеством названий классов, которые вы передаете в параметре target_names
. Давайте проясним, как правильно определять метки или имена целей в classification_report
от sklearn
, а также решим вашу проблему.
Шаг 1: Определение уникальных меток
Сначала стоит убедиться, что вы используете уникальные метки из ваших данных истинных и предсказанных значений. Для этого вы можете воспользоваться функцией unique_labels
из sklearn.utils
, которая позволяет извлечь уникальные метки из массивов с целями.
from sklearn.utils.multiclass import unique_labels
# Извлечение уникальных меток
true_labels = twenty_test.target[:n_samples]
predicted_labels = predicted
unique_labels_set = unique_labels(true_labels, predicted_labels)
Шаг 2: Фильтрация имен классов
Как только вы извлекли уникальные метки, вы можете использовать их для фильтрации имен классов из twenty_test.target_names
. Обратите внимание, что индексы для фильтрации должны быть в пределах размера twenty_test.target_names
.
# Фильтрация имен классов на основе уникальных меток
target_names_filtered = [twenty_test.target_names[i] for i in unique_labels_set if i < len(twenty_test.target_names)]
Шаг 3: Генерация отчета
Теперь вы можете сгенерировать отчет, передавая отфильтрованные имена классов в параметре target_names
.
from sklearn import metrics
# Генерация отчета
report = metrics.classification_report(true_labels, predicted_labels, target_names=target_names_filtered)
print(report)
Дополнительные рекомендации
- Убедитесь, что ваши предсказания и истинные метки имеют одинаковую длину:
n_samples
. - Использование параметра
labels
:
Если вы все же хотите использовать параметрlabels
, убедитесь, что вы передаете правильный набор меток, который присутствует в ваших данных. Это может быть полезно, если количество меток в ваших данных меньше, чем общее количество классов.
Пример использования параметра labels
Если в вашем случае определенные метки (например, 25, 27, 30, 31, 32) отсутствуют в данных, просто рассмотрите оставшиеся метки, чтобы избежать появления пустых строк в отчете:
labels = unique_labels_set # или список меток, которые хотите использовать
report = metrics.classification_report(true_labels, predicted_labels, labels=labels)
print(report)
Заключение
С помощью предложенных шагов вы сможете корректно сформировать отчет, избегая ошибок, связанных с несовпадением количества классов и имен целевых переменных. Если у вас возникнут дополнительные вопросы или потребуются уточнения, не стесняйтесь задавать их.