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

13 KiB

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

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

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).

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)

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)

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):

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