Вопрос или проблема
Я использовал одномерное кодирование [1,0,0][0,1,0][0,0,1] для своей функциональной модели классификации
.
Предсказанные вероятности для тестовых данных yprob = model.predict(testX)
дают мне :
yprob = array([[0.18120882, 0.5803128 , 0.22847839],
[0.0101245 , 0.12861261, 0.9612609 ],
[0.16332535, 0.4925239 , 0.35415074],
...,
[0.9931931 , 0.09328955, 0.01351734],
[0.48841736, 0.25034943, 0.16123319],
[0.3807928, 0.42698202, 0.27493873]], dtype=float32)
Я хотел бы вычислить точность, F1-меру и матрицу путаницы на основе этого.
Последовательный API предлагает функцию predict_classes
для этого.
yclasses = model.predict_classes(testX)
и, используя функцию f1_score из sklearn, мы могли бы вычислить все эти значения.
Как я мог бы применить это для предсказания вероятностей тестовых данных для многоклассовой многометочной классификации?
Мой второй вопрос заключается в том, соответствует ли наивысшее значение каждого массива yprob = model.predict(testX)
предсказанному классу? Например, [0.18120882, 0.5803128 , 0.22847839]
– это первый элемент в массиве. Наивысшее значение – 0.5803128
. Значит ли это, что оно соответствует одномерному кодированию [0, 1, 0], так что это вторая метка
, потому что это второй элемент в массиве?
Кажется, между многоклассовой и многометочной классификацией существует путаница:
- Многоклассовая классификация – это обычный случай, при котором задача состоит в том, чтобы предсказать среди N возможных классов. Например, изображение может быть либо собакой, либо лошадью, либо кошкой, но всегда ровно одним из этих трех животных.
- Многометочная классификация – это ситуация, когда задача состоит в предсказании множества. Например, изображение может быть любым подмножеством {собака, лошадь, кошка}: это может быть {собака, кошка}, это может быть {лошадь}, это может быть {собака, лошадь, кошка}, это может даже быть пустое множество (ни одного животного).
Практически в случае многометочной классификации вы предсказываете каждое возможное животное независимо как бинарную задачу, поэтому для каждого изображения система отвечает на 3 вопроса:
- содержит ли это изображение собаку? (да/нет)
- содержит ли это изображение лошадь? (да/нет)
- содержит ли это изображение кошку? (да/нет)
Поскольку каждый вопрос предсказывается независимо, нет смысла выбирать класс с максимальной вероятностью. На деле существует 3 независимые задачи бинарной классификации и 3 соответствующие матрицы путаницы.
Похоже, вы не собирались учитывать случай многометочной классификации и у вас нет ни одного изображения с несколькими животными, верно? Если это так, вам следует изменить систему для решения обычной многоклассовой задачи.
Похоже, путаница может быть вызвана одномерным кодированием класса: возможно, вы думали, что класс является категориальным, поэтому было бы ошибкой кодировать класс как числовое значение. Это верно для категориальных признаков, но на самом деле не для целевой переменной, вы можете прекрасно использовать, например, LabelEncoder для представления класса как одной целевой переменной. Это намного проще и, вероятно, более уместно для вашей задачи.
Одно отличие, которое вы заметите, заключается в том, что вероятности, полученные в качестве предсказаний, в сумме составляют один, потому что классификатор не рассматривает классы как независимые (в отличие от того, что происходит в вашем текущем эксперименте: вероятности не суммируются до 1).
Ответ или решение
Чтобы вычислить F1-меру для многоклассовой многометочной классификации, необходимо учесть ряд аспектов, связанных с вашей моделью, форматом данных и способами оценки точности предсказаний.
Понимание задачи
Ваша задача, как вы правильно заметили, относится к многоклассовой и многометочной классификации. Однако в контексте, который вы описали, более корректным будет рассматривать вашу задачу как многоклассовую классификацию, где каждая входная выборка может быть отнесена только к одному классу.
Если вы используете One-Hot Encoding для представления меток классов, и ваши предсказания представляют собой вероятности классов для каждой выборки, следующий шаг включает преобразование вероятностей в классы. Для этого можно использовать функцию predict_classes
, которую предлагает модель.
Преобразование вероятностей в классы
Вы правильно предположили, что для получения окончательных классов из вероятностей, вам необходимо выбрать класс с максимальной вероятностью для каждой выборки. Например, для аранжированного массива вероятностей [0.18120882, 0.5803128, 0.22847839]
это будет значение 0.5803128
, которое соответствует классу с индексом 1
(то есть второй метке в One-Hot Encoding).
Вычисление F1-меры
Теперь, чтобы рассчитать F1-меру, вы можете воспользоваться библиотекой scikit-learn
. Процесс будет выглядеть следующим образом:
-
Импорт необходимых библиотек:
from sklearn.preprocessing import OneHotEncoder from sklearn.metrics import f1_score, accuracy_score, confusion_matrix import numpy as np
-
Создание массива истинных меток (если вы уже имеете истинные метки в формате One-Hot Encoding):
# Пример истинных меток y_true = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
-
Получение предсказанных меток:
y_prob = model.predict(testX) # Преобразуем вероятности в классы y_pred = (y_prob >= 0.5).astype(int) # Можете менять порог, например, 0.5
-
Вычисление F1-меры, точности и матрицы путаницы:
f1 = f1_score(y_true, y_pred, average='macro') accuracy = accuracy_score(y_true, y_pred) conf_matrix = confusion_matrix(y_true.argmax(axis=1), y_pred.argmax(axis=1))
Целостное решение вместе с принятыми параметрами может выглядеть таким образом:
print("F1 Score: ", f1) print("Accuracy: ", accuracy) print("Confusion Matrix:\n", conf_matrix)
Заключение
Вам необходимо учитывать различия между многоклассовыми и многометочными задачами, чтобы корректно интерпретировать свои результаты. В вашем случае, для многоклассовой классификации с одним правильным ответом стоит использовать подход с выбором класса с максимальными вероятностями. Убедитесь, что ваши метки и входные данные корректно структурированы для получения адекватных результатов.
Если у вас возникли вопросы или требуется дополнительная помощь, не стесняйтесь обращаться.