Files
cas-pml/SL/aufgaben/workshop8/README.md
T

119 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Workshop 08 — Standardisierung & Lineare Regression
> CAS Practical Machine Learning · Supervised Learning · Lektion 5 (Foliensatz 13, Folie 68)
> Zeit: 60'
## Aufgabenstellung
Untersuche den Einfluss des **Standardisierens der Features** auf folgende Ergebnisse
der Linearen Regression:
- Modellkoeffizienten
- Predictions
- Score (R²)
**Optional / zu Hause:** Untersuche den Einfluss des **Logarithmierens des Targets**
auf die Performance der Linearen Regression.
## Datensatz
Fortsetzung des Praxisteils → **Melbourne Housing Dataset**.
| Datei | Inhalt |
| ---------------------- | --------------------------------------------------- |
| `data/melb_data_prep.csv` | aufbereiteter Datensatz (Workshop 03), Target `Price` |
| `src/bfh_cas_pml.py` | Kursmodul mit `prep_data()` / `prep_demo_data()` |
Beide Dateien stammen aus den Kursmaterialien (analog `bank_data_prep.csv` + `bfh_cas_pml.py`
bei WS6). `prep_data()` erledigt Feature-Target-Split **und** Train-Test-Split:
```python
from bfh_cas_pml import prep_data
X_train, X_test, y_train, y_test = prep_data("data/melb_data_prep.csv", "Price", seed=1234)
```
**Fallback** (self-contained, falls die Kursdateien fehlen): `sklearn.datasets.fetch_california_housing`
— ebenfalls Immobilienpreise mit rechtsschiefem Target, gut für den Log-Teil.
## Ordnerstruktur
```
workshop8
├── data
│ └── melb_data_prep.csv # aus Kursmaterial (oder Fallback via sklearn)
├── devenv.lock
├── devenv.nix
├── README.md
└── src
├── bfh_cas_pml.py # aus Kursmaterial (nur für Melbourne-Variante)
└── linearregression.py # Lösung
```
## Vorgehen
1. Daten laden (Variante wählen: Melbourne oder California-Fallback).
2. **Baseline** ohne Standardisierung: `LinearRegression` fitten → `coef_`, `intercept_`, Predictions, Score festhalten.
3. **Mit Standardisierung**: `StandardScaler` *nur auf `X_train`* fitten, dann `X_train` + `X_test` transformieren → erneut fitten, dieselben Grössen festhalten.
4. **Vergleichen**: Koeffizienten, Predictions, Score gegenüberstellen.
5. *(optional)* Target logarithmieren (`log1p`/`expm1`), Performance auf Originalskala vergleichen.
## Erkenntnisse
### Standardisierung (Schritte 13)
**Kernaussage:** Bei der einfachen `LinearRegression` ändert Standardisieren der Features
**nur** Koeffizienten und Intercept (→ Interpretation), **nicht** aber Predictions und Score.
OLS ist invariant gegenüber linearer Umskalierung der Features.
- **Koeffizienten** — ändern sich. Zusammenhang: `coef_std ≈ coef_roh * X_train.std(axis=0)`
(Populations-Std, `ddof=0`). Die skalierten Koeffizienten sind „pro Standardabweichung"-Gewichte
→ das ist das **standardisierte Regressionsgewicht β** aus dem Theorieteil. Erst dadurch werden
die Features untereinander vergleichbar (Roh-Koeffizienten hängen an der jeweiligen Feature-Skala).
- **Intercept** — ändert sich: von ≈ 1.06e8 (Vorhersage am unsinnigen Punkt „alle Rohwerte = 0")
auf ≈ +1.06e6. Nach dem Skalieren liegt „alle Features = 0" beim Mittelwert jedes Features →
dort sagt OLS gerade `y_train.mean()` voraus, also `intercept_std ≈ y_train.mean()`.
- **Predictions** — identisch (bis auf Fliesskomma-Rauschen). OLS „sieht" eine reine Umskalierung
der Achsen nicht: die Geometrie der Punktwolke bleibt gleich, das Modell gleicht die Skalierung
vollständig über die Koeffizienten aus.
- **Score (R²)** — identisch: `0.5601419746121108` vs. `…148` (Unterschied erst an der 14. Stelle
= numerisches Rauschen aus dem unterschiedlich skalierten Gleichungssystem, kein echter Effekt).
**Warum bei einfacher LR egal:** OLS wird analytisch über die Normalgleichungen gelöst, kein
iterativer Solver → die Skalierung beeinflusst weder Lösung noch Konvergenz.
**Wann Standardisierung _doch_ zählt:**
- **Ridge / Lasso**: der Strafterm ($\lambda \sum \beta_j^2$ bzw. $\lambda \sum |b_j|$) bestraft die
Koeffizienten*grösse* — die hängt bei Rohdaten an der Feature-Skala → ungleiche Bestrafung.
Darum „Standardisierung erforderlich" (vgl. Theorienotizen, Ridge). Hier ändert Skalieren das
Ergebnis tatsächlich.
- **Interpretierbarkeit / Feature-Vergleich** über β (s.o.).
- **iterative Solver** (Gradientenverfahren): Konvergenz — bei OLS irrelevant.
### Log-Target (Schritt 4, optional — noch offen)
Anders als Feature-Scaling verändert eine **Target**-Transformation das Modell _wirklich_:
`log(y)` modelliert einen multiplikativen statt additiven Zusammenhang.
Vorgehen:
- fit auf `np.log1p(y_train)`
- Predictions mit `np.expm1(...)` **zurücktransformieren**, *bevor* R² auf der Originalskala gerechnet wird
- `log1p`/`expm1` statt `log`/`exp` wegen möglicher Nullwerte (`log(0)` undefiniert)
Erwartung (Hypothese, selbst verifizieren):
- Preise sind rechtsschief → Log-Transform macht die Verteilung symmetrischer, Residuen homoskedastischer
- `expm1` ist immer > 0 → keine negativen Preis-Vorhersagen mehr (vgl. Folien-Fazit S. 64)
- R² auf der Originalskala kann sich ändern — **Achtung:** nicht Log-Skala mit Original-Skala vergleichen
## Wichtig
- Scaler **nur auf Trainingsdaten** fitten → sonst Data Leakage.
- Beim Log-Target Predictions **vor** der R²-Berechnung zurücktransformieren.
## Quellen
- Foliensatz 13 (Regressionsanalyse), V. Vogel, TI BFH — Praxisteil & Folie 68
- Notizen: `../../L5_Notizen.md`