K-Means: Elbow-Methode & Gütemasse
Thema: Optimale Clusterzahl
kbestimmen und Clusterqualität bewerten Skript: Unsupervised Learning (CAS PML)
Ziel
Auf synthetischen 2D-Daten (drei Gauss-Blobs) K-Means für verschiedene k laufen lassen und die "richtige" Clusterzahl systematisch über Gütemasse bestimmen — statt nur visuell zu schätzen.
Projektstruktur
.
├── data/ # leer: Daten werden synthetisch generiert
├── src/
│ └── k_means2_elbow_measures.py
├── devenv.nix
└── README.md
Ausführen (in der devenv-Shell):
python src/k_means2_elbow_measures.py
Hinweis: Das erhaltene Textfile hat kaputte Umlaute (Windows-1252 statt UTF-8). Beim Übernehmen nach
src/als UTF-8 neu speichern, sonst sind die Kommentare unleserlich.
Ablauf des Skripts
- Daten generieren: je 100 Punkte um die Zentren
(0,0),(6,6),(0,6)vianp.random.randn(Seed fix → reproduzierbar) - Für
k = 1 \dots 8K-Means fitten und drei Masse sammeln:- Inertia (
kmeans.inertia_) — immer - Silhouette-Score und Davies-Bouldin-Index — erst ab
k \geq 2(fürk=1nicht definiert →np.nan)
- Inertia (
- Bestes
kwählen (vereinfacht: maximaler Silhouette-Score vianp.nanargmax) - Finales Modell mit
best_kfitten → Labels + Zentren - Visualisierung in vier Panels: Rohdaten | Elbow (Inertia) | Silhouette | finales Clustering
Gütemasse (Kurzreferenz)
- Inertia / WCSS — Summe der quadrierten Abstände zum jeweiligen Zentroid; sinkt monoton mit
k, hat also kein Optimum, nur einen "Knick" (Elbow)
\text{WCSS} = \sum_{i=1}^{k} \sum_{x \in P_i} \lVert x - \mu_i \rVert^2
- Silhouette-Score —
a_i= mittlere Intra-Cluster-Distanz,b_i= mittlere Distanz zum nächsten Cluster; Bereich[-1, 1], höher = besser
s_i = \frac{b_i - a_i}{\max(a_i, b_i)}
- Davies-Bouldin-Index — mittleres "Worst-Case"-Verhältnis von Cluster-Streuung zu Cluster-Abstand; 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)}
- mit
\sigma_i= mittlere Distanz der Punkte in Clusterizu ihrem Zentroidc_i
Verständnisfragen (im Code eingebettet)
- Warum nimmt man zur $k$-Wahl die Silhouette und nicht die Inertia?
- Warum sind die Cluster im Ergebnis-Plot farblich klar getrennt?
- Warum können verschiedene Runs unterschiedliche Ergebnisse liefern?
- Ist das gefundene
kimmer "korrekt"?
Experimente (zum Ausprobieren)
- Zentren näher zusammenlegen (Daten stärker überlappen) → wie verändern sich Elbow und Scores?
- Davies-Bouldin gegen die Silhouette als $k$-Kriterium tauschen → wählt es dasselbe
k? n_initreduzieren / Seed variieren → wie stabil ist das Ergebnis?
Zu allen Verständnisfragen stehen im Skript kurze Musterantworten als Kommentar.