Читать книгу Praxiseinstieg Machine Learning mit Scikit-Learn, Keras und TensorFlow - Aurélien Géron - Страница 101
Die Wechselbeziehung zwischen Relevanz und Sensitivität
ОглавлениеUm diese Wechselbeziehung besser zu verstehen, betrachten wir, wie der SGDClassifier bei der Klassifikation Entscheidungen trifft. Für jeden Datenpunkt wird anhand einer Entscheidungsfunktion ein Score berechnet, und falls dieser Score über einem Schwellenwert liegt, wird der Datenpunkt der positiven Kategorie zugeordnet, andernfalls der negativen Kategorie. Abbildung 3-3 zeigt einige Ziffern mit dem niedrigsten Score auf der linken und dem höchsten Score auf der rechten Seite. Nehmen wir an, die Entscheidungsgrenze läge beim Pfeil in der Mitte (zwischen den zwei 5en): Sie erhalten dann vier richtig Positive (echte 5en) auf der rechten Seite des Schwellenwerts und einen falsch Positiven (eine 6).
Abbildung 3-3: Bei dieser Wechselbeziehung zwischen Relevanz und Sensitivität werden Bilder aufgrund ihres Klassifikationsscores bewertet – solche oberhalb des gewählten Schwellenwerts betrachtet man als positiv. Je höher der Schwellenwert ist, desto geringer ist die Sensitivität, aber desto höher ist (im Allgemeinen) auch die Relevanz.
In Scikit-Learn können Sie den Schwellenwert nicht direkt festlegen, aber die zur Vorhersage verwendeten Scores der Entscheidungsfunktion sind verfügbar. Anstatt die Methode predict() eines Klassifikators aufzurufen, können Sie die Methode decision_function() verwenden, die für jeden Datenpunkt einen Score liefert, auf dessen Grundlage Sie Vorhersagen mit einem beliebigen Schwellenwert treffen können:
>>> y_scores = sgd_clf.decision_function([some_digit])
>>> y_scores
array([2412.53175101])
>>> threshold = 0
>>> y_some_digit_pred = (y_scores > threshold)
array([ True])
Der SGDClassifier verwendet als Schwellenwert 0, sodass der obige Code das gleiche Ergebnis wie die Methode predict() liefert (nämlich True). Erhöhen wir nun diesen Schwellenwert:
>>> threshold = 8000
>>> y_some_digit_pred = (y_scores > threshold)
>>> y_some_digit_pred
array([False])
Das bestätigt uns, dass ein Erhöhen des Schwellenwerts die Sensitivität verringert. Das Bild enthält tatsächlich eine 5, was der Klassifikator bei einem Schwellenwert von 0 auch korrekt erkennt. Er scheitert aber, wenn wir den Schwellenwert auf 8000 erhöhen.
Wie sollen wir uns also für einen Schwellenwert entscheiden? Dazu müssen Sie zunächst wieder die Scores sämtlicher Datenpunkte im Trainingsdatensatz mit der Funktion cross_val_predict() ermitteln, diesmal aber mit der Angabe, dass Sie die Entscheidungswerte anstelle der Vorhersagen erhalten möchten:
y_scores = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3,
method="decision_function")
Mit diesen Scores können Sie Relevanz und Sensitivität für alle möglichen Schwellenwerte mithilfe der Funktion precision_recall_curve() berechnen:
from sklearn.metrics import precision_recall_curve
precisions, recalls, thresholds = precision_recall_curve(y_train_5, y_scores)
Als letzten Schritt verwenden Sie Matplotlib, um Relevanz und Sensitivität als Funktion des Schwellenwerts darzustellen (siehe Abbildung 3-4):
def plot_precision_recall_vs_threshold(precisions, recalls, thresholds):
plt.plot(thresholds, precisions[:-1], "b--", label="Relevanz")
plt.plot(thresholds, recalls[:-1], "g-", label="Sensitivität")
[...] # Schwellenwert hervorheben und Legende, Achsbeschriftung
# und Raster ergänzen
plot_precision_recall_vs_threshold(precisions, recalls, thresholds)
plt.show()
Abbildung 3-4: Relevanz und Sensitivität über dem Schwellenwert zur Entscheidung
Sie fragen sich vielleicht, warum die Verlaufskurve der Relevanz in Abbildung 3-4 unregelmäßiger ist als die der Sensitivität. Das liegt daran, dass die Relevanz manchmal beim Erhöhen des Schwellenwerts sinkt (auch wenn sie im Allgemeinen steigt). Um dies nachzuvollziehen, betrachten Sie noch einmal Abbildung 3-3. Wenn Sie beim Schwellenwert in der Mitte beginnen und sich nur eine Ziffer nach rechts bewegen, sinkt die Relevanz von (80%) auf ¾ (75%). Andererseits kann die Sensitivität nur sinken, wenn sich der Schwellenwert erhöht, was die glattere Form der Kurve erklärt. |
Zur Auswahl eines Kompromisses zwischen Relevanz und Sensitivität können Sie auch die Relevanz gegen die Sensitivität plotten, wie in Abbildung 3-5 gezeigt (hier ist der gleiche Schwellenwert wie zuvor hervorgehoben).
Wie Sie sehen, fällt die Relevanz etwa bei einer Sensitivität von 80% scharf ab. Vermutlich sollten Sie einen Kompromiss zwischen Relevanz und Sensitivität kurz vor diesem Abfall auswählen – beispielsweise bei einer Sensitivität von etwa 60%. Aber natürlich hängt das auch von Ihrem Projekt ab.
Abbildung 3-5: Relevanz gegen Sensitivität
Nehmen wir an, Sie möchten eine Relevanz von 90% erhalten. Sie schauen im ersten Diagramm nach und finden heraus, dass Sie einen Schwellenwert von etwa 8000 benötigen. Um genauer zu sein, können Sie nach dem niedrigsten Schwellenwert suchen, der Ihnen mindestens 90% Relevanz liefert (np.argmax() wird Ihnen den ersten Index des maximalen Werts liefern, was in diesem Fall dem ersten True-Wert entspricht):
threshold_90_precision = thresholds[np.argmax(precisions >= 0.90)] # ~7816
Um Vorhersagen zu treffen (vorerst noch auf den Trainingsdaten), führen Sie anstelle der Methode predict() des Klassifikators den folgenden Code aus:
y_train_pred_90 = (y_scores >= threshold_90_precision)
Überprüfen wir Relevanz und Sensitivität dieser Vorhersagen:
>>> precision_score(y_train_5, y_train_pred_90)
0.9000380083618396
>>> recall_score(y_train_5, y_train_pred_90)
0.4368197749492714
Großartig, Sie haben nun einen Klassifikator mit einer Relevanz von 90% (Sie sind zumindest nah genug dran)! Wie Sie sehen, ist es recht einfach, einen Klassifikator mit einer praktisch beliebigen Relevanz zu erstellen: Sie setzen einfach den Schwellenwert hoch genug und sind fertig. Moment einmal. Ein Klassifikator mit einer hohen Relevanz ist nicht sehr nützlich, wenn dessen Sensitivität zu niedrig ist!
Wenn jemand sagt: »Lass uns eine Relevanz von 99% erreichen«, sollten Sie fragen: »Bei welcher Sensitivität?« |