Scikit-learn: sklearn.metrics.classification_report falsch?

Erstellt am 1. Apr. 2020  ·  3Kommentare  ·  Quelle: scikit-learn/scikit-learn

Beschreibe den Fehler

sklearn.metrics.classification kann gespiegelte Werte für Präzision und Rückruf melden?

Schritte / Code zum Reproduzieren

from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.neighbors import KNeighborsClassifier
from sklearn import datasets

def calc_precision_recall(conf_matrix, class_labels):

    # for each class
    for i in range(len(class_labels)):

        # calculate true positives
        true_positives =(conf_matrix[i, i])

        # false positives
        false_positives = (conf_matrix[i, :].sum() - true_positives)

        # false negatives
        false_negatives = 0
        for j in range(len(class_labels)):
            false_negatives += conf_matrix[j, i]
        false_negatives -= true_positives

        # and finally true negatives
        true_negatives= (conf_matrix.sum() - false_positives - false_negatives - true_positives)

        # print calculated values
        print(
            "Class label", class_labels[i],
            "T_positive", true_positives,
            "F_positive", false_positives,
            "T_negative", true_negatives,
            "F_negative", false_negatives,
            "\nSensitivity/recall", true_positives / (true_positives + false_negatives),
            "Specificity", true_negatives / (true_negatives + false_positives),
            "Precision", true_positives/(true_positives+false_positives), "\n"
        )

    return

# import some data to play with
iris = datasets.load_iris()
X = iris.data[:, 0:3]  # we only take the first two features.
y = iris.target

# Random_state parameter is just a random seed that can be used to reproduce these specific results.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=27)

# Instantiate a K-Nearest Neighbors Classifier:
KNN_model = KNeighborsClassifier(n_neighbors=2)

# Fit the classifiers:
KNN_model.fit(X_train, y_train)

# Predict and store the prediction:
KNN_prediction = KNN_model.predict(X_test)

# Generate the confusion matrix
conf_matrix = confusion_matrix(KNN_prediction, y_test)

# Print the classification report
print(classification_report(KNN_prediction, y_test))

# Dummy class labels for the three iris classes
class_labels = [0,1,2]

# Own function to calculate precision and recall from the confusion matrix
calc_precision_recall(conf_matrix, class_labels)

erwartete Ergebnisse

Meine Funktion gibt für jede Klasse Folgendes zurück:

Klassenbezeichnung 0 T_positiv 7 F_positiv 0 T_negativ 23 F_negativ 0
Empfindlichkeit / Rückruf 1.0 Spezifität 1.0 Präzision 1.0

Klassenbezeichnung 1 T_positiv 11 F_positiv 1 T_negativ 18 F_negativ 0
Empfindlichkeit / Rückruf 1.0 Spezifität 0,9473684210526315 Präzision 0,9166666666666666

Klassenbezeichnung 2 T_positiv 11 F_positiv 0 T_negativ 18 F_negativ 1
Empfindlichkeit / Rückruf 0.9166666666666666 Spezifität 1.0 Präzision 1.0

          precision    recall  

       0       1.00      1.00      
       1       0.92      1.00    
       2       1.00      0.92

Meine Funktion geht davon aus, dass die Verwirrungsmatrix mit tatsächlichen Werten auf der oberen x-Achse und vorhergesagten Werten auf der linken y-Achse strukturiert ist. Dies ist die gleiche Struktur wie die in Wikipedia verwendete und die in der Dokumentation für die Verwirrungsmatrixfunktion angegebene.

Tatsächliche Ergebnisse

Im Gegensatz dazu sind dies die Ergebnisse, die von sklearn.metrics import classification_report gemeldet wurden

           precision    recall  f1-score   support

       0       1.00      1.00      1.00         7
       1       1.00      0.92      0.96        12
       2       0.92      1.00      0.96        11

Versionen

System:
Python: 3.8.1 (Standard, 8. Januar 2020, 22:29:32) [GCC 7.3.0]
ausführbare Datei: / home / will / anaconda3 / envs / ElStatLearn / bin / python
Maschine: Linux-4.15.0-91-generic-x86_64-with-glibc2.10

Python-Abhängigkeiten:
pip: 20.0.2
Setuptools: 38.2.5
sklearn: 0.22.1
Anzahl: 1.18.1
scipy: 1.4.1
Cython: Keine
Pandas: 1.0.1
matplotlib: 3.1.3
Joblib: 0.14.1

Mit OpenMP erstellt: True

triage metrics

Hilfreichster Kommentar

Ich denke, dass y_test in print(classification_report(KNN_prediction, y_test)) erster Stelle stehen sollte.

Also: print(classification_report(y_test, KNN_prediction)) .

Die Funktion sklearn.metrics.classification_report(y_true, y_pred, labels=None, target_names=None, sample_weight=None, digits=2, output_dict=False, zero_division='warn') hat y_true als erstes Argument. Dies würde die Präzision umdrehen und zurückrufen.

Siehe Klassifizierungsbericht .

Bearbeiten: Ihre Verwirrungsmatrix ist auch rückwärts, aber es funktioniert, weil die Verwirrungsmatrix von sklearn von Wikipedia rückwärts ist.

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

Sie können sehen, dass es 1 Beobachtung in Zeile 1 und 0 in Spalte 1 gibt, also sind die Zeilen Grundwahrheit und Spalten Vorhersagen. Sie können also die unter confusion_matrix angezeigte Notation C[i, j] verwenden

Alle 3 Kommentare

Ich denke, dass y_test in print(classification_report(KNN_prediction, y_test)) erster Stelle stehen sollte.

Also: print(classification_report(y_test, KNN_prediction)) .

Die Funktion sklearn.metrics.classification_report(y_true, y_pred, labels=None, target_names=None, sample_weight=None, digits=2, output_dict=False, zero_division='warn') hat y_true als erstes Argument. Dies würde die Präzision umdrehen und zurückrufen.

Siehe Klassifizierungsbericht .

Bearbeiten: Ihre Verwirrungsmatrix ist auch rückwärts, aber es funktioniert, weil die Verwirrungsmatrix von sklearn von Wikipedia rückwärts ist.

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

Sie können sehen, dass es 1 Beobachtung in Zeile 1 und 0 in Spalte 1 gibt, also sind die Zeilen Grundwahrheit und Spalten Vorhersagen. Sie können also die unter confusion_matrix angezeigte Notation C[i, j] verwenden

Vielen Dank, dass Sie das geklärt haben - die Wikipedia-Referenz hat mich verwirrt!

Kein Problem, sollte wahrscheinlich Wikipedia dazu bringen, ihr Beispiel auf die sklearn-Ausrichtung umzustellen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen