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

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?