This repository has been archived on 2026-06-23. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
cas-pml/NSL/aufgaben/README.md
T

134 lines
4.9 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.
# CAS PML Unsupervised Learning: Clustering-Aufgaben
> Modul: CAS Practical Machine Learning Unsupervised Learning (Dehmer)
> Inhalt: die zwei Clustering-Übungen aus dem Skript, plus ein Elbow-Demo
## Projektstruktur
```
.
├── data/
│ ├── data_delivery_fleet.tsv # Übung 1
│ └── data_stocks.tsv # Übung 2 (Dateiname ggf. anpassen)
├── plots/ # generierte PNGs (headless)
├── src/
│ ├── uebung1_kmeans_fleet.py # Übung 1: k-Means
│ ├── uebung2_kprototypes_stocks.py # Übung 2: k-Prototypes
│ └── k_means2_elbow_measures.py # Zusatz: Elbow & Gütemasse
├── devenv.nix
└── README.md
```
## Setup & Ausführen
In der devenv-Shell:
```
python src/uebung1_kmeans_fleet.py
python src/uebung2_kprototypes_stocks.py
python src/k_means2_elbow_measures.py
```
Alle Skripte laufen **headless**: Plots werden als PNG nach `plots/` geschrieben (kein `plt.show()`, da in der Shell kein Display Agg-Backend).
## Gütemasse zur Wahl von $k$ (gemeinsame Referenz)
- Inertia / WCSS (k-Means) bzw. `cost_` (k-Prototypes) Summe der Abstände/Unähnlichkeiten zum Zentrum; sinkt monoton mit $k$, daher nur "Knick" (Elbow)
$$ \text{WCSS} = \sum_{i=1}^{k} \sum_{x \in P_i} \lVert x - \mu_i \rVert^2 $$
- Erklärte Varianz Anteil der Between-Cluster-Varianz an der Gesamtvarianz, höher = besser (ideal 100 %)
$$ \text{Variance Explained} = \frac{\text{BSS}}{\text{TSS}} \cdot 100\,\% $$
- Silhouette-Score $a_i$ = mittlere Intra-, $b_i$ = mittlere nächste Inter-Cluster-Distanz; Bereich $[-1, 1]$, höher = besser
$$ s_i = \frac{b_i - a_i}{\max(a_i, b_i)} $$
- Davies-Bouldin (nur Zusatz-Demo) niedriger = besser (Achtung: umgekehrt zur Silhouette)
$$ DB = \frac{1}{k} \sum_{i=1}^{k} \max_{j \neq i} \frac{\sigma_i + \sigma_j}{d(c_i, c_j)} $$
---
## Übung 1 — k-Means: Delivery Fleet
Aufgabenstellung (Skript): Fleet-Daten von Lieferfahrer:innen clustern.
1. Datensatz aus tab-separiertem File laden (Pandas)
2. Daten visualisieren und eine sinnvolle Clusterzahl visuell *und* systematisch finden
3. Daten clustern
Datensatz `data_delivery_fleet.tsv` (3 Spalten):
- `Driver_ID` ID der Fahrer:in
- `Distance_Feature` mittlere gefahrene Meilen pro Tag
- `Speeding_Feature` % der Zeit über dem Tempolimit (>5 mph)
Geclustert wird auf `Distance_Feature` × `Speeding_Feature`.
Ablauf von `uebung1_kmeans_fleet.py` (PNGs in `plots/`):
1. Rohdaten-Scatter (`01_rohdaten.png`)
2. K-Means mit frei gewähltem $k=4$ (`02_kmeans_k4.png`)
3. Sweep $k = 1 \dots 8$ als Übersichts-Grid (`03_kmeans_sweep_k1-8.png`)
4. $k$ über Inertia/Elbow (`04`), erklärte Varianz (`05`), Silhouette (`06`)
5. finales Modell mit bestem $k$ (`07_final.png`)
> Anpassungen ggü. Notebook: `.as_matrix()` → `.to_numpy()`; `plt.show()` → `savefig`; Hartigan als optionaler Legacy-Block (`RUN_HARTIGAN = False`).
---
## Übung 2 — k-Prototypes: Stock Data
Aufgabenstellung (Skript): einen grösseren Stock-Datensatz clustern.
1. Datensatz (tab-separiert) laden
2. Daten clustern
Warum k-Prototypes? Die Daten sind **gemischt** (numerisch + kategorial):
- k-Means → nur numerisch
- k-Modes → nur kategorial (Modus statt Mittel, Mismatch-Distanz)
- k-Prototypes = beides kombiniert, gewichtet über $\gamma$
$$ D(x, c) = \underbrace{\sum_{\text{num}} (x_j - c_j)^2}_{\text{numerisch (L2)}} + \gamma \underbrace{\sum_{\text{cat}} \delta(x_j, c_j)}_{\text{kategorial (Mismatches)}} $$
API-Kern (`kmodes`):
```python
from kmodes.kprototypes import KPrototypes
kp = KPrototypes(n_clusters=k, init="Cao", random_state=0, n_init=5)
labels = kp.fit_predict(X, categorical=[<indizes>])
kp.cost_ # Elbow-Analogon zur Inertia
kp.cluster_centroids_ # numerisch = Mittel, kategorial = Modus
```
Gerüst-Abschnitte in `uebung2_kprototypes_stocks.py` (mit TODO selbst füllen):
1. Daten laden & verstehen (dtypes → numerisch vs. kategorial, ID-Spalte raus?)
2. Features vorbereiten: $X$ bauen + `categorical_idx` setzen
3. $k$ finden: Elbow über `cost_`
4. finales Clustering fitten
5. Interpretation: Cluster je Feature beschreiben, semantisch deuten
---
## Zusatz — Elbow-Methode & Gütemasse (synthetisch)
Kein Skript-Auftrag, sondern ein Demo zur $k$-Wahl auf synthetischen Daten
(drei Gauss-Blobs). Vergleicht Inertia (Elbow), Silhouette und Davies-Bouldin.
Ablauf von `k_means2_elbow_measures.py` (4-Panel-Plot):
1. Daten generieren: je 100 Punkte um $(0,0)$, $(6,6)$, $(0,6)$ (Seed fix)
2. Für $k = 1 \dots 8$ K-Means fitten und Inertia, Silhouette, Davies-Bouldin sammeln
3. Bestes $k$ wählen (vereinfacht: max. Silhouette)
4. Finales Modell + Visualisierung (Rohdaten | Elbow | Silhouette | Ergebnis)
Verständnisfragen / Experimente:
- [ ] Warum zur $k$-Wahl Silhouette statt Inertia?
- [ ] Daten stärker überlappen lassen → wie verändern sich die Scores?
- [ ] Davies-Bouldin statt Silhouette als Kriterium (dann `argmin`!) → dasselbe $k$?