From e79f047f172c98ea2ba2ef510ea27334a3f97268 Mon Sep 17 00:00:00 2001 From: aaron Date: Thu, 11 Jun 2026 12:24:35 +0200 Subject: [PATCH] feature(notes): add l5 validation notes --- SL/notizen/L5_Notizen.md | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/SL/notizen/L5_Notizen.md b/SL/notizen/L5_Notizen.md index cb85dfe..151c465 100644 --- a/SL/notizen/L5_Notizen.md +++ b/SL/notizen/L5_Notizen.md @@ -393,3 +393,70 @@ Untersuche den Einfluss des **Standardisierens der Features** auf: - Score Optional/zu Hause: Einfluss des **Logarithmierens des Targets** auf die Performance der linearen Regression. + +> *(eigene Bearbeitung — bewusst nicht vorgelöst)* + +--- + +# Validierung — Klassifikationsmetriken (Foliensatz 14) + +> Bewertung von **Klassifikations**modellen (Ergänzung zu den Regressionsmetriken oben). + +## Konfusionsmatrix + +Gegenüberstellung tatsächlicher vs. vorhergesagter Klassen: + +- **TP** (True Positive): positiver Fall korrekt als positiv erkannt +- **TN** (True Negative): negativer Fall korrekt als negativ erkannt +- **FP** (False Positive): negativer Fall fälschlich als positiv → **Fehler Typ I** +- **FN** (False Negative): positiver Fall fälschlich als negativ → **Fehler Typ II** + +Konvention: **Zeilen = tatsächliche** Klasse, **Spalten = vorhergesagte** Klasse. + +> ⚠️ Achtung: Das genaue Layout variiert je nach Quelle (welche Klasse oben/links steht — in diesem Foliensatz sind sogar zwei verschiedene Anordnungen abgebildet). `sklearn.metrics.confusion_matrix` liefert für binär [0,1] die Reihenfolge `[[TN, FP], [FN, TP]]` (Labels aufsteigend sortiert). → immer Achsenbeschriftung prüfen, bevor man Zellen interpretiert. + +**Nutzen:** detaillierte Fehleranalyse (nicht nur Gesamt-Accuracy), Modelloptimierung (Schwachstellen sichtbar machen), Modellvergleich, Basis für abgeleitete Metriken (Precision, Recall, F1). + +> Warum nicht nur Accuracy? Bei **unausgeglichenen** Klassen ist Accuracy irreführend: immer „negativ" raten bei 99 % Negativen → 99 % Accuracy, aber 0 % der positiven Fälle erkannt. Darum Precision/Recall/F1. + +## Precision + +$$\text{Precision} = \frac{TP}{TP + FP} = \frac{TP}{\text{alle als positiv vorhergesagten}}$$ + +- *Wie viele der als positiv vorhergesagten Fälle sind wirklich positiv?* +- einsetzen, wenn **positive Vorhersagen genau** sein müssen (FP teuer; z.B. Spam-Filter: lieber Spam durchlassen als wichtige Mail fälschlich blocken) +- steigt, wenn die FP sinken + +## Recall (Sensitivität) + +$$\text{Recall} = \frac{TP}{TP + FN} = \frac{TP}{\text{alle tatsächlich positiven}}$$ + +- *Wie viele der tatsächlich positiven Fälle wurden erkannt?* +- einsetzen, wenn **FN teurer** sind als FP (z.B. Krankheitsdiagnose: kranke Person nicht übersehen) +- steigt, wenn die FN sinken + +## Precision vs. Recall + +- **Zielkonflikt** (Trade-off): mit steigender Precision sinkt i.d.R. der Recall — und umgekehrt. +- steuerbar über den Entscheidungs-Schwellenwert (Threshold) des Klassifikators. + +## F1-Score + +$$F_1 = 2 \cdot \frac{\text{Precision} \cdot \text{Recall}}{\text{Precision} + \text{Recall}}$$ + +- **harmonisches Mittel** von Precision und Recall (nicht arithmetisch!) → bestraft Ungleichgewicht: ist *einer* der beiden klein, wird auch F1 klein. +- balanciert beide; besonders wertvoll bei **unausgeglichenen** Datensätzen. + +## Praxis: Kreuzvalidierung (Stabilität) + +```python +from sklearn.model_selection import cross_val_score +scores = cross_val_score(model, X, y, cv=kfold) # kfold default = 5 +print("mean:", np.mean(scores), "std:", np.std(scores)) +sns.boxplot(x=scores) +``` + +- `cross_val_score` gibt ein **Array** mit dem Score je Fold zurück und macht das Splitten **selbst** (kein manueller Train-Test-Split nötig). +- **mean** → durchschnittliche Performance. +- **std** → **Stabilität** des Learners: wie stark hängt die Performance von der zufälligen Datenaufteilung (random_state) ab. + - **kleine std = stabileres** Resultat der Methode.