Как я могу интерпретировать матрицу путаницы Склеарн


24

Я использую матрицу путаницы, чтобы проверить производительность моего классификатора.

Я использую Scikit-Learn, я немного запутался. Как я могу интерпретировать результат от

from sklearn.metrics import confusion_matrix
>>> y_true = [2, 0, 2, 2, 0, 1]
>>> y_pred = [0, 0, 2, 2, 0, 2]
>>> confusion_matrix(y_true, y_pred)
array([[2, 0, 0],
       [0, 0, 1],
       [1, 0, 2]])

Как я могу принять решение, являются ли эти прогнозируемые значения хорошими или нет.


1
Сначала забудь про склеарн, это красная селедка. Источник вашего недоразумения кажется более фундаментальным. Посмотрите здесь: en.wikipedia.org/wiki/Confusion_matrix . Сосредоточьтесь на повествовании о примере 3 * 3 на странице Википедии. Скорее всего, это поможет решить проблему с вашей путаницей.
Жубарб

Ответы:


47

Матрица путаницы - это способ подсчета количества ошибочных классификаций, т. Е. Количества предсказанных классов, которые оказались в неправильном классификационном бункере на основе истинных классов.

Хотя sklearn.metrics.confusion_matrix предоставляет числовую матрицу, я считаю более полезным генерировать «отчет» с использованием следующего:

import pandas as pd
y_true = pd.Series([2, 0, 2, 2, 0, 1, 1, 2, 2, 0, 1, 2])
y_pred = pd.Series([0, 0, 2, 1, 0, 2, 1, 0, 2, 0, 2, 2])

pd.crosstab(y_true, y_pred, rownames=['True'], colnames=['Predicted'], margins=True)

что приводит к:

Predicted  0  1  2  All
True                   
0          3  0  0    3
1          0  1  2    3
2          2  1  3    6
All        5  2  5   12

Это позволяет нам увидеть, что:

  1. Диагональные элементы показывают количество правильных классификаций для каждого класса: 3, 1 и 3 для классов 0, 1 и 2.
  2. Недиагональные элементы обеспечивают неправильную классификацию: например, 2 класса 2 были ошибочно классифицированы как 0, ни один из класса 0 не был ошибочно классифицирован как 2 и т. Д.
  3. Общее количество классификаций для каждого класса в обоих y_trueи y_predиз промежуточных итогов "Все"

Этот метод также работает для текстовых меток, и для большого количества выборок в наборе данных его можно расширить для предоставления отчетов в процентах.

import numpy as np
import pandas as pd

# create some data
lookup = {0: 'biscuit', 1:'candy', 2:'chocolate', 3:'praline', 4:'cake', 5:'shortbread'}
y_true = pd.Series([lookup[_] for _ in np.random.random_integers(0, 5, size=100)])
y_pred = pd.Series([lookup[_] for _ in np.random.random_integers(0, 5, size=100)])

pd.crosstab(y_true, y_pred, rownames=['True'], colnames=['Predicted']).apply(lambda r: 100.0 * r/r.sum())

Выходные данные тогда:

Predicted     biscuit  cake      candy  chocolate    praline  shortbread
True                                                                    
biscuit     23.529412    10  23.076923  13.333333  15.384615    9.090909
cake        17.647059    20   0.000000  26.666667  15.384615   18.181818
candy       11.764706    20  23.076923  13.333333  23.076923   31.818182
chocolate   11.764706     5  15.384615   6.666667  15.384615   13.636364
praline     17.647059    10  30.769231  20.000000   0.000000   13.636364
shortbread  17.647059    35   7.692308  20.000000  30.769231   13.636364

где числа теперь представляют процент (а не количество случаев) результатов, которые были классифицированы.

Хотя обратите внимание, что sklearn.metrics.confusion_matrixвывод может быть непосредственно визуализирован с помощью:

import matplotlib.pyplot as plt
conf = sklearn.metrics.confusion_matrix(y_true, y_pred)
plt.imshow(conf, cmap='binary', interpolation='None')
plt.show()

4
Добро пожаловать на наш сайт! Я ценю заботу и качество, которые вы вложили в свой первый ответ здесь.
whuber

1
Первый пример больше не работает, по крайней мере, с pandas-0.13.1. Я только что обновился до pandas-0.16.0 и все еще получаю ту же ошибку:AssertionError: arrays and names must have the same length
chbrown

1
@chbrown: похоже, что-то изменилось в пандах, которые должны быть массивом или серией. Я обновил пример кода для использования y_pred = pd.Series(...). Это должно работать сейчас.
achennu

5

На оси ординат по оси Y имеются действительные значения, а по оси X - значения, заданные предиктором. Следовательно, числа на диагонали - это количество правильных предсказаний. А элементы диагонали являются неверными предсказаниями.

В твоем случае:

>>> confusion_matrix(y_true, y_pred)
    array([[2, 0, 0],  # two zeros were predicted as zeros
           [0, 0, 1],  # one 1 was predicted as 2
           [1, 0, 2]]) # two 2s were predicted as 2, and one 2 was 0

Это немного сбивает с толку (вы сказали, что «# 1 1 было предсказано как 2», а по диагонали - 0), у меня есть матрица из 50 КБ, немного сложно спроецировать все значения. Есть ли метрика, чтобы дать мне эти результаты напрямую? (Я имею в виду, получаю ли я хорошую путаницу или нет).
user3378649

1
Вы можете посмотреть на элементы по диагонали, это ваши правильные предсказания, недиагональные элементы - это неправильные предсказания. Это начало.
Akavall

Я получил два разных результата. В цели у нас есть две метки «0» или «1». Можете ли вы помочь дать подсказку, как интерпретировать эти результаты. - confusion_matrix: [[0 85723] [0 77]] - confusion_matrix: [[85648 75] [75 2]]
user3378649

1

Я хотел бы указать графически необходимость понять это. Это простая матрица, которую нужно хорошо понять, прежде чем делать выводы. Итак, вот упрощенная объяснимая версия приведенных выше ответов.

        0  1  2   <- Predicted
     0 [2, 0, 0]  
TRUE 1 [0, 0, 1]  
     2 [1, 0, 2] 

# At 0,0: True value was 0, Predicted value was 0, - 2 times predicted
# At 1,1: True value was 1, Predicted value was 1, - 0 times predicted
# At 2,2: True value was 2, Predicted value was 2, - 2 times predicted
# At 1,2: True value was 1, Predicted value was 2, - 1 time predicted
# At 2,0: True value was 2, Predicted value was 0, - 1 time predicted...
...Like that

4
Не могли бы вы отредактировать это, чтобы сказать, что, по вашему мнению, оно выходит за рамки уже предоставленных ответов?
18:30

1
Привет! Я только что сослался на ответ Акавалла. Он упомянул мышление. Я только что объяснил его ответ, который имеет тенденцию быть правильным, по-видимому, лучше.
Пранцелл,

@Pranzell Не могли бы вы поделиться своим кодом, чтобы нарисовать такую ​​красивую текстовую таблицу?
фу DL
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.