Отчет по метрикам SKLEARN: “Количество классов, 28, не соответствует размеру target_names, 35. Попробуйте указать параметр labels.”

Вопрос или проблема

Как правильно определить метки или имена целевых классов для 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)

Дополнительные рекомендации

  1. Убедитесь, что ваши предсказания и истинные метки имеют одинаковую длину: n_samples.
  2. Использование параметра labels:
    Если вы все же хотите использовать параметр labels, убедитесь, что вы передаете правильный набор меток, который присутствует в ваших данных. Это может быть полезно, если количество меток в ваших данных меньше, чем общее количество классов.

Пример использования параметра labels

Если в вашем случае определенные метки (например, 25, 27, 30, 31, 32) отсутствуют в данных, просто рассмотрите оставшиеся метки, чтобы избежать появления пустых строк в отчете:

labels = unique_labels_set  # или список меток, которые хотите использовать
report = metrics.classification_report(true_labels, predicted_labels, labels=labels)
print(report)

Заключение

С помощью предложенных шагов вы сможете корректно сформировать отчет, избегая ошибок, связанных с несовпадением количества классов и имен целевых переменных. Если у вас возникнут дополнительные вопросы или потребуются уточнения, не стесняйтесь задавать их.

Оцените материал
Добавить комментарий

Капча загружается...