Files
cas-pml/SL/notizen/L4_Notizen.md
T

369 lines
13 KiB
Markdown

# Notizen SL Lektion 4 (Foliensatz 12: Algorithmen — Decision Trees)
> Thema: Supervised Learning Algorithmen
> Datum: 04.06.2026
> Dozentin: Violeta Vogel
## Theorie Decision Trees
- Ein Entscheidungsbaum ist ein Modell, das Daten anhand von Wenn-Dann-Regeln klassifiziert oder vorhersagt
- Der Baum versucht Daten so aufzuteilen, dass Gruppen möglichst **rein** werden *(rein, nicht klein — Reinheit ist das Ziel, ein reiner Knoten darf gross sein)*
- nur noch eine Klasse enthalten
- Besteht aus
- Wurzelknoten
- Entscheidungsknoten
- Blattknoten
- Äste
- Arbeitet nach Top-Down Prinzip
- Divide and Conquer
- Merkmale wählen dass die Daten am besten trennt
- Entweder mit Gini Koeffizient oder Entropie-Reduktion trennen
- Aufteilen entlang dieses Merkmales in eine oder mehrere Gruppen
- Rekursiv weiter aufteilen
- Stop wenn
- Daten in einem Knoten homogen sind
- keine sinvollen Splits mehr möglich
- maximale Tiefe erreicht
- Eigenschaften
- Gut nachvollziehbar
- Flexibel
- Geringe Anforderungen an Feature Engineering
- keine Normierung oder Skalierung
- Anfällig zu Overfitting!
- Feature Importance
- Wichtigkeit eines Features
- Wie stark trägt ein Feature zur Vorhersage bei?
- Ein Feature ist wichtig, wenn es
- oft gesplittet werden kann
- früh im Baum vorkommt
- grosse Verbesserungen der Reinheit bringt
- Zwei Arten von Feature Importance
- Impurity based Importance
- schnell
- berechnet man während des Trainings
- Importance ergibt sich aus der Summe aller Reinheitsverbesserungen, die dieses Feature bringt
- die Summen werden zum Schluss normiert, sodass alle Importances zusammen **1** ergeben *(Folie 81 — daher sind es relative Anteile)*
- Wann verwenden?
- Für erste Einschätzungen
- Um Übersicht zu gewinnen
- Wenn Modell nicht zu viele korellierte Features hat
- Permutation Importance
- robust
- langsam
- berechnet man nach dem Training
- misst wie stark die Modellleistung sinkt wenn ein Feature zufällig permutiert (durchgewürfelt) wird
- **sinkt** die Leistung stark → Feature ist wichtig → bleibt *(korrigiert: nicht „verändert sich → raus“)*
- bleibt die Leistung ~gleich → Feature unwichtig → kann raus
- permutieren über alle Features
- Wann verwenden?
- Wenn man eine verlässliche Feature-Wichtigkeit braucht
- Wenn man ein BlackBoxModel erklärbar machen will
- Prüfen auf Bias
- Importance = Baseline Score - Score nach Permutation:
1. Zuerst Baseline Leistung messen
2. Ein Feature permutieren
3. Leistung erneut messen
4. Wichtigkeitswert berechnen
### Gini Impurity
- misst wie wahrscheinlich es ist, dass zwei zufällig ausgewählte Elemente aus einem Knoten verschiedenen Klassen angehören
- Für einen Knoten mit Klassenanteilen p1,p2,...,pK:
- Gini = 1 - sum(i=1,k,pi^2)
- Gini = 0 -> perfekte Reinheit (nur eine Klasse)
- Gini hoch -> starke Durchmischung
- Vorteile
- Effizient
- Schneller als Entropie
- ideal für grosse Datensätze
- Gut geeignet für Random Forests
- Nachteile
- Bevorzugt Features mit vielen Splitpunkten
- Also numerische Features und solche mit vielen Kategorien
- Kann bei unbalancierten Klassen verzerren
### Entropie
- misst wie viel Unsicherheit in einem Datensegment steckt
- Entscheidungsbaum versucht Unsicherheit durch Splits zu reduzieren
- Für einen Knoten mit Klassenanteilen p1,p2,...,pK:
- entropie = -sum(i=1,k,pi*log2(pi))
- Entropie = 0 -> perfekte Reinheit (nur eine Klasse)
- Entropie hoch -> starke durchmischung
- Vorteile
- hohe sensitivität
- reagiert stärker auf Veränderung als Gini
- mathematisch sauber definiert
- gute Trennung bei seltenen Klassen
- Nachteile
- höherer Rechenaufwand als Gini, da Logarithmen berechnet werden müssen
- Ähnliches Verhalten wie Gini, der Aufwand lohnt sich also nicht immer
- Kann bei stark unbalancierten Daten instabil sein
- überempfindliche Splits bei seltenen Klassen
- Kann zu tiefen Bäumen führen
- overfitting
### Splitting
- ist der Prozess bei dem der Entscheidungsbaum die Frage auswählt, die Daten am besten trennt
- testet viele mögliche Splits und bewertet nach Reinheitsmass
- wählt Split mit höchstem Informationsgewinn
1. Alle features testen
- für jedes Feature mögliche Schwellenwerte prüfen
- Feature Alter -> teste 20,25,30,45 ...
- Feautre Einkommen -> teste 40k,50k,69k ...
2. für jeden Split die Reinheit berechnen
- berechnen wie "rein" die beiden entstehenden Gruppen sind, bspw. mit:
- Gini-Impurity
- Entropie
- Misclassification Error
3. Splitqualität bestimmen
- Baum misst wie stark sich die Reinheit verbessert
- je grösser Gain desto besser der Split
4. Den besten Split auswählen
5. Rekursiv weiter splitten
- bis Stopkriterium erreicht ist
### Pruning
- Pruning ist der Oberbegriff fürs Begrenzen der Baum-Komplexität gegen Overfitting; es gibt zwei Spielarten: Pre-Pruning (Wachstum begrenzen) und Post-Pruning (voll wachsen lassen, dann zurückschneiden) *(die Definition „nach dem Training verkleinern“ beschreibt genau genommen nur Post-Pruning)*
- Ziel ist es Overfitting zu reduzieren
- Vorteil
- reduziert overfitting
- verbessert generalisierung
- vereinfacht interpretierbarkeit
- erhöht stabilität
- verhindert unnötige splits
- Nachteile
- kann zu stark vereinfachen
- nicht immer nötig
- erfordert Validierungsdaten um optimal zu funktionieren
- rechenintensiver als pre-pruning
### Pre-Pruning
- setzt Wachstumsgrenzen für den Baum damit er nicht unnötig tief wird
- typische Kriterien
- maximale Tiefe
- minimale Samples pro Blatt
- minimale Verbesserung nötig für Split
- Methoden
- max_depth
- begrenzung der Baumtiefe
- min_samples_split
- nur splitten wenn genügend Datenpunkte verfügbar
- min_samples_leaf
- jedes Blatt muss mindestens n Samples enthalten
- min_impurity_decrease
- Split wird nur akzeptiert wenn er die Reinheit genügend verbessert
- max_leaf_nodes
- begrenzt die Anzahl Blätter direkt → kompakte Bäume
### Entscheidung Pruning/Prepruning
- Vorteile von Pre-Pruning
- schnell
- weniger Rechenaufwand
- verhindert overfitting früh
- einfachere modelle (flache bäume) sind einfacher zu verstehen
- Nachteile von Pre-Pruning
- kann gute Spliuts verhindern wenn Grenzen zu streng sind
- erfordert Hyperparameter-Tuning -> sonst Underfitting
- weniger flexibel als Post-Pruning
### Post-Pruning
- Post-Pruning schneided bereits gewachsene Bäume zurück um Overfitting zu reduzieren
- Methoden
- Cost-Complexity-Pruning *(in sklearn: Parameter `ccp_alpha`)*
- Reduced Error Pruning
- Vorteile
- robuster gegenüber neuen Daten
- verbessert generalisierung
- flexibler als Pre-Pruning, der Baum darf zuerst alle Muster entdecken
- Nachteile
- rechenintensiver
- benötigt Validierungsdaten
- komplexere Implementierung
## Decision Tree Classifier
- ist ein überwachter Machine-Learning-Algorihmus der Daten anhand einer Reihe von regelbasierten Entscheidungen klassifiziert
- Erstell ein umgedrehtes Baumdiegramm
- oben ist das wichtigste Merkmal
- jede Antwort führt zu einem neuen Ast und zu einer weiteren Frage
- bis ein Blattknoten erreicht wird, der die finale Klassenzuordnung enthält
---
## Praxis: Decision Tree Classifier (Code)
> Ergänzung zu den übersprungenen Praxis-Folien (bis Workshop 5). Datengrundlage:
> vorbereiteter Bank-Datensatz, geladen über das Kursmodul `bfh_cas_pml`.
### Basismodell
```python
from bfh_cas_pml import prep_data
from sklearn.tree import DecisionTreeClassifier
X_train, X_test, y_train, y_test = prep_data('bank_data_prep.csv', 'y', seed=1234)
model = DecisionTreeClassifier(random_state=1234) # random_state nur für Reproduzierbarkeit
model.fit(X_train, y_train)
print(model.score(X_test, y_test)) # ≈ 0.83
```
### Diagnose — Overfitting sichtbar machen
```python
print('depth :', model.get_depth()) # 28
print('leaves:', model.get_n_leaves()) # 777
print('train :', model.score(X_train, y_train)) # 1.0 <- perfekt
print('test :', model.score(X_test, y_test)) # 0.83
```
`train=1.0` vs `test=0.83` ist das Lehrbuch-Symptom: der voll ausgewachsene Baum
memoriert die Trainingsdaten (jedes Blatt rein), generalisiert aber schlecht.
→ Abhilfe = Pruning.
### Pre-Pruning per Hyperparameter-Tuning (Workshop 5: `min_impurity_decrease`)
Ein Split wird nur gemacht, wenn er die Impurity um mindestens diesen Wert senkt —
**normiert auf den ganzen Baum und gewichtet nach Knotengröße**:
```
ΔI_norm = (N_node / N_total) * ( I_parent - w_left*I_left - w_right*I_right )
```
Folge: tiefe Knoten betreffen wenige Samples → ihr ΔI_norm ist winzig → sinnvolle
Schwellen liegen bei ~1e-4 … 1e-2 (Float → `np.arange`, nicht `range`).
```python
import numpy as np
model = DecisionTreeClassifier(random_state=1234)
params = np.arange(0, 0.004, 0.0002)
scores = []
for p in params:
model.set_params(min_impurity_decrease=p)
model.fit(X_train, y_train)
scores.append(model.score(X_test, y_test))
best_i = np.argmax(scores) # Index des Maximums
print(f'best={scores[best_i]:.4f} @ {params[best_i]}') # ~0.879 @ 0.0004
```
Vorgehen = Wertebereich **schrittweise eingrenzen** (grob → fein). Erwarteter
Kurvenverlauf: kurzer Anstieg/Bump über der Baseline (0.83), dann Abfall, sobald
nützliche Splits wegfallen; im Extrem Stumpf → Accuracy ≈ Mehrheitsklasse.
> ⚠ Methodik-Caveat: hier wird gegen `X_test` getunt → **optimistic bias** (wie
> in W4). Der „beste“ Score ist optimistisch verzerrt; sauber wäre ein
> Validation-Split bzw. CV.
### Baum visualisieren (gepruntes Modell)
```python
from bfh_cas_pml import inspect_decision_tree_model
inspect_decision_tree_model(
DecisionTreeClassifier(min_impurity_decrease=0.0004, random_state=1234),
X_train, y_train)
# druckt depth/leaves/score und zeichnet plot_tree -> der geprunte Baum ist klein & lesbar
```
### Feature Importance (impurity-based)
```python
import pandas as pd
import seaborn as sns
imp = pd.Series(model.feature_importances_, index=X_train.columns).sort_values()
sns.barplot(x=imp.values, y=imp.index) # horizontaler Bar-Chart wie auf Folie 83
# Top-Features im Bank-Set: duration, nr_employed, month, euribor3m, age
```
Permutation Importance (robuster, in den Folien nur als Theorie):
```python
from sklearn.inspection import permutation_importance
r = permutation_importance(model, X_test, y_test, n_repeats=10, random_state=1234)
perm = pd.Series(r.importances_mean, index=X_train.columns).sort_values()
```
---
## RandomForest Tree
- ist ein ensemble Lernverfahren das aus vielen einzelnen Entscheidungsbäumen besteht
- jeder Baum trifft eine Vorhersage und der RandomForest kombiniert diese zu einer Gesamtvorhersage
- Sammlung zufällig trainierter Entscheidungsbäume
- Gemeinsame Entscheidung ist besser als einzelne Vorhersagen
### Ablauf
1. Bootstrap-Sampling
- Für jeden baum zufälliges Dataset ziehen (mit zurücklegen)
2. Random Feature Selection
- Bei jedem Split darf der Baum nur aus einer zufälligen Auswahl von Features wählen
3. Viele Bäume trainieren
- 100-1000 Bäume
- jeder Baum ist schwach, zusammen sind sie stark
4. Aggregation der Vorhersagen
- Klassifikation (Mehrheitsvoting)
- Regression (Durchschnitt aller Baumvorhersagen)
### Hyperparameter
1. n_estimators
- Anzahl der Bäume im Wald
- Mehr Bäume -> stabiler, genauer aber langsamer
2. max_depth
- Maximale Tiefe jedes einzelnen Baums
- Klein -> verhindert Overfitting
- Gross -> jeder Baum wird komplexer
3. max_features
- Wie viele Features pro Split?
- Klassifikation oft "sqrt"
4. min_samples_split
- Minimale Anzahl Samples die nötig sind um einen Split zu erzeugen
- Höher -> glattere, stabilere Bäume
- Tiefer -> Mehr Splits
5. min_samples_leaf
- Minimale Anzahl Samples in einem Blatt
- Höher -> robust gegen rauschen
- Tiefer -> feinere instabilere Blätter (bei unbalancierten Daten wichtig)
6. Bootstrap
- Ob bootstrap-Sampling verwendet wird
- True -> jeder Baum sieht zufällige Daten
- False -> alle Bäume sehen dieselben Daten
7. criterion
- Reinheitsmass für Splits
- Klassifikation: Gini oder entropy
- Regression: squared_error oder absolute_error
8. max_leaf_nodes
- Begrenzt die Anzahl Blätter pro Baum
- Verhindert extreme Tiefe
9. oob_score
- Out Of Bag validierung aktivieren
- Liefert eine eingebaute Testgenauigkeit
- Spart einen separaten Validierungssplit
### Unterschied zu DecisionTree
- es werden viele Bäume trainiert (100-1000)
- jeder Baum basiert auf Zufallsstichprobe
- kein Pruning, Bäume werden voll ausgebaut
- Vorhersage: Alle Bäume werden aus gewertet und es wird abgestimmt
- DecistionTree, wenn
- leicht erklärbares Modell wird benötigt
- Daten sind einfach und Overfitting kontrollierbar ist
- schnelle Trainings und Vorhersagezeiten
- Random Forest, wenn
- Maximale Genauigkeit
- komplexe Daten, verrauscht, hochdimensional
- Robustheit
- Overfitting unbedingt zu vermeiden ist