fix: add correct naming
This commit is contained in:
@@ -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
|
||||||
@@ -29,7 +30,7 @@ from scipy.spatial.distance import cdist, pdist
|
|||||||
# EINSTELLUNGEN / PFADE
|
# EINSTELLUNGEN / PFADE
|
||||||
# =========================================================
|
# =========================================================
|
||||||
|
|
||||||
BASE = Path(__file__).resolve().parent.parent # .../aufgaben
|
BASE = Path(__file__).resolve().parent.parent # .../aufgaben
|
||||||
DATA = BASE / "data" / "data_delivery_fleet.tsv"
|
DATA = BASE / "data" / "data_delivery_fleet.tsv"
|
||||||
PLOTS = BASE / "plots"
|
PLOTS = BASE / "plots"
|
||||||
PLOTS.mkdir(exist_ok=True)
|
PLOTS.mkdir(exist_ok=True)
|
||||||
@@ -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 = [
|
||||||
data,
|
silhouette_score(
|
||||||
KMeans(n_clusters=k, n_init=10, random_state=RANDOM_SEED).fit(data).labels_,
|
data,
|
||||||
metric="euclidean")
|
KMeans(n_clusters=k, n_init=10, random_state=RANDOM_SEED).fit(data).labels_,
|
||||||
for k in ks_sil]
|
metric="euclidean",
|
||||||
|
)
|
||||||
|
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:
|
||||||
|
|||||||
Reference in New Issue
Block a user