fix: add correct naming

This commit is contained in:
2026-06-18 15:39:57 +02:00
parent 6371ebf1e2
commit 3423172072
2 changed files with 25 additions and 12 deletions
+22 -9
View File
@@ -14,6 +14,7 @@ Umbau aus dem Lösungs-Notebook (lektion_1.ipynb):
""" """
import matplotlib import matplotlib
matplotlib.use("Agg") # headless: nur in Dateien rendern matplotlib.use("Agg") # headless: nur in Dateien rendern
from pathlib import Path from pathlib import Path
@@ -107,8 +108,10 @@ plt.close(fig)
# ---- Within-Cluster Sum of Squares (Inertia) ---- # ---- Within-Cluster Sum of Squares (Inertia) ----
Ks = range(1, 10) Ks = range(1, 10)
inertia = [KMeans(n_clusters=k, n_init=10, random_state=RANDOM_SEED).fit(data).inertia_ inertia = [
for k in Ks] KMeans(n_clusters=k, n_init=10, random_state=RANDOM_SEED).fit(data).inertia_
for k in Ks
]
fig, ax = plt.subplots() fig, ax = plt.subplots()
ax.bar(Ks, inertia) ax.bar(Ks, inertia)
@@ -122,12 +125,14 @@ plt.close(fig)
# ---- Percentage of Variance Explained ---- # ---- Percentage of Variance Explained ----
# TSS = WCSS + BSS -> Variance Explained = BSS / TSS # TSS = WCSS + BSS -> Variance Explained = BSS / TSS
ks = range(1, 10) ks = range(1, 10)
models = [KMeans(n_clusters=k, n_init=10, random_state=RANDOM_SEED).fit(data) for k in ks] models = [
KMeans(n_clusters=k, n_init=10, random_state=RANDOM_SEED).fit(data) for k in ks
]
centroids = [m.cluster_centers_ for m in models] centroids = [m.cluster_centers_ for m in models]
# Abstand jedes Punkts zum nächsten Zentrum -> WCSS pro k # Abstand jedes Punkts zum nächsten Zentrum -> WCSS pro k
dist = [np.min(cdist(data, cent, "euclidean"), axis=1) for cent in centroids] dist = [np.min(cdist(data, cent, "euclidean"), axis=1) for cent in centroids]
wcss = np.array([np.sum(d ** 2) for d in dist]) wcss = np.array([np.sum(d**2) for d in dist])
tss = np.sum(pdist(data) ** 2) / data.shape[0] tss = np.sum(pdist(data) ** 2) / data.shape[0]
bss = tss - wcss bss = tss - wcss
@@ -143,11 +148,14 @@ plt.close(fig)
# ---- Silhouette Score (erst ab k >= 2 definiert) ---- # ---- Silhouette Score (erst ab k >= 2 definiert) ----
ks_sil = range(2, 10) ks_sil = range(2, 10)
silhouette = [silhouette_score( silhouette = [
silhouette_score(
data, data,
KMeans(n_clusters=k, n_init=10, random_state=RANDOM_SEED).fit(data).labels_, KMeans(n_clusters=k, n_init=10, random_state=RANDOM_SEED).fit(data).labels_,
metric="euclidean") metric="euclidean",
for k in ks_sil] )
for k in ks_sil
]
fig, ax = plt.subplots() fig, ax = plt.subplots()
ax.plot(list(ks_sil), silhouette, marker="o") ax.plot(list(ks_sil), silhouette, marker="o")
@@ -166,7 +174,9 @@ print(f"Bestes k nach Silhouette: {best_k}")
# ========================================================= # =========================================================
k_means_final = KMeans(n_clusters=best_k, n_init=10, random_state=RANDOM_SEED).fit(data) k_means_final = KMeans(n_clusters=best_k, n_init=10, random_state=RANDOM_SEED).fit(data)
save_kmeans(data, k_means_final, "07_final.png", title=f"Finales Clustering (k={best_k})") save_kmeans(
data, k_means_final, "07_final.png", title=f"Finales Clustering (k={best_k})"
)
print(f"Plots gespeichert in: {PLOTS}") print(f"Plots gespeichert in: {PLOTS}")
@@ -177,6 +187,7 @@ print(f"Plots gespeichert in: {PLOTS}")
# Im Lösungs-Notebook enthalten, gilt aber als veraltet (vgl. Chiang & Mirkin). # Im Lösungs-Notebook enthalten, gilt aber als veraltet (vgl. Chiang & Mirkin).
# Silhouette/Elbow werden bevorzugt -> standardmässig deaktiviert (RUN_HARTIGAN). # Silhouette/Elbow werden bevorzugt -> standardmässig deaktiviert (RUN_HARTIGAN).
def hartigan_k(data, threshold=12): def hartigan_k(data, threshold=12):
"""'Korrekte' Clusterzahl nach Hartigan: erstes k mit H <= threshold.""" """'Korrekte' Clusterzahl nach Hartigan: erstes k mit H <= threshold."""
inertia_list = np.zeros(len(data) + 1) inertia_list = np.zeros(len(data) + 1)
@@ -186,7 +197,9 @@ def hartigan_k(data, threshold=12):
kmn = KMeans(n_clusters=num + 1, n_init=10, random_state=RANDOM_SEED).fit(data) kmn = KMeans(n_clusters=num + 1, n_init=10, random_state=RANDOM_SEED).fit(data)
inertia_list[num + 1] = kmn.inertia_ inertia_list[num + 1] = kmn.inertia_
if num > 0: if num > 0:
h_rule = ((float(inertia_list[num]) / inertia_list[num + 1]) - 1) * (len(data) - num - 1) h_rule = ((float(inertia_list[num]) / inertia_list[num + 1]) - 1) * (
len(data) - num - 1
)
print(f"k={num}, H={h_rule:.2f}") print(f"k={num}, H={h_rule:.2f}")
num += 1 num += 1
if h_rule > threshold: if h_rule > threshold: