103 lines
4.9 KiB
Markdown
103 lines
4.9 KiB
Markdown
# Workshop 06 — RandomForestClassifier: Parameter Tuning
|
|
|
|
## Aufgabe
|
|
|
|
Drei Tuning-Parameter des `RandomForestClassifier` auf die erreichte Accuracy
|
|
untersuchen (vorbereiteter Bank-Datensatz, identisch zu WS5), je über einen
|
|
vorgegebenen Wertebereich:
|
|
|
|
| Parameter | Wertebereich | Typ |
|
|
|------------------------|---------------------------|-------|
|
|
| `n_estimators` | `range(100, 500, 50)` | int |
|
|
| `max_features` | `range(1, 11)` | int |
|
|
| `min_impurity_decrease`| `np.arange(0, 0.1, 0.01)` | float |
|
|
|
|
Zusätzlich: Wirkung von `random_state` einordnen, und (Zusatzfrage) bestimmen,
|
|
welche der übrigen Parameter keine Tuning-Parameter sind.
|
|
|
|
## Vorgehen
|
|
|
|
Wiederverwendung des Sweep-/Plot-Gerüsts aus WS5. Die einzige Anpassung war die
|
|
Generalisierung der Sweep-Funktion auf einen frei wählbaren Parameternamen
|
|
(`set_params` per dict-Unpacking), womit sich alle drei Parameter mit derselben
|
|
Funktion abdecken lassen. Jeder Sweep hält die übrigen Parameter auf den
|
|
Defaults und variiert nur den untersuchten.
|
|
|
|
Pro Sweep: Liniendiagramm (Parameter vs. Accuracy) mit markiertem Maximum sowie
|
|
Konsolenausgabe von bestem Score und zugehörigem Parameterwert.
|
|
|
|
`n_jobs=-1` gesetzt — bei bis zu 450 Bäumen pro Fit und mehreren Fits pro Sweep
|
|
ist die Parallelisierung über alle Cores hier praktisch zwingend, nicht
|
|
optional. `n_jobs` ist dabei reiner Performance-Schalter ohne Einfluss auf das
|
|
Resultat.
|
|
|
|
## Resultate
|
|
|
|
| Parameter | bester Score | bei Wert |
|
|
|------------------------|--------------|----------|
|
|
| `n_estimators` | 0.8792 | 400 |
|
|
| `max_features` | 0.8780 | 6 |
|
|
| `min_impurity_decrease`| 0.8750 | 0.0 |
|
|
|
|
Interpretation der einzelnen Verläufe:
|
|
|
|
**`n_estimators`** — die Kurve bewegt sich über den gesamten Bereich nur
|
|
zwischen 0.875 und 0.879. Diese Schwankung liegt im Bereich des Seed-Rauschens
|
|
und ist kein echtes Optimum. Die belastbare Aussage lautet: Plateau ab ~150
|
|
Bäumen, danach reine Rechenzeit ohne Mehrwert. Der nominelle „Peak" bei 400 ist
|
|
nicht als optimaler Wert zu interpretieren.
|
|
|
|
**`max_features`** — hier liegt echtes Signal vor: Anstieg von ~0.857 (bei 1)
|
|
auf ein breites Maximum ab ~4 Features. Der beste Wert (6) liegt nahe am
|
|
sklearn-Default `sqrt(n_features)` für Klassifikation, was den Default bestätigt.
|
|
Zu kleine Werte machen die einzelnen Bäume zu zufällig (Underfit); zu grosse
|
|
Werte erhöhen die Korrelation zwischen den Bäumen und schmälern den
|
|
Ensemble-Vorteil.
|
|
|
|
**`min_impurity_decrease`** — bestes Resultat bei 0 (kein Pruning), danach
|
|
monotoner Abfall auf ein Plateau bei ~0.757. Das ist das aufschlussreichste
|
|
Ergebnis des Workshops und der direkte Kontrast zu WS5: beim einzelnen
|
|
DecisionTree hat Pre-Pruning das Overfitting reduziert und die Test-Accuracy
|
|
verbessert. Beim Random Forest übernimmt das Bagging diese Varianzkontrolle
|
|
bereits auf Ensemble-Ebene — Pruning der einzelnen Bäume nimmt ihnen die
|
|
gewollte Varianz und kann die Accuracy daher praktisch nur verschlechtern.
|
|
|
|
## Wirkung von `random_state`
|
|
|
|
Der Random Forest hat zwei Zufallsquellen: das Bootstrap-Sampling (welche Zeilen
|
|
jeder Baum sieht) und die Random Feature Selection (welche Features pro Split zur
|
|
Wahl stehen). `random_state` seedet beide und macht den Lauf reproduzierbar.
|
|
|
|
Der Effekt des konkreten Seeds nimmt mit steigendem `n_estimators` ab: bei wenig
|
|
Bäumen schwankt die Accuracy je nach Seed merklich, bei vielen Bäumen mittelt
|
|
sich das aus. Ein Teil der Zacken im `n_estimators`-Verlauf ist genau diese
|
|
Seed-Variation und nicht echtes Signal — siehe Interpretation oben.
|
|
|
|
## Zusatzfrage: Nicht-Tuning-Parameter
|
|
|
|
Kriterium: ein Tuning-Parameter verschiebt den Bias-Varianz-Tradeoff bzw. die
|
|
Kapazität des Modells. Parameter, die nur Infrastruktur, Reproduzierbarkeit,
|
|
Logging, Workflow oder Reporting steuern, sind keine Tuning-Parameter. Aus
|
|
`model.get_params()` betrifft das:
|
|
|
|
- `random_state` — Seed (Reproduzierbarkeit)
|
|
- `n_jobs` — Parallelisierung (Performance)
|
|
- `verbose` — Logging-Ausgabe
|
|
- `warm_start` — Workflow-Schalter für inkrementelles Fitten
|
|
- `oob_score` — schaltet nur die Out-of-Bag-Schätzung als Reporting an, ändert
|
|
das gefittete Modell nicht
|
|
|
|
Grenzfälle wie `bootstrap`, `class_weight` oder `max_samples` beeinflussen das
|
|
Modell hingegen sehr wohl und zählen damit zu den Tuning-Parametern.
|
|
|
|
## Caveats / Deviations
|
|
|
|
- **One-at-a-time-Tuning**: jeder Parameter wurde einzeln bei Defaults der
|
|
übrigen variiert. Damit werden Wechselwirkungen zwischen Parametern nicht
|
|
erfasst; das gemeinsame Optimum kann von der Kombination der drei
|
|
Einzelbestwerte abweichen. Eine gemeinsame Suche (`GridSearchCV`, vgl. WS4)
|
|
wäre dafür das richtige Werkzeug.
|
|
- **Optimistic Bias**: wie in WS4/WS5 wird direkt gegen das Test-Set getunt. Die
|
|
berichteten Bestwerte sind dadurch optimistisch verzerrt; sauber wäre ein
|
|
Validierungs-Split bzw. Cross-Validation.
|