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 mitk, 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.
- Datensatz aus tab-separiertem File laden (Pandas)
- Daten visualisieren und eine sinnvolle Clusterzahl visuell und systematisch finden
- Daten clustern
Datensatz data_delivery_fleet.tsv (3 Spalten):
Driver_ID– ID der Fahrer:inDistance_Feature– mittlere gefahrene Meilen pro TagSpeeding_Feature– % der Zeit über dem Tempolimit (>5 mph)
Geclustert wird auf Distance_Feature × Speeding_Feature.
Ablauf von uebung1_kmeans_fleet.py (PNGs in plots/):
- Rohdaten-Scatter (
01_rohdaten.png) - K-Means mit frei gewähltem
k=4(02_kmeans_k4.png) - Sweep
k = 1 \dots 8als Übersichts-Grid (03_kmeans_sweep_k1-8.png) küber Inertia/Elbow (04), erklärte Varianz (05), Silhouette (06)- 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.
- Datensatz (tab-separiert) laden
- 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):
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):
- Daten laden & verstehen (dtypes → numerisch vs. kategorial, ID-Spalte raus?)
- Features vorbereiten:
Xbauen +categorical_idxsetzen kfinden: Elbow übercost_- finales Clustering fitten
- 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):
- Daten generieren: je 100 Punkte um
(0,0),(6,6),(0,6)(Seed fix) - Für
k = 1 \dots 8K-Means fitten und Inertia, Silhouette, Davies-Bouldin sammeln - Bestes
kwählen (vereinfacht: max. Silhouette) - 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!) → dasselbek?