[PYTHON] ROC-Kurve für die Klassifizierung mehrerer Klassen

Zweck

Ein Memorandum zum Zeichnen von ROC-Kurven durch Lesen vorhergesagter Werte der Mehrklassenklassifizierung, die im xlsx- oder csv-Format mit Pandas gespeichert wurden. Ich übe auch das Schreiben von Artikeln für Qiita.

Über die ROC-Kurve

Ich werde in diesem Artikel nicht auf die Grundlagen eingehen. In Bezug auf die Geschichte der ROC-Kurve ist der Artikel hier leicht zu verstehen.

Änderung des Etikettenformats

Überprüfen Sie zunächst das Datenformat. pandas1.JPG --GT hat numerische Werte von 0, 1, 2 und entspricht jedem Etikett.

Die ROC-Kurve muss in eine 0, 1-Binärdatei konvertiert werden

from sklearn.preprocessing import label_binarize
y_test = label_binarize(df.iloc[:, 0], classes=[0,1,2])

Verwenden Sie sklearns label_binarize für die binäre Konvertierung. binary.JPG Es ist etwas lang, also nur der obere Teil. Infolge der binären Umwandlung ist C1 = [1, 0, 0], C2 = [0, 1, 0], C3 = [0, 0, 1].

Liste der vorhergesagten Werte

Nach der Binärisierung der Beschriftungen müssen auch die vorhergesagten Werte für jedes Modell in die entsprechende Liste konvertiert werden.

M1_y_score = []
M2_y_score = []
M3_y_score = []
for i in df.index:
    M1_y_score.append(([df.iloc[i, 1], df.iloc[i, 2], df.iloc[i, 3]]))
    M2_y_score.append(([df.iloc[i, 4], df.iloc[i, 5], df.iloc[i, 6]]))
    M3_y_score.append(([df.iloc[i, 7], df.iloc[i, 8], df.iloc[i, 9]]))
M1_y_score = M1_y_score
M2_y_score = M2_y_score
M3_y_score = M3_y_score

So habe ich die Schleifenverarbeitung ausgeführt und den vorhergesagten Wert gespeichert. An diesem Punkt,

from sklearn.metrics import roc_auc_score
auc_m1 = roc_auc_score(y_test, M1_y_score, multi_class="ovo")
print(auc_m1)

Sie können eine AUC für mehrere Klassen finden, indem Sie sie eingeben. Das Argument multi_class scheint einen Fehler auszulösen, wenn Sie weder "ovo" noch "ovr" setzen. Weitere Informationen finden Sie in der sklearn-Dokumentation .

Berechnung von FPR und TPR

Dieser Teil ist gerade gestolpert.

M1_fpr = dict()
M1_tpr = dict()
M1_roc_auc = dict()
M2_fpr = dict()
M2_tpr = dict()
M2_roc_auc = dict()
M3_fpr = dict()
M3_tpr = dict()
M3_roc_auc = dict()

Nach dem Erstellen eines leeren Wörterbuchs zum Speichern der Daten

n_class = 3
from sklearn.metrics import roc_curve, auc
for i in range(n_classes):
    M1_fpr[i], M1_tpr[i], _ = roc_curve(y_test[:, i], M1_y_score[:, i])
    M1_roc_auc[i] = auc(M1_fpr[i], M1_tpr[i])

    M2_fpr[i], M2_tpr[i], _ = roc_curve(y_test[:, i], M2_y_score[:, i])
    M2_roc_auc[i] = auc(M2_fpr[i], M2_tpr[i])

    M3_fpr[i], M3_tpr[i], _ = roc_curve(y_test[:, i], M3_y_score[:, i])
    M3_roc_auc[i] = auc(M3_fpr[i], M3_tpr[i])

Ich durchlaufe die Anzahl der Etiketten und speichere die fpr und tpr jedes Modells. error1.JPG Ich bekomme aus irgendeinem Grund eine Fehlermeldung! Das lag daran, dass ich es beim Speichern der vorhergesagten Werte nicht zu einem ndarray gemacht habe. Ändern Sie also den obigen Code ein wenig ...

M1_y_score = np.array(M1_y_score)
M2_y_score = np.array(M2_y_score)
M3_y_score = np.array(M3_y_score)

Indem Sie es zu einem ndarray-Typ machen, ist es jetzt möglich, Daten in einem Wörterbuch zu speichern. Wenn Sie danach gemäß dem offiziellen Dokument codieren, ist es in Ordnung!

M1_all_fpr = np.unique(np.concatenate([M1_fpr[i] for i in range(n_classes)]))
M2_all_fpr = np.unique(np.concatenate([M2_fpr[i] for i in range(n_classes)]))
M3_all_fpr = np.unique(np.concatenate([M3_fpr[i] for i in range(n_classes)]))
M1_mean_tpr = np.zeros_like(M1_all_fpr)
M2_mean_tpr = np.zeros_like(M2_all_fpr)
M3_mean_tpr = np.zeros_like(M3_all_fpr)

for i in range(n_classes):
    M1_mean_tpr += np.interp(M1_all_fpr, M1_fpr[i], M1_tpr[i])
    M2_mean_tpr += np.interp(M2_all_fpr, M2_fpr[i], M2_tpr[i])
    M3_mean_tpr += np.interp(M3_all_fpr, M3_fpr[i], M3_tpr[i])

M1_mean_tpr /= n_classes
M2_mean_tpr /= n_classes
M3_mean_tpr /= n_classes

M1_fpr["macro"] = M1_all_fpr
M1_tpr["macro"] = M1_mean_tpr
M1_roc_auc["macro"] = auc(M1_fpr["macro"], M1_tpr["macro"])

M2_fpr["macro"] = M2_all_fpr
M2_tpr["macro"] = M2_mean_tpr
M2_roc_auc["macro"] = auc(M2_fpr["macro"], M2_tpr["macro"])

M3_fpr["macro"] = M3_all_fpr
M3_tpr["macro"] = M3_mean_tpr
M3_roc_auc["macro"] = auc(M3_fpr["macro"], M3_tpr["macro"])

ROC-Kurvenzeichnung

Sobald dies erledigt ist, müssen Sie es nur noch mit matplotlib grafisch darstellen.

import matplotlib.pyplot as plt
from matplotlib import cm
lw=1
colors = [cm.gist_ncar(190), cm.gist_ncar(30), cm.gist_ncar(10)]
sns.color_palette(colors)
sns.set_palette(colors, desat=1.0)

plt.figure(figsize=(6, 6))

plt.plot(M1_fpr["macro"], M1_tpr["macro"],
         label='M1',
         color=colors[0], 
         linestyle='-', 
         linewidth=2)

plt.plot(M2_fpr["macro"], M2_tpr["macro"],
         label='M2',
         color=colors[1], 
         linestyle='-', 
         linewidth=2)

plt.plot(M3_fpr["macro"], M3_tpr["macro"],
         label='M3',
         color=colors[2], 
         linestyle='-', 
         linewidth=2)

plt.plot([0, 1], [0, 1], 'k--', lw=lw)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.legend(loc="lower right")
plt.show()

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784518/0a44adaf-50eb-9bd7-55bc-1a7a0adaf28b.jpeg ", width=50%)> Ich konnte eine ROC-Kurve mit mehreren Klassen unter Verwendung von Makro-Durchschnittswerten zeichnen.

Recommended Posts

ROC-Kurve für die Klassifizierung mehrerer Klassen
Zeichnen Sie die ROC-Kurve für die binäre Klassifizierung mit Matplotlib
SVM (Mehrklassenklassifikation)
Naive Buchten (Mehrklassenklassifikation)
Keras Multiklassenklassifikation Iris
K Nachbarschaftsmethode (Mehrklassenklassifikation)
CNN (1) zur Bildklassifizierung (für Anfänger)
ROC-Kurve und PR-Kurve - Verstehen, wie die Klassifizierungsleistung bewertet wird ②-