ML Atlas

Machine Learning von Grund auf · Lektion 2.3 · 10 von 33 fertigen Lektionen · 12 Min.

Schwelle, ROC und PR: alle Schwellen auf einmal

Kurz gesagt

ROC- und Precision-Recall-Kurven zeigen alle Schwellen zugleich. Ist eine Klasse selten, bleibt ROC AUC fast gleich, AP fällt: Fehlalarme fressen Präzision.

Aufwärmen Zwei Fragen aus früheren Lektionen. Eine Minute, und sie blockiert die Lektion nicht.
Aus Lektion 2.2: Einen Klassifikator bewerten: mehr als Genauigkeit Ein Screening-Modell übersieht viele Krebsfälle, schlägt aber fast nie falschen Alarm. Welche Zahl ist niedrig?

Antwort anzeigen

Richtige Antwort: Der Recall, also der Anteil entdeckter Krebsfälle an allen tatsächlichen Krebsfällen

Der Recall ist der Anteil der tatsächlich Positiven, die erwischt wurden, also bedeuten viele Übersehene einen niedrigen Recall.

Aus Lektion 2.1: Klassifikation: eine Grenze ziehen Du erhöhst den Schwellenwert von 0,5 auf 0,8. Was passiert mit der Grenze?

Antwort anzeigen

Richtige Antwort: Sie verschiebt sich parallel, und weniger Pinguine werden als Art B eingestuft

Zu jedem Schwellenwert gehört eine Gerade mit derselben Richtung; ein strengerer Schwellenwert verschiebt sie so, dass nur sichere Fälle durchkommen.

In Lektion 2.2 hast du eine Schwelle verschoben und zugesehen, wie sich die Konfusionsmatrix ändert. Jede Schwelle ist eine andere Entscheidung, obwohl die Werte des Modells gleich bleiben. Heute siehst du alle Schwellen auf einmal, auf zwei Kurven: ROC und Precision-Recall (PR). Du prüfst auch, welche von beiden die Wahrheit sagt, wenn es nur wenige Kranke gibt. Das Modell ist absichtlich schwach: eine logistische Regression, die nur einen Messwert sieht, die mittlere Textur des Tumors, damit die Kurven nicht an den Ecken kleben.

Erst vorhersagen, dann prüfen Dasselbe Modell bewertet dieselben 357 gutartigen Biopsien. Zuerst gibt es 212 bösartige (37 % der Daten), dann nur 19 (5 %). Was passiert mit ROC AUC (der Fläche unter der ROC-Kurve) und was mit AP, der Fläche unter der PR-Kurve?
Wie sicher bist du?

Interaktives Labor

Dieses interaktive Labor läuft im Browser mit aktiviertem JavaScript. Der Text drumherum beschreibt, was es zeigt.

Antwort anzeigen

Richtige Antwort: ROC AUC ändert sich kaum (etwa 0,77), während AP auf etwa 0,14 fällt

ROC AUC beträgt 0,773 mit allen bösartigen und im Mittel 0,772 mit 19 (über 200 Ziehungen, welche bösartigen bleiben). AP fällt von 0,591 auf im Mittel 0,137. Das Modell hat nichts vergessen; nur die Anteile der Klassen haben sich geändert. ROC sieht das nicht, die PR-Kurve schon.

Probier es aus

  • Beginne mit 212 bösartigen und der Schwelle 0,5. Lies Sensitivität und FPR ab und verschiebe die Schwelle dann auf 0,3. In welche Richtung wandert der Punkt auf beiden Kurven?
  • Wechsle bei der Schwelle 0,3 zu 19 bösartigen. Es gibt genauso viele Fehlalarme wie eben. Was ist mit der Präzision passiert?
  • Vergleiche ROC AUC und AP bei 212, 40 und 19 bösartigen.

Wenn du es im Labor geprüft hast, benennen wir, was du siehst.

Die Idee in einfachen Worten

Das Modell sagt nicht „bösartig“ oder „gutartig“. Es gibt einen Wert von 0 bis 1, und eine Schwelle trifft die Entscheidung. Jede Schwelle ergibt ein anderes Zahlenpaar: wie viele bösartige gefunden wurden (Sensitivität) und wie viele gutartige einen Fehlalarm bekamen. Die ROC-Kurve zeichnet diese Paare für alle Schwellen auf einmal: waagerecht der Anteil der Fehlalarme unter den gutartigen (FPR), senkrecht die Sensitivität. Eine hohe Schwelle ist die linke untere Ecke (wenige Alarme), eine niedrige die rechte obere (Alarm bei jeder Biopsie).

Die Precision-Recall-Kurve (PR) zeigt dieselben Schwellen anders: waagerecht die Sensitivität, senkrecht die Präzision, also welcher Teil der Alarme richtig ist. Die Fläche unter der ROC-Kurve ist ROC AUC, die Fläche unter der PR-Kurve ist AP (average precision). Jede dieser Zahlen fasst alle Schwellen auf einmal zusammen und hängt daher nicht davon ab, welche Schwelle du wählst.

Auf allen 569 Biopsien hat das Modell ROC AUC 0,773 und AP 0,591. Zufälliges Raten ergäbe ROC AUC 0,5 und ein AP gleich dem Anteil bösartiger Biopsien, also 0,373. Das Modell ist klar besser als Raten, aber weit vom Ideal entfernt, das 1 ist.

Jak to policzono
  • Biopsien: Breast Cancer Wisconsin (Diagnostic), UCI, Lizenz CC BY 4.0. 569 Biopsien (357 gutartig, 212 bösartig). Das Modell sieht einen Messwert: die mittlere Textur des Tumors.
  • Werte aus einer Kreuzvalidierung mit 5 Teilen (StratifiedKFold(5) in scikit-learn): Jede Biopsie bewertet ein Modell, das sie nie gesehen hat.
  • Seltenere Klasse: Alle 357 gutartigen bleiben, dazu 40 oder 19 zufällig gezogene bösartige. Das Diagramm zeigt eine Ziehung; die Mittelwerte stammen aus 200 Ziehungen.
  • Modell: Standardisierung und logistische Regression (C = 1).

Warum es funktioniert

ROC zählt Fehlalarme gegen die gutartigen: FPR ist die Zahl der Fehlalarme geteilt durch 357. Die Sensitivität zählt Treffer gegen die bösartigen. Nimmst du bösartige Biopsien zufällig weg, bleiben beide Brüche ungefähr gleich, also bewegen sich die ROC-Kurve und ihre Fläche kaum. Bei der Schwelle 0,3 schlägt das Modell bei 144 von 357 gutartigen Alarm (FPR 40,3 %), ob es 212 bösartige gibt oder 19.

Die Präzision zählt Fehlalarme gegen alle Alarme. Bei 212 bösartigen und der Schwelle 0,3 findet das Modell 177, die Präzision beträgt also 55,1 %. Bei 19 bösartigen findet es 17, und die 144 Fehlalarme bleiben: Die Präzision fällt auf 10,6 %, also 8,5 Fehlalarme pro richtigem Alarm. Die PR-Kurve fällt mit der Präzision, und AP von 0,591 auf im Mittel 0,137. Die Linie des zufälligen Ratens bei PR fällt ebenfalls, auf den Anteil bösartiger: 0,051.

Das ist kein Zufall einer Ziehung oder einer Aufteilung in Teile. Bei 40 bösartigen (10 %) beträgt ROC AUC im Mittel 0,773 und AP 0,232. Im Code unten hat dasselbe Modell auf 20 anderen Aufteilungen bei 19 bösartigen jedes Mal ein AP unter der Hälfte des AP mit allen Daten.

Häufiger Fehler

Richtig oder falsch: „Ein hohes ROC AUC bedeutet wenige Fehlalarme.“ Falsch. ROC AUC misst, wie gut das Modell sortiert: die Wahrscheinlichkeit, dass eine zufällige bösartige Biopsie einen höheren Wert bekommt als eine zufällige gutartige. Es sagt nicht, wie viele Alarme falsch sein werden, denn das hängt davon ab, wie selten die Klasse ist. Im Labor beträgt ROC AUC bei 19 bösartigen im Mittel 0,772, fast so viel wie bei 212, und bei der Schwelle 0,3 kommen 8,5 Fehlalarme auf einen richtigen. Ist die Klasse selten, schau auf die PR-Kurve und auf die Präzision bei der Schwelle, die du wirklich verwenden wirst.

Eine Warnung in die andere Richtung: Auch AP ist keine Zahl „nur über das Modell“. Es hängt vom Anteil der Klasse in den Daten ab, deshalb lassen sich die AP zweier Datensätze mit verschiedenen Anteilen nicht direkt vergleichen. Vergleiche AP mit der Linie des zufälligen Ratens auf denselben Daten.

Quiz

Drei Fragen zur Selbstkontrolle. Wähle eine Antwort oder klappe die Lösung unter der Frage auf. Mit der Tastatur: Pfeiltasten wählen, Enter oder Leertaste bestätigt.

1. Was zeigt die ROC-Kurve?
Antwort anzeigen

Richtige Antwort: Die Sensitivität gegen den Anteil der Fehlalarme, für alle Schwellen auf einmal

Jeder Punkt der Kurve ist eine Schwelle. Eine hohe Schwelle ist die linke untere Ecke, eine niedrige die rechte obere. Die Fläche unter der Kurve, ROC AUC, fasst alle Schwellen in einer Zahl zusammen: hier 0,773.

2. Bösartige sind 5 % statt 37 %. ROC AUC bewegt sich kaum. Warum fällt AP?
Antwort anzeigen

Richtige Antwort: Weil dieselben Fehlalarme jetzt einen viel größeren Teil aller Alarme ausmachen

Die FPR teilt Fehlalarme durch die Zahl der gutartigen, die sich nicht ändert. Die Präzision teilt sie durch alle Alarme. Bei der Schwelle 0,3 und 19 bösartigen kommen 144 Fehlalarme auf 17 richtige.

3. Wann sagt die PR-Kurve mehr als die ROC-Kurve?
Antwort anzeigen

Richtige Antwort: Wenn die positive Klasse selten ist und zählt, wie viele Alarme richtig sind

Bei einer seltenen Klasse sieht die ROC-Kurve gleich aus, während die Präzision fällt. Im Labor mit 19 bösartigen fällt AP auf im Mittel 0,137, obwohl ROC AUC fast stillsteht.

Das Wichtigste

  • Die ROC-Kurve und die PR-Kurve zeigen alle Schwellen auf einmal; die Schwelle wählst du danach, nach den Kosten der Fehler.
  • ROC AUC misst, wie gut das Modell sortiert, und hängt kaum von den Anteilen der Klassen ab.
  • Ist die positive Klasse selten, fressen dieselben Fehlalarme die Präzision: Schau auf die PR-Kurve und AP.
  • Vergleiche AP mit der Linie des zufälligen Ratens, also dem Anteil der positiven Klasse in denselben Daten.

Tiefer: Formel, Code, Praxis

Die Mathematik

Bei der Schwelle t sagt das Modell „bösartig“, wenn sein Wert s ≥ t. Dann gilt Sensitivität = TP / (TP + FN), FPR = FP / (FP + TN), Präzision = TP / (TP + FP).

Die FPR hat im Nenner nur gutartige, die Sensitivität nur bösartige. Nimmst du bösartige zufällig weg, ändert sich keiner der beiden Brüche systematisch, also bleibt die ROC-Kurve. Die Präzision hat beide Arten von Alarmen im Nenner. Bei der Schwelle 0,3: 177 / (177 + 144) ≈ 0,551 bei 212 bösartigen und 17 / (17 + 144) ≈ 0,106 bei 19.

ROC AUC ist die Wahrscheinlichkeit, dass eine zufällige bösartige Biopsie einen höheren Wert bekommt als eine zufällige gutartige: AUC = P(s₊ > s₋), Gleichstände zählen halb. AP ist die mittlere Präzision, gewichtet mit den Schritten der Sensitivität: AP = Σₖ (Rₖ − Rₖ₋₁) · Pₖ. Zufällige Werte ergeben AUC 0,5 und ein AP gleich dem Anteil der positiven Klasse: 212 / 569 ≈ 0,373 oder 19 / 376 ≈ 0,051.

Im Code (Python)

Dasselbe Experiment in scikit-learn: Werte aus der Kreuzvalidierung, ROC AUC und AP bei 212, 40 und 19 bösartigen (Mittel aus 1000 Ziehungen), dann dasselbe auf 20 anderen Aufteilungen.

import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import StratifiedKFold, cross_val_predict
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score, average_precision_score

X, y = load_breast_cancer(return_X_y=True)
X, y = X[:, [1]], 1 - y  # nur die mittlere Textur, wie im Labor; 1 = bösartig
model = make_pipeline(StandardScaler(), LogisticRegression())
def scores(cv):  # Validierungswerte: Jede Biopsie bewertet ein Modell, das sie nie gesehen hat
    return cross_val_predict(model, X, y, cv=cv, method="predict_proba")[:, 1]
ben, mal = np.flatnonzero(y == 0), np.flatnonzero(y == 1)
def rare(p, keep, draws, seed):  # alle 357 gutartigen + `keep` zufällige bösartige, Mittel über die Ziehungen
    rng = np.random.default_rng(seed)
    rows = [np.r_[ben, rng.choice(mal, keep, replace=False)] for _ in range(draws)]
    return np.mean([(roc_auc_score(y[i], p[i]), average_precision_score(y[i], p[i])) for i in rows], axis=0)
p = scores(StratifiedKFold(5))
print(f"212 malignant ({212 / 569:.0%}): ROC AUC {roc_auc_score(y, p):.3f}, AP {average_precision_score(y, p):.3f}")
for keep in (40, 19):
    auc, ap = rare(p, keep, 1000, 0)
    print(f"{keep} malignant ({keep / (357 + keep):.0%}), mean of 1000 draws: ROC AUC {auc:.3f}, AP {ap:.3f}")
r = []
for s in range(20):  # 20 andere Arten, die Daten in 5 Teile zu schneiden
    q = scores(StratifiedKFold(5, shuffle=True, random_state=s))
    r.append([roc_auc_score(y, q), average_precision_score(y, q), *rare(q, 19, 200, s)])
r = np.array(r)
print(f"20 other fold splits, 212 -> 19 malignant: ROC AUC {r[:, 0].mean():.3f} -> {r[:, 2].mean():.3f}, AP {r[:, 1].mean():.3f} -> {r[:, 3].mean():.3f}; AP below half in {(r[:, 3] < r[:, 1] / 2).sum()} of 20")

Ausgabe

212 malignant (37%): ROC AUC 0.773, AP 0.591
40 malignant (10%), mean of 1000 draws: ROC AUC 0.773, AP 0.231
19 malignant (5%), mean of 1000 draws: ROC AUC 0.774, AP 0.140
20 other fold splits, 212 -> 19 malignant: ROC AUC 0.774 -> 0.775, AP 0.595 -> 0.140; AP below half in 20 of 20

Mit allen bösartigen sind die Zahlen dieselben wie im Labor. Bei 40 und 19 zieht der Code die bösartigen anders als das Labor und macht 1000 Ziehungen statt 200, deshalb unterscheiden sich die Mittelwerte in der dritten Nachkommastelle: AP 0,140 statt 0,137. Auf 20 anderen Aufteilungen ist das Bild dasselbe: ROC AUC bleibt, und AP fällt jedes Mal unter die Hälfte.

Für die Praxis
  • In scikit-learn liefern roc_auc_score und average_precision_score die Zahlen, und RocCurveDisplay und PrecisionRecallDisplay zeichnen die Kurven. Berechne sie auf Validierungswerten (cross_val_predict(..., method="predict_proba")), nicht auf den Lerndaten.
  • Bei einer seltenen Klasse (Betrug, seltene Krankheiten, Ausfälle) berichte AP neben ROC AUC und neben AP die Linie des zufälligen Ratens, also den Anteil der positiven Klasse.
  • Eine Kurve ist eine Speisekarte von Schwellen. Wähle die Schwelle in der Validierung nach den Kosten der Fehler, zum Beispiel „Sensitivität mindestens 90 % bei höchstmöglicher Präzision“, und prüfe sie erst danach auf dem Testdatensatz.
  • Das ROC AUC zweier Datensätze mit verschiedenen Anteilen lässt sich vergleichen, sagt aber nicht, wie viele Alarme falsch sein werden; AP sagt darüber mehr, aber vergleiche es nur bei gleichen Anteilen.

Mehr im Atlas

Einträge der Enzyklopädie zu den Ideen dieser Lektion: