W3docs

AUC - ROC Kurve

AUC-ROC-Kurven in Python mit sklearn berechnen und darstellen. TPR, FPR, Schwellenwerte und wann AUC besser als Genauigkeit ist.

Die AUC-ROC-Kurve (Area Under the Receiver Operating Characteristic Curve) ist eine der wichtigsten Metriken zur Bewertung binärer Klassifikationsmodelle. Sie erfasst die Fähigkeit eines Modells, positive und negative Beispiele über jeden möglichen Entscheidungsschwellenwert hinweg zu trennen, und liefert damit ein deutlich reichhaltigeres Bild als ein einzelner Genauigkeitswert.

Dieses Kapitel behandelt:

  • Was die ROC-Kurve ist und wie sie aufgebaut wird
  • Wie man TPR, FPR und die dahinterstehenden Begriffe der Konfusionsmatrix liest
  • Wie man AUC-ROC mit Python's scikit-learn berechnet
  • Wie man die ROC-Kurve mit matplotlib darstellt
  • Wann AUC-ROC die richtige Metrik ist und wann nicht

Schlüsselbegriffe: TP, FP, TN, FN

Bevor wir uns der Kurve selbst widmen, ist es wichtig, die vier Ergebnisse zu verstehen, die ein binärer Klassifikator erzeugen kann. Bei jeder Vorhersage ist das tatsächliche Label entweder positiv (P) oder negativ (N), und das vorhergesagte Label ist entweder positiv oder negativ:

Vorhergesagt PositivVorhergesagt Negativ
Tatsächlich PositivRichtig Positiv (TP)Falsch Negativ (FN)
Tatsächlich NegativFalsch Positiv (FP)Richtig Negativ (TN)

Diese vier Zellen sind die Bausteine jeder in diesem Kapitel behandelten Bewertungsmetrik. Eine ausführlichere Einführung finden Sie im Kapitel Konfusionsmatrix.

Was ist die ROC-Kurve?

Ein Klassifikator gibt in der Regel einen Wahrscheinlichkeitswert (eine Zahl zwischen 0 und 1) aus, anstatt ein hartes Label. Sie wählen einen Schwellenwert — beispielsweise 0,5 — und alles, was über dem Schwellenwert liegt, wird als positiv vorhergesagt.

Das Verändern des Schwellenwerts verschiebt das Gleichgewicht zwischen dem Erkennen echter positiver Fälle und dem versehentlichen Markieren echter negativer Fälle:

  • Ein sehr niedriger Schwellenwert erkennt mehr positive Fälle (hoher Recall), erzeugt aber auch mehr Fehlalarme.
  • Ein sehr hoher Schwellenwert ist selektiv (hohe Präzision), übersieht jedoch echte positive Fälle.

Die ROC-Kurve stellt diesen Kompromiss für jeden möglichen Schwellenwert gleichzeitig dar:

  • X-Achse — False Positive Rate (FPR): Welcher Anteil der tatsächlich negativen Fälle wird fälschlicherweise als positiv markiert.
  • Y-Achse — True Positive Rate (TPR), auch Recall oder Sensitivität genannt: Welcher Anteil der tatsächlich positiven Fälle wird korrekt erkannt.

TPR = TP / (TP + FN) und FPR = FP / (FP + TN)

Jeder Punkt auf der ROC-Kurve entspricht einer Schwellenwerteinstellung. Zusammen zeichnen sie einen Pfad von (0, 0) — dem selektivsten Schwellenwert, der nichts als positiv vorhersagt — bis (1, 1) — dem am wenigsten selektiven Schwellenwert, der alles als positiv vorhersagt.

Was ist AUC?

Der AUC (Area Under the Curve) fasst die gesamte ROC-Kurve in einer einzigen Zahl zwischen 0 und 1 zusammen:

AUCBedeutung
1,0Perfekter Klassifikator — trennt jeden positiven von jedem negativen Fall
0,5Kein Skill — entspricht zufälligem Raten
< 0,5Schlechter als zufällig (Ihre vorhergesagten Wahrscheinlichkeiten sind invertiert)
0,7 – 0,8Akzeptabel für viele praktische Probleme
0,8 – 0,9Gut
> 0,9Ausgezeichnet

Intuitiv ist AUC die Wahrscheinlichkeit, dass das Modell ein zufällig gewähltes positives Beispiel höher einstuft als ein zufällig gewähltes negatives Beispiel.

AUC-ROC mit scikit-learn berechnen

Das Modul sklearn.metrics bietet roc_curve() zum Abrufen der schwellenwertweisen TPR/FPR-Werte und roc_auc_score() zum Ermitteln des einzelnen AUC-Werts.

Minimales funktionierendes Beispiel

from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score, roc_curve

# 1. Create a toy binary-classification dataset
X, y = make_classification(n_samples=500, n_features=10, random_state=42)

# 2. Split into train / test sets
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)

# 3. Train a logistic regression model
model = LogisticRegression(random_state=42)
model.fit(X_train, y_train)

# 4. Get probability scores for the positive class (column 1)
y_proba = model.predict_proba(X_test)[:, 1]

# 5. Compute AUC
auc = roc_auc_score(y_test, y_proba)
print(f"AUC-ROC: {auc:.3f}")

# 6. Get the (fpr, tpr, thresholds) arrays for plotting
fpr, tpr, thresholds = roc_curve(y_test, y_proba)
print(f"Number of threshold points: {len(thresholds)}")

Die Ausgabe wird ungefähr wie folgt aussehen:

AUC-ROC: 0.944
Number of threshold points: 30

Der genaue Wert variiert leicht je nach Ihrer scikit-learn-Version, sollte aber für diesen Datensatz im Bereich 0,90–0,97 liegen.

Die ROC-Kurve darstellen

import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score, roc_curve

X, y = make_classification(n_samples=500, n_features=10, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

model = LogisticRegression(random_state=42)
model.fit(X_train, y_train)

y_proba = model.predict_proba(X_test)[:, 1]
auc = roc_auc_score(y_test, y_proba)
fpr, tpr, _ = roc_curve(y_test, y_proba)

plt.figure(figsize=(7, 5))
plt.plot(fpr, tpr, color="steelblue", lw=2, label=f"ROC curve (AUC = {auc:.2f})")
plt.plot([0, 1], [0, 1], color="gray", linestyle="--", label="Random baseline (AUC = 0.50)")
plt.xlabel("False Positive Rate (FPR)")
plt.ylabel("True Positive Rate (TPR)")
plt.title("ROC Curve")
plt.legend(loc="lower right")
plt.tight_layout()
plt.savefig("roc_curve.png", dpi=120)
plt.show()

Die diagonale gestrichelte Linie repräsentiert einen zufälligen Klassifikator. Je weiter die ROC-Kurve in Richtung der oberen linken Ecke ausbeult, desto besser ist das Modell.

Mehrere Modelle vergleichen

Ein gängiges Vorgehen ist es, mehrere Modelle zu trainieren und deren ROC-Kurven in derselben Grafik zu vergleichen:

from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score, roc_curve
import matplotlib.pyplot as plt

X, y = make_classification(n_samples=500, n_features=10, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

models = {
    "Logistic Regression": LogisticRegression(random_state=42),
    "Decision Tree": DecisionTreeClassifier(max_depth=3, random_state=42),
}

plt.figure(figsize=(7, 5))
for name, clf in models.items():
    clf.fit(X_train, y_train)
    y_proba = clf.predict_proba(X_test)[:, 1]
    fpr, tpr, _ = roc_curve(y_test, y_proba)
    auc = roc_auc_score(y_test, y_proba)
    plt.plot(fpr, tpr, lw=2, label=f"{name} (AUC = {auc:.2f})")

plt.plot([0, 1], [0, 1], "k--", label="Random (AUC = 0.50)")
plt.xlabel("False Positive Rate")
plt.ylabel("True Positive Rate")
plt.title("ROC Curve Comparison")
plt.legend(loc="lower right")
plt.tight_layout()
plt.savefig("roc_comparison.png", dpi=120)
plt.show()

Das Modell mit der größeren Fläche unter seiner Kurve ist in der Regel die bessere Wahl für diesen Datensatz. Für einen rigorosen Modellauswahlprozess kombinieren Sie dies mit Kreuzvalidierung.

Einen Betriebspunkt wählen (Schwellenwert)

Der AUC fasst alle Schwellenwerte zusammen, aber letztendlich müssen Sie einen Schwellenwert für die Produktion auswählen. Zwei gängige Strategien:

1. Youdens J-Statistik

Youdens J maximiert TPR − FPR und findet den einzelnen Punkt auf der ROC-Kurve, der am weitesten von der Diagonalen entfernt ist:

from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve
import numpy as np

X, y = make_classification(n_samples=500, n_features=10, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

model = LogisticRegression(random_state=42)
model.fit(X_train, y_train)
y_proba = model.predict_proba(X_test)[:, 1]

fpr, tpr, thresholds = roc_curve(y_test, y_proba)
j_scores = tpr - fpr
best_idx = int(np.argmax(j_scores))
best_threshold = thresholds[best_idx]

print(f"Best threshold (Youden's J): {best_threshold:.3f}")
print(f"TPR at best threshold: {tpr[best_idx]:.3f}")
print(f"FPR at best threshold: {fpr[best_idx]:.3f}")

2. Geschäftlich motivierter Schwellenwert

Bei der Betrugserkennung kann man mehr falsch positive Ergebnisse tolerieren, um mehr Betrug zu erkennen (niedrigerer Schwellenwert). Bei medizinischen Screenings möchte man möglicherweise sehr wenige falsch negative Ergebnisse (ebenfalls niedrigerer Schwellenwert). Die Wahl des Schwellenwerts ist letztlich eine Geschäftsentscheidung, die durch die Kosten jedes Fehlertyps bestimmt wird.

AUC-ROC vs. andere Metriken

MetrikAm besten, wenn...Achtung bei...
AccuracyKlassen ausgewogen sindIrreführend bei unausgewogenen Datensätzen
Precision / RecallMan sich hauptsächlich um eine Klasse kümmertErfordert einen Schwellenwert
F1-ScoreHarmonisches Gleichgewicht zwischen Precision und RecallNoch schwellenwertabhängig
AUC-ROCModelle vergleichen oder Schwellenwerte anpassenNicht aussagekräftig für mehrere Klassen ohne Erweiterung
AUC-PR (Precision-Recall AUC)Starke Klassenungleichgewichte (seltene positive Fälle)Weniger intuitiv als ROC

Bei stark unausgewogenen Daten — etwa 1 % positive Fälle — ist die AUC-PR-Kurve (Precision vs. Recall) oft informativer als die AUC-ROC, da FPR klein erscheinen kann, auch wenn viele negative Fälle falsch markiert werden.

Häufige Fallstricke

Harte Labels anstelle von Wahrscheinlichkeiten übergeben. roc_auc_score benötigt Wahrscheinlichkeitswerte, keine 0/1-Labels. Verwenden Sie model.predict_proba(X_test)[:, 1], nicht model.predict(X_test).

Vergessen, die positive Klasse anzugeben. Standardmäßig behandeln roc_curve und roc_auc_score das größere Integer-Label als positiv. Übergeben Sie explizit pos_label=1, wenn Ihre Labels keine 0/1-Integer sind.

Überanpassung an AUC auf dem Trainingsset. Bewerten Sie immer auf einem zurückgehaltenen Testset oder verwenden Sie Kreuzvalidierung, um eine zuverlässige AUC-Schätzung zu erhalten. Das Kapitel Grid Search zeigt, wie man scoring='roc_auc' direkt an GridSearchCV übergibt.

AUC ≈ 0,5 bedeutet nicht immer, dass das Modell schlecht ist. Es kann bedeuten, dass sich positive und negative Beispiele im Merkmalsraum wirklich überlappen, oder dass Ihre Merkmale für die Aufgabe nicht informativ sind.

Praktisches Beispiel: Krankheitsvorhersage

Das folgende End-to-End-Beispiel verwendet den Brustkrebs-Datensatz, der mit scikit-learn ausgeliefert wird:

from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import roc_auc_score, roc_curve
import matplotlib.pyplot as plt

# Load dataset (569 samples, 30 features, binary labels: malignant=0 / benign=1)
data = load_breast_cancer()
X, y = data.data, data.target

# Scale features — important for logistic regression
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

X_train, X_test, y_train, y_test = train_test_split(
    X_scaled, y, test_size=0.2, random_state=42, stratify=y
)

classifiers = {
    "Logistic Regression": LogisticRegression(max_iter=1000, random_state=42),
    "Random Forest": RandomForestClassifier(n_estimators=100, random_state=42),
}

plt.figure(figsize=(7, 5))
for name, clf in classifiers.items():
    clf.fit(X_train, y_train)
    y_proba = clf.predict_proba(X_test)[:, 1]
    auc = roc_auc_score(y_test, y_proba)
    fpr, tpr, _ = roc_curve(y_test, y_proba)
    plt.plot(fpr, tpr, lw=2, label=f"{name} (AUC = {auc:.3f})")

plt.plot([0, 1], [0, 1], "k--", label="Random (AUC = 0.50)")
plt.xlabel("False Positive Rate")
plt.ylabel("True Positive Rate")
plt.title("ROC Curve — Breast Cancer Dataset")
plt.legend(loc="lower right")
plt.tight_layout()
plt.savefig("breast_cancer_roc.png", dpi=120)
plt.show()

Beide Klassifikatoren sollten bei diesem Datensatz AUC-Werte über 0,98 erzielen, was bestätigt, dass die Brustkrebs-Merkmale hoch prädiktiv sind.

Verwandte Themen

  • Konfusionsmatrix — die TP/FP/TN/FN-Bausteine, die in diesem Kapitel verwendet werden
  • Logistische Regression — das häufigste Modell, das mit der AUC-ROC-Bewertung kombiniert wird
  • Kreuzvalidierung — wie man zuverlässige AUC-Schätzungen erhält, die über eine einzelne Trainings-/Testaufteilung hinaus verallgemeinern
  • Grid Search — wie man Hyperparameter mit scoring='roc_auc' abstimmt
  • Entscheidungsbaum — ein weiterer binärer Klassifikator, dessen Wahrscheinlichkeitsausgaben mit AUC-ROC bewertet werden können

Zusammenfassung

KonzeptKernaussage
ROC-KurveStellt TPR vs. FPR bei jedem Entscheidungsschwellenwert dar
AUCFläche unter der ROC-Kurve; 1,0 = perfekt, 0,5 = zufällig
roc_auc_scoreWahrscheinlichkeitswerte übergeben, keine harten Labels
roc_curveGibt (fpr, tpr, thresholds)-Arrays zum Darstellen zurück
SchwellenwertauswahlYoudens J oder Domänenwissen verwenden, um einen Produktionsschwellenwert zu wählen
Wann AUC-PR bevorzugt wirdStark unausgewogene Datensätze mit seltenen positiven Fällen

AUC-ROC gibt Ihnen eine einzige, schwellenwertunabhängige Zahl, die die diskriminative Fähigkeit Ihres Modells über alle Betriebspunkte zusammenfasst. Verwenden Sie sie, um Modelle zu vergleichen, Hyperparameter abzustimmen und die Qualität von Klassifikatoren zu kommunizieren — wählen Sie dann den spezifischen Schwellenwert, der zur Toleranz Ihrer Anwendung gegenüber falsch positiven und falsch negativen Ergebnissen passt.

Was this page helpful?