Einführung
In diesem Tutorial erhalten Sie einen Schritt-für-Schritt Leitfaden darüber, wie Sie die Präzision-Rekall-Metrik verwenden, um die Qualität der Klassifiziererausgabe zu bewerten. Die Präzision-Rekall-Kurve ist ein nützliches Maß für den Erfolg der Vorhersage, wenn die Klassen sehr unausgewogen sind. In der Information Retrieval ist Präzision ein Maß für die Relevanz der Ergebnisse, während Rekall ein Maß dafür ist, wie viele tatsächlich relevante Ergebnisse zurückgegeben werden.
VM-Tipps
Nachdem der VM-Start abgeschlossen ist, klicken Sie in der oberen linken Ecke, um zur Registerkarte Notebook zu wechseln und Jupyter Notebook für die Übung zu öffnen.
Manchmal müssen Sie einige Sekunden warten, bis Jupyter Notebook vollständig geladen ist. Die Validierung von Vorgängen kann aufgrund der Einschränkungen in Jupyter Notebook nicht automatisiert werden.
Wenn Sie bei der Lernphase Probleme haben, können Sie Labby gerne fragen. Geben Sie nach der Sitzung Feedback, und wir werden das Problem für Sie prompt beheben.
Dataset und Modell
Wir werden den Iris-Datensatz und einen Linearen SVC-Klassifizierer verwenden, um zwei Arten von Irisen zu unterscheiden. Zunächst importieren wir die erforderlichen Bibliotheken und laden den Datensatz.
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
X, y = load_iris(return_X_y=True)
Als nächstes fügen wir rauschende Merkmale zum Datensatz hinzu und teilen ihn in Trainings- und Testsets auf.
random_state = np.random.RandomState(0)
n_samples, n_features = X.shape
X = np.concatenate([X, random_state.randn(n_samples, 200 * n_features)], axis=1)
X_train, X_test, y_train, y_test = train_test_split(
X[y < 2], y[y < 2], test_size=0.5, random_state=random_state
)
Schließlich skalieren wir die Daten mit einem StandardScaler und trainieren einen Linearen SVC-Klassifizierer auf den Trainingsdaten.
classifier = make_pipeline(
StandardScaler(), LinearSVC(random_state=random_state, dual="auto")
)
classifier.fit(X_train, y_train)
Zeichnen der Präzision-Rekall-Kurve
Um die Präzision-Rekall-Kurve zu zeichnen, verwenden wir die PrecisionRecallDisplay-Klasse aus der sklearn.metrics-Bibliothek. Wir können entweder die from_estimator- oder die from_predictions-Methode verwenden, um die Kurve zu berechnen. Die from_estimator-Methode berechnet die Vorhersagen für uns, bevor die Kurve gezeichnet wird, während die from_predictions-Methode erfordert, dass wir die vorhergesagten Scores angeben.
from sklearn.metrics import PrecisionRecallDisplay
## Verwendung der from_estimator-Methode
display = PrecisionRecallDisplay.from_estimator(
classifier, X_test, y_test, name="LinearSVC", plot_chance_level=True
)
_ = display.ax_.set_title("2-class Precision-Recall curve")
## Verwendung der from_predictions-Methode
y_score = classifier.decision_function(X_test)
display = PrecisionRecallDisplay.from_predictions(
y_test, y_score, name="LinearSVC", plot_chance_level=True
)
_ = display.ax_.set_title("2-class Precision-Recall curve")
Zeichnen der Präzision-Rekall-Kurve für die Mehrfachklassifizierung
Die Präzision-Rekall-Kurve unterstützt die Mehrfachklassifizierung nicht. Man kann jedoch entscheiden, wie man diesen Fall behandelt. Wir werden einen Mehrfachklassifizierungsdatensatz erstellen, mit OneVsRestClassifier trainieren und vorhersagen und dann die Präzision-Rekall-Kurve zeichnen.
from sklearn.preprocessing import label_binarize
from sklearn.multiclass import OneVsRestClassifier
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import average_precision_score
## Mehrfachklassifizierungsdaten erstellen
Y = label_binarize(y, classes=[0, 1, 2])
n_classes = Y.shape[1]
X_train, X_test, Y_train, Y_test = train_test_split(
X, Y, test_size=0.5, random_state=random_state
)
## Mit OneVsRestClassifier trainieren und vorhersagen
classifier = OneVsRestClassifier(
make_pipeline(StandardScaler(), LinearSVC(random_state=random_state, dual="auto"))
)
classifier.fit(X_train, Y_train)
y_score = classifier.decision_function(X_test)
## Präzision und Recall für jede Klasse berechnen
precision = dict()
recall = dict()
average_precision = dict()
for i in range(n_classes):
precision[i], recall[i], _ = precision_recall_curve(Y_test[:, i], y_score[:, i])
average_precision[i] = average_precision_score(Y_test[:, i], y_score[:, i])
## Mikro-averaged Präzision und Recall berechnen
precision["micro"], recall["micro"], _ = precision_recall_curve(Y_test.ravel(), y_score.ravel())
average_precision["micro"] = average_precision_score(Y_test, y_score, average="micro")
## Die mikro-averaged Präzision-Rekall-Kurve zeichnen
display = PrecisionRecallDisplay(
recall=recall["micro"],
precision=precision["micro"],
average_precision=average_precision["micro"],
prevalence_pos_label=Counter(Y_test.ravel())[1] / Y_test.size,
)
display.plot(plot_chance_level=True)
_ = display.ax_.set_title("Mikro-averaged über alle Klassen")
## Präzision-Rekall-Kurve für jede Klasse und iso-f1-Kurven zeichnen
colors = cycle(["navy", "turquoise", "darkorange", "cornflowerblue", "teal"])
_, ax = plt.subplots(figsize=(7, 8))
f_scores = np.linspace(0.2, 0.8, num=4)
lines, labels = [], []
for f_score in f_scores:
x = np.linspace(0.01, 1)
y = f_score * x / (2 * x - f_score)
(l,) = plt.plot(x[y >= 0], y[y >= 0], color="gray", alpha=0.2)
plt.annotate("f1={0:0.1f}".format(f_score), xy=(0.9, y[45] + 0.02))
display = PrecisionRecallDisplay(
recall=recall["micro"],
precision=precision["micro"],
average_precision=average_precision["micro"],
)
display.plot(ax=ax, name="Mikro-average Präzision-Rekall", color="gold")
for i, color in zip(range(n_classes), colors):
display = PrecisionRecallDisplay(
recall=recall[i],
precision=precision[i],
average_precision=average_precision[i],
)
display.plot(ax=ax, name=f"Präzision-Rekall für Klasse {i}", color=color)
handles, labels = display.ax_.get_legend_handles_labels()
handles.extend([l])
labels.extend(["iso-f1 Kurven"])
ax.set_xlim([0.0, 1.0])
ax.set_ylim([0.0, 1.05])
ax.legend(handles=handles, labels=labels, loc="best")
ax.set_title("Erweiterung der Präzision-Rekall-Kurve auf die Mehrfachklassifizierung")
plt.show()
Zusammenfassung
In diesem Tutorial wurde ein Schritt-für-Schritt Leitfaden dazu gegeben, wie man die Präzision-Rekall-Metrik verwendet, um die Qualität der Klassifiziererausgabe zu bewerten. Wir haben gelernt, wie man die Präzision-Rekall-Kurve für die binäre Klassifizierung mit der PrecisionRecallDisplay-Klasse aus der sklearn.metrics-Bibliothek zeichnet. Wir haben auch gelernt, wie man die Präzision-Rekall-Kurve für die Mehrfachklassifizierung mit OneVsRestClassifier zeichnet und wie man Präzision und Recall für jede Klasse berechnet.