Wie kann ich die Sklearn-Verwirrungsmatrix interpretieren?

24

Ich verwende eine Verwirrungsmatrix , um die Leistung meines Klassifikators zu überprüfen.

Ich benutze Scikit-Learn und bin etwas verwirrt. Wie kann ich das Ergebnis von interpretieren?

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]])

Wie kann ich die Entscheidung treffen, ob diese vorhergesagten Werte gut sind oder nicht?

user3378649
quelle
1
Vergiss zunächst sklearn, das ist ein roter Hering. Die Ursache Ihres Missverständnisses scheint grundlegender zu sein. Schau mal hier: de.wikipedia.org/wiki/Confusion_matrix . Konzentrieren Sie sich auf die Erzählung des 3 * 3-Beispiels auf der Wikipedia-Seite. Das wird höchstwahrscheinlich Ihre Verwirrung beseitigen.
Zhubarb
Ein relevanter Thread: stats.stackexchange.com/a/340079/121522
mkt - Monica

Antworten:

47

Mit der Verwirrungsmatrix kann die Anzahl der Fehlklassifizierungen, dh die Anzahl der vorhergesagten Klassen, die auf der Grundlage der wahren Klassen in einen falschen Klassifizierungsbereich gelangt sind, tabellarisch dargestellt werden.

Während sklearn.metrics.confusion_matrix eine numerische Matrix bereitstellt, finde ich es sinnvoller, einen "Bericht" mit den folgenden Methoden zu erstellen:

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)

was in ... endet:

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

Dies ermöglicht es uns zu sehen, dass:

  1. Die diagonalen Elemente zeigen die Anzahl der korrekten Klassifikationen für jede Klasse: 3, 1 und 3 für die Klassen 0, 1 und 2.
  2. Die nicht diagonalen Elemente liefern die Fehlklassifizierungen: Zum Beispiel wurden 2 der Klasse 2 als 0, keine der Klasse 0 als 2 usw. falsch klassifiziert.
  3. Die Gesamtzahl der Klassifizierungen für jede Klasse in beiden y_trueund y_predaus den Zwischensummen "Alle"

Diese Methode funktioniert auch für Textbeschriftungen und kann für eine große Anzahl von Beispielen im Dataset erweitert werden, um Prozentberichte bereitzustellen.

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())

Die Ausgabe ist dann:

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

wobei die Zahlen jetzt den Prozentsatz (und nicht die Anzahl der Fälle) der klassifizierten Ergebnisse darstellen.

Beachten Sie jedoch, dass die sklearn.metrics.confusion_matrixAusgabe direkt visualisiert werden kann mit:

import matplotlib.pyplot as plt
conf = sklearn.metrics.confusion_matrix(y_true, y_pred)
plt.imshow(conf, cmap='binary', interpolation='None')
plt.show()
Achennu
quelle
4
Willkommen auf unserer Webseite! Ich schätze die Sorgfalt und Qualität, die Sie hier in Ihre erste Antwort gesteckt haben.
Whuber
1
Das erste Beispiel funktioniert zumindest ab pandas-0.13.1 nicht mehr. Ich habe gerade ein Upgrade auf pandas-0.16.0 durchgeführt und erhalte immer noch den gleichen Fehler:AssertionError: arrays and names must have the same length
chbrown 17.04.15
1
@chbrown: Es scheint, als hätte sich etwas in Pandas geändert, die sitzen müssen, um ein Array oder eine Serie zu sein. Ich habe den zu verwendenden Beispielcode aktualisiert y_pred = pd.Series(...). Das sollte jetzt funktionieren.
achennu
5

Auf der y-Achse hat die Verwirrungsmatrix die tatsächlichen Werte und auf der x-Achse die vom Prädiktor angegebenen Werte. Daher sind die Zählungen auf der Diagonale die Anzahl der korrekten Vorhersagen. Und Elemente der Diagonale sind falsche Vorhersagen.

In Ihrem Fall:

>>> 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
Akavall
quelle
Es ist ein bisschen verwirrend (Sie sagten, "# eins 1 wurde als 2 vorhergesagt" - während in der Diagonale 0 ist), ich habe eine Matrix von 50K-Elementen, es ist ein bisschen schwierig, alle Werte zu projizieren. Gibt es eine Metrik, mit der ich diese Ergebnisse direkt erhalten kann? (Ich meine, wenn ich eine gute Verwirrungsmatrix bekomme oder nicht).
user3378649
1
Sie könnten Elemente auf der Diagonale betrachten, das sind Ihre korrekten Vorhersagen, Elemente außerhalb der Diagonale sind falsche Vorhersagen. Das ist ein Anfang.
Akavall
Ich habe zwei verschiedene Ergebnisse. Im Ziel haben wir zwei Bezeichnungen '0' oder '1'. Können Sie uns helfen, einen Hinweis zu geben, wie diese Ergebnisse interpretiert werden können? - confusion_matrix: [[0 85723] [0 77]] - confusion_matrix: [[85648 75] [75 2]]
user3378649
1

Ich möchte die Notwendigkeit, dies zu verstehen, grafisch spezifizieren. Es ist eine einfache Matrix, die gut verstanden werden muss, bevor man zu Schlussfolgerungen kommt. Hier ist eine vereinfachte, erklärbare Version der obigen Antworten.

        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
Pranzell
quelle
4
Könnten Sie das bearbeiten, um zu sagen, wie Sie denken, dass es über die bereits gegebenen Antworten hinausgeht?
mdewey
1
Hallo! Ich habe gerade auf Akavalls Antwort hingewiesen. Er hat das Denken erwähnt. Ich habe gerade seine Antwort, die tendenziell die richtige ist, vermutlich besser erklärt.
Pranzell
@Pranzell Teilen Sie uns bitte Ihren Code mit, um eine so schöne textbasierte Tabelle zu zeichnen.
Fu DL