From 7e0b684afb74bb40d9f48320a36289ae4a2dd7c6 Mon Sep 17 00:00:00 2001 From: aaron Date: Thu, 18 Jun 2026 14:53:56 +0200 Subject: [PATCH] fix: encoding --- NSL/aufgaben/README.md | 2 - NSL/aufgaben/src/k_means2_elbow_measures.py | 131 ++++++++++++++++++++ 2 files changed, 131 insertions(+), 2 deletions(-) diff --git a/NSL/aufgaben/README.md b/NSL/aufgaben/README.md index de54eb0..e4b9b83 100644 --- a/NSL/aufgaben/README.md +++ b/NSL/aufgaben/README.md @@ -24,8 +24,6 @@ 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 1. Daten generieren: je 100 Punkte um die Zentren $(0,0)$, $(6,6)$, $(0,6)$ via `np.random.randn` (Seed fix → reproduzierbar) diff --git a/NSL/aufgaben/src/k_means2_elbow_measures.py b/NSL/aufgaben/src/k_means2_elbow_measures.py index e69de29..7aa50c8 100644 --- a/NSL/aufgaben/src/k_means2_elbow_measures.py +++ b/NSL/aufgaben/src/k_means2_elbow_measures.py @@ -0,0 +1,131 @@ +import numpy as np +import matplotlib.pyplot as plt +from sklearn.cluster import KMeans +from sklearn.metrics import silhouette_score, davies_bouldin_score + +# ========================================================= +# ?? EINSTELLUNGEN +# ========================================================= + +RANDOM_SEED = 42 +MAX_K = 8 +POINTS_PER_CLUSTER = 100 + +# echte Cluster (für Simulation) +CENTER_1 = [0, 0] +CENTER_2 = [6, 6] +CENTER_3 = [0, 6] + +# ========================================================= +# 1. DATEN GENERIEREN +# ========================================================= + +np.random.seed(RANDOM_SEED) + +data1 = np.random.randn(POINTS_PER_CLUSTER, 2) + CENTER_1 +data2 = np.random.randn(POINTS_PER_CLUSTER, 2) + CENTER_2 +data3 = np.random.randn(POINTS_PER_CLUSTER, 2) + CENTER_3 + +X = np.vstack((data1, data2, data3)) + +# ========================================================= +# 2. ELBOW + GÜTEMASSE +# ========================================================= + +k_values = range(1, MAX_K + 1) +inertia_values = [] +silhouette_values = [] +db_values = [] + +for k in k_values: + kmeans = KMeans(n_clusters=k, random_state=RANDOM_SEED, n_init=10) + kmeans.fit(X) + + inertia_values.append(kmeans.inertia_) + + if k >= 2: + labels = kmeans.labels_ + silhouette_values.append(silhouette_score(X, labels)) + db_values.append(davies_bouldin_score(X, labels)) + else: + silhouette_values.append(np.nan) + db_values.append(np.nan) + +# ========================================================= +# 3. BESTES k (vereinfacht: nach Silhouette) +# ========================================================= + +best_k = k_values[np.nanargmax(silhouette_values)] + +# Frage: +# Warum nehmen wir hier Silhouette und nicht Inertia? +# Lösung: +# ? Inertia sinkt immer ? kein klares Optimum + +# ========================================================= +# 4. FINALES MODELL +# ========================================================= + +kmeans_final = KMeans(n_clusters=best_k, random_state=RANDOM_SEED, n_init=10) +kmeans_final.fit(X) + +labels_final = kmeans_final.labels_ +centers_final = kmeans_final.cluster_centers_ + +# ========================================================= +# 5. VISUALISIERUNG +# ========================================================= + +fig, ax = plt.subplots(1, 4, figsize=(20, 4)) + +# ---- Originaldaten ---- +ax[0].scatter(X[:, 0], X[:, 1]) +ax[0].set_title("Rohdaten (unclustered)") + +# Frage: +# Siehst du hier schon Cluster? +# Lösung: +# ? Ja, visuell oft erkennbar, aber nicht immer eindeutig + +# ---- Elbow ---- +ax[1].plot(k_values, inertia_values, marker="o") +ax[1].set_title("Elbow (Inertia)") +ax[1].set_xlabel("k") +ax[1].set_ylabel("Fehler") + +# ---- Silhouette ---- +ax[2].plot(k_values, silhouette_values, marker="o") +ax[2].set_title("Silhouette Score") +ax[2].set_xlabel("k") + +# ---- Finales Clustering ---- +scatter = ax[3].scatter(X[:, 0], X[:, 1], c=labels_final) +ax[3].scatter(centers_final[:, 0], centers_final[:, 1], c="red", s=200, marker="X") +ax[3].set_title(f"K-Means Ergebnis (k={best_k})") + +# Frage: +# Warum sind die Cluster farbig getrennt? +# Lösung: +# ? Hard Clustering: jeder Punkt genau ein Label + +plt.tight_layout() +plt.show() + +# ========================================================= +# ? WEITERE FRAGEN +# ========================================================= + +# Frage: +# Was passiert, wenn wir die Daten stärker überlappen lassen? +# Lösung: +# ? Clustering wird schwieriger, Scores schlechter + +# Frage: +# Warum können verschiedene Runs unterschiedliche Ergebnisse liefern? +# Lösung: +# ? zufällige Initialisierung der Zentren + +# Frage: +# Ist das gefundene k immer korrekt? +# Lösung: +# ? Nein, nur heuristisch bestimmt