Python: как нормализовать матрицу путаницы?
Я вычислил матрицу путаницы для моего классификатора, используя метод confusion_matrix() из пакета sklearn. Диагональные элементы матрицы путаницы представляют собой число точек, для которых предсказанная метка равна истинной метке, в то время как недиагональные элементы - это те, которые неверно маркированы классификатором.
Я хотел бы нормализовать свою матрицу путаницы, чтобы она содержала только числа от 0 до 1. Я хотел бы прочитать процент правильно классифицированных образцов из матрицы.
Я нашел несколько методов, как нормализовать матрицу (нормализация строк и столбцов), но я мало знаю о математике и не уверен, что это правильный подход. Может кто-нибудь помочь?
Ответы
Ответ 1
Я предполагаю, что M[i,j]
означает Element of real class i was classified as j
. Если это будет наоборот, вам нужно будет транспонировать все, что я говорю. Я также собираюсь использовать следующую матрицу для конкретных примеров:
1 2 3
4 5 6
7 8 9
Есть две вещи, которые вы можете сделать:
Поиск того, как классифицирован каждый класс
Первое, что вы можете задать, это то, что процент элементов реального класса i
здесь классифицируется как каждый класс. Для этого возьмем строку, фиксирующую i
, и разделим каждый элемент на сумму элементов в строке. В нашем примере объекты класса 2 классифицируются как класс 1 4 раза, классифицируются как класс 2 5 раз и классифицируются как класс 3 6 раз. Чтобы найти проценты, мы просто делим все на сумму 4 + 5 + 6 = 15
4/15 of the class 2 objects are classified as class 1
5/15 of the class 2 objects are classified as class 2
6/15 of the class 2 objects are classified as class 3
Поиск классов, ответственных за каждую классификацию
Второе, что вы можете сделать, это посмотреть на каждый результат из вашего классификатора и спросить, сколько из этих результатов происходит из каждого реального класса. Это будет похоже на другой случай, но с столбцами вместо строк. В нашем примере наш классификатор возвращает "1" 1 раз, когда исходный класс равен 1, 4 раза, когда исходный класс равен 2 и 7 раз, когда исходный класс равен 3. Чтобы найти проценты, мы делим на сумму 1 + 4 + 7 = 12
1/12 of the objects classified as class 1 were from class 1
4/12 of the objects classified as class 1 were from class 2
7/12 of the objects classified as class 1 were from class 3
-
Конечно, оба метода, которые я дал, применимы только к столбцу с одной строкой за раз, и я не уверен, было бы хорошей идеей реально изменить вашу матрицу путаницы в этой форме. Тем не менее, это должно дать проценты, которые вы ищете.
Ответ 2
Предположим, что
>>> y_true = [0, 0, 1, 1, 2, 0, 1]
>>> y_pred = [0, 1, 0, 1, 2, 2, 1]
>>> C = confusion_matrix(y_true, y_pred)
>>> C
array([[1, 1, 1],
[1, 2, 0],
[0, 0, 1]])
Затем, чтобы узнать, сколько образцов в классе получили их правильную метку, вам нужно
>>> C / C.astype(np.float).sum(axis=1)
array([[ 0.33333333, 0.33333333, 1. ],
[ 0.33333333, 0.66666667, 0. ],
[ 0. , 0. , 1. ]])
Диагональ содержит требуемые значения. Другой способ вычислить это - понять, что вы вычисляете вызов на класс:
>>> from sklearn.metrics import precision_recall_fscore_support
>>> _, recall, _, _ = precision_recall_fscore_support(y_true, y_pred)
>>> recall
array([ 0.33333333, 0.66666667, 1. ])
Аналогично, если вы разделите сумму на axis=0
, вы получите точность (доля предсказаний класса k
с меткой истины истины k
):
>>> C / C.astype(np.float).sum(axis=0)
array([[ 0.5 , 0.33333333, 0.5 ],
[ 0.5 , 0.66666667, 0. ],
[ 0. , 0. , 0.5 ]])
>>> prec, _, _, _ = precision_recall_fscore_support(y_true, y_pred)
>>> prec
array([ 0.5 , 0.66666667, 0.5 ])
Ответ 3
Матричный вывод с помощью sklearn confusion_matrix()
равен таким образом, что
C_ {i, j} равно числу наблюдений, которые, как известно, находятся в группе я но предсказано, что он находится в группе j
чтобы получить проценты для каждого класса (часто называемого специфичностью и чувствительностью в двоичной классификации), вам нужно нормализовать по строке: заменить каждый элемент в строке сам по себе, деленный на сумму элементов этой строки.
Обратите внимание, что у sklearn есть сводная функция, которая вычисляет метрики из матрицы путаницы: class_report. Он выводит точность и отзыв, а не специфичность и чувствительность, но они часто рассматриваются как более информативные в целом (особенно для несбалансированной многоклассовой классификации).
Ответ 4
Из документации по sklearn (пример графика)
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
где см - матрица путаницы, предоставленная sklearn.
Ответ 5
Есть библиотека, предоставленная самим scikit-learn для построения графиков. Он основан на matplotlib и должен быть уже установлен, чтобы продолжить.
pip install scikit-plot
Теперь просто установите параметр нормализации на true:
import scikitplot as skplt
skplt.metrics.plot_confusion_matrix(Y_TRUE, Y_PRED, normalize=True)
Ответ 6
Используя Seaborn, вы можете легко распечатать нормализованную и довольно запутанную матрицу с картой пустотности:
![enter image description here]()
from sklearn.metrics import confusion_matrix
import seaborn as sns
cm = confusion_matrix(y_test, y_pred)
# Normalise
cmn = cm.astype('float') /
cm.sum(axis=1)[:, np.newaxis]
fig, ax = plt.subplots(figsize=(10,10))
sns.heatmap(cmn, annot=True, fmt='.2f', xticklabels=target_names, yticklabels=target_names)
plt.ylabel('Actual')
plt.xlabel('Predicted')
plt.show(block=False)
Ответ 7
Я думаю, что самый простой способ сделать это, сделав:
c = sklearn.metrics.confusion_matrix(y, y_pred)
normed_c = (c.T / c.astype(np.float).sum(axis=1)).T