Wenn man Machine-Learning-Modelle trainiert, ist die Wahl der richtigen Metrik zur Modellbewertung entscheidend. Unterschiedliche Aufgaben (z. B. Klassifikation vs. Regression) erfordern unterschiedliche Metriken – und die richtige Interpretation entscheidet oft über Erfolg oder Fehlschluss.
In diesem Beitrag betrachten wir die wichtigsten Metriken, erklären ihre Bedeutung, zeigen Beispiele in Python und geben Hinweise, wann welche Metrik sinnvoll ist.
Train-Test-Split
Voraussetzung für eine Bewertung der Modelle ist immer eine saubere Trennung von Trainings- und Testdatensatz. Während des Trainings wird lediglich der Trainingsdatensatz verwendet. Der ungesehene Testdatensatz dient einzig der Modellbewertung.
Baseline-Modell
Häufig ist es darüber hinaus sinnvoll ein Baseline-Modell zu verwenden um zu bewerten, welchen Vorteil das Verfahren gegenüber einer möglichst simplen Basisannahme ist. Beispielsweise könnte man als Baseline annehmen, dass man bei einem Klassifikationsproblem mit zwei Klassen immer die häufigere der beiden Klassen vorhersagt. In mindestens der Hälfte aller Fälle wird man damit schon richtig liegen.
Klassifikationsmetriken
Zur Illustration verwenden wir verwenden ein klassisches Beispiel mit dem Iris-Datensatz und einer logistischen Regression.
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
# --- Klassifikationsbeispiel ---
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
clf = LogisticRegression(max_iter=200)
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)Accuracy (Genauigkeit)
Definition: Anteil der korrekt klassifizierten Instanzen an allen Instanzen.
\(Accuracy = \frac{TP + TN}{TP + TN + FP + FN}\)Die Accuracy kann dann sinnvoll interpretiert werden wenn die Klassen ausgeglichen sind (50/50 Verteilung) bzw. bei Mehrklassenproblemen keine Klasse überwiegt. Bei unausgeglichenen Datensätzen (z. B. 95 % Klasse A, 5 % Klasse B), kann die Accuracy dagegen täuschen.
from sklearn.metrics import accuracy_score
print('Accuracy:', accuracy_score(y_test, y_pred))
Precision, Recall und F1-Score
Bei unausgeglichenen Klassen oder wenn falsche Positive oder falsche Negative unterschiedlich gewichtet werden (wie beispielsweise im medizinischen Kontext) sollte man auf Precision, Recall und F1-Score zurückgreifen.
Beispiel:
- Medizinische Tests (Recall wichtiger – keine Krankheit übersehen).
- Spamfilter (Precision wichtiger – keine echten Mails löschen).
Precision (Genauigkeit der positiven Vorhersagen):
Precision beschreibt wie viele aller als positiven vorhergesagten Fälle tatsächlich positiv sind. Hohe Precision bedeutet wenige False Positives.
\(Precision = \frac{TP}{TP + FP}\)Recall (Vollständigkeit der Erkennung):
Recall beschreibt viele der tatsächlichen positiven Fälle vom Modell korrekt klassifiziert wurden. Hoher Recall bedeutet wenige False Negatives
\( Recall = \frac{TP}{TP + FN} \)F1-Score (harmonisches Mittel):
Der F1-Score ist das harmonische mittel aus Precision und Recall. Er versucht also beide Metriken zu kombinieren, wobei ein guter Precision Wert einen schlechten Recall Wert nicht kompensiert (und umgekehrt).
\( F1 = 2 * \frac{Precision * Recall}{Precision + Recall} ] \)In Python können die Metriken separat aus sklearn importiert werden.
from sklearn.metrics import precision_score, recall_score, f1_scoreEs gibt aber auch die Möglichkeit einen classification_report zu erstellen. Er zeigt automatisch precision, recall, f1-score, support.
from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred))
Bei Mehrklassenproblemen zeigt der Classification Report darüber hinaus auch noch entsprechende Durchschnittswerte an (macro, micro, weighted avg). Diese können folgendermaßen interpretiert werden:
| Aggregation | Bedeutung | Verwendung |
|---|---|---|
| Micro avg | zählt alle TP, FP, FN über alle Klassen und berechnet Metrik global | Gut bei unausgeglichenen Klassen, gewichtet nach Häufigkeit |
| Macro avg | berechnet Mittelwert pro Klasse (ungewichtet) | Gut wenn alle Klassen gleich wichtig sind |
| Weighted avg | wie Macro, aber gewichtet nach Support | Praktischer Kompromiss für unausgeglichene Klassen |
Confusion Matrix
Zeigt die tatsächlichen vs. vorhergesagten Klassen.
from sklearn.metrics import confusion_matrix
print(confusion_matrix(y_test, y_pred))
Interpretation: Gibt Einblick, welche Klassen häufig verwechselt werden – wichtig für gezielte Modellverbesserung.
ROC-Kurve
Viele Klassifikatoren geben keine harte Klassenentscheidung, sondern Scores / Wahrscheinlichkeiten aus:
y_score = model.predict_proba(X_test)[:, 1]Die eigentliche Klassifikation entsteht erst durch einen Schwellenwert (z. B. 0.5).
ROC-Kurven (Receiver Operating Characteristic) bewerten das Modell über alle möglichen Schwellenwerte hinweg. Es wird also für jeden mögliche Schwellwert zwischen 0 und 1 eine Klassifikation erzeugt (also beispielsweise auch schon bei einem Score von 0,3 Klasse 1 vergeben) und jeweils bewertet, wie gut das Modell basierend auf diesem Wert funktioniert.
Für jeden möglichen Schwellwert wird auf der x-Achse die False Positive Rate abgetragen, also wie viele aller Fälle falsch vorhergesagt wurden. Auf der y-Achse wird die True Positive Rate (=Recall) dargestellt, also wie viele Fälle korrekt vorhergesagt wurden. Jeder Punkt entspricht einem Schwellwert.
ROC-AUC berechnet die Fläche unter der Kurve. Dieser Wert kann interpretiert werden als die Wahrscheinlichkeit, dass ein zufällig gewählter positiver Fall einen höheren Score erhält als ein zufällig gewählter negativer Fall.
In Python lässt sich das so erzeugen:
from sklearn.metrics import roc_auc_score, roc_curve
roc_auc = roc_auc_score(y_test, y_score)
print(f"ROC-AUC: {roc_auc:.3f}")
fpr, tpr, thresholds = roc_curve(y_test, y_score)Weitere Klassifikationsmetriken
- Log-Loss / Cross-Entropy: Bewertet Wahrscheinlichkeitsvorhersagen – je niedriger, desto besser
- Cohen’s Kappa: Korrigiert die Accuracy um Zufallstreffer
Regressionsmetriken
# --- Regressionsbeispiel ---
Xr, yr = make_regression(n_samples=200, n_features=3, noise=10, random_state=42)
Xr_train, Xr_test, yr_train, yr_test = train_test_split(Xr, yr, test_size=0.3, random_state=42)
reg = LinearRegression()
reg.fit(Xr_train, yr_train)
yr_pred = reg.predict(Xr_test)
R² (Bestimmtheitsmaß)
Definition: Anteil der Varianz der Zielvariable, die vom Modell erklärt wird.
\( R^2 = 1 – \frac{\sum (y – \hat{y})^2}{\sum (y – \bar{y})^2}\)Interpretation:
- 1 → perfekte Vorhersage
- 0 → keine Verbesserung gegenüber Mittelwert
- < 0 → Modell schlechter als Mittelwert
from sklearn.metrics import r2_score
print('R²:', r2_score(yr_test, yr_pred))
Wann sinnvoll:
- Wenn die Varianzaufklärung zentral ist.
- Nicht geeignet, wenn Ausreißer oder Nichtlinearitäten dominieren.
MSE, RMSE, MAE
| Metrik | Formel | Sensitivität |
|---|---|---|
| MSE (Mean Squared Error) | Mittelwert der quadrierten Fehler | Stark auf Ausreißer empfindlich |
| RMSE (Root Mean Squared Error) | Wurzel aus MSE, gleiche Einheit wie Zielvariable | Intuitiver interpretierbar |
| MAE (Mean Absolute Error) | Mittelwert der absoluten Fehler | Robust gegen Ausreißer |
from sklearn.metrics import mean_squared_error
mse = mean_squared_error(yr_test, yr_pred)
mae = np.mean(np.abs(yr_test - yr_pred))
rmse = np.sqrt(mse)
print(f"MSE={mse:.2f}, RMSE={rmse:.2f}, MAE={mae:.2f}")
Wann sinnvoll:
- MSE/RMSE: Wenn große Fehler stark bestraft werden sollen.
- MAE: Wenn Robustheit wichtiger ist.
Weiterführende Themen
Häufig möchte man neben der Metriken auch die Konfidenzintervalle bewerten. Das wird hier erklärt: Konfidenzintervalle
Neben der reinen Modellbewertung ist die Modellvalidierung entscheidend. Das wird hier erklärt: [KOMMT NOCH]