Das Entdecken von Annahmen beim K-Means-Clustering

Machine LearningMachine LearningBeginner
Jetzt üben

This tutorial is from open-source community. Access the source code

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab werden wir den k-Means-Clustering-Algorithmus und seine Annahmen untersuchen. Wir werden Daten mit unterschiedlichen Verteilungen generieren und visualisieren, wie k-Means diese Daten in Cluster aufteilt. Wir werden auch einige der Einschränkungen des Algorithmus diskutieren und mögliche Lösungen, um sie zu überwinden.

VM-Tipps

Nachdem die VM gestartet ist, klicken Sie in der oberen linken Ecke, um zur Registerkarte Notebook zu wechseln und Jupyter Notebook für die Übung zu nutzen.

Manchmal müssen Sie einige Sekunden warten, bis Jupyter Notebook vollständig geladen ist. Die Validierung von Vorgängen kann aufgrund von Einschränkungen in Jupyter Notebook nicht automatisiert werden.

Wenn Sie bei der Lernphase Probleme haben, können Sie Labby gerne fragen. Geben Sie nach der Sitzung Feedback, und wir werden das Problem für Sie prompt beheben.

Datenerzeugung

Wir werden die make_blobs-Funktion aus scikit-learn verwenden, um verschiedene Datensätze mit unterschiedlichen Verteilungen zu erzeugen. Im folgenden Codeblock erzeugen wir vier Datensätze:

  • Ein Gemisch von Gaußschen Blobs
  • Anisotrop verteiltete Blobs
  • Blobs mit ungleichem Varianz
  • Blobs unterschiedlicher Größe
import numpy as np
from sklearn.datasets import make_blobs

n_samples = 1500
random_state = 170
transformation = [[0.60834549, -0.63667341], [-0.40887718, 0.85253229]]

X, y = make_blobs(n_samples=n_samples, random_state=random_state)
X_aniso = np.dot(X, transformation)  ## Anisotropic blobs
X_varied, y_varied = make_blobs(
    n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state
)  ## Unequal variance
X_filtered = np.vstack(
    (X[y == 0][:500], X[y == 1][:100], X[y == 2][:10])
)  ## Unevenly sized blobs
y_filtered = [0] * 500 + [1] * 100 + [2] * 10

Visualisiere Daten

Wir werden Matplotlib verwenden, um die erzeugten Datensätze zu visualisieren. Im folgenden Codeblock erstellen wir ein 2x2-Diagramm, das die wahren Cluster für jeden Datensatz zeigt.

import matplotlib.pyplot as plt

fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(12, 12))

axs[0, 0].scatter(X[:, 0], X[:, 1], c=y)
axs[0, 0].set_title("Mixture of Gaussian Blobs")

axs[0, 1].scatter(X_aniso[:, 0], X_aniso[:, 1], c=y)
axs[0, 1].set_title("Anisotropically Distributed Blobs")

axs[1, 0].scatter(X_varied[:, 0], X_varied[:, 1], c=y_varied)
axs[1, 0].set_title("Unequal Variance")

axs[1, 1].scatter(X_filtered[:, 0], X_filtered[:, 1], c=y_filtered)
axs[1, 1].set_title("Unevenly Sized Blobs")

plt.suptitle("Ground truth clusters").set_y(0.95)
plt.show()

K-Means-Clustering

Wir werden die KMeans-Klasse aus scikit-learn verwenden, um die Daten zu clustern. Im folgenden Codeblock erstellen wir ein 2x2-Diagramm, das die Cluster zeigt, die durch k-Means für jeden Datensatz erhalten werden.

from sklearn.cluster import KMeans

common_params = {
    "n_init": "auto",
    "random_state": random_state,
}

fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(12, 12))

y_pred = KMeans(n_clusters=2, **common_params).fit_predict(X)
axs[0, 0].scatter(X[:, 0], X[:, 1], c=y_pred)
axs[0, 0].set_title("Non-optimal Number of Clusters")

y_pred = KMeans(n_clusters=3, **common_params).fit_predict(X_aniso)
axs[0, 1].scatter(X_aniso[:, 0], X_aniso[:, 1], c=y_pred)
axs[0, 1].set_title("Anisotropically Distributed Blobs")

y_pred = KMeans(n_clusters=3, **common_params).fit_predict(X_varied)
axs[1, 0].scatter(X_varied[:, 0], X_varied[:, 1], c=y_pred)
axs[1, 0].set_title("Unequal Variance")

y_pred = KMeans(n_clusters=3, **common_params).fit_predict(X_filtered)
axs[1, 1].scatter(X_filtered[:, 0], X_filtered[:, 1], c=y_pred)
axs[1, 1].set_title("Unevenly Sized Blobs")

plt.suptitle("Unexpected KMeans clusters").set_y(0.95)
plt.show()

Mögliche Lösungen

Wir werden einige mögliche Lösungen für die Einschränkungen des k-Means-Clusterings diskutieren. Im folgenden Codeblock zeigen wir, wie man die richtige Anzahl von Clustern für den ersten Datensatz findet und wie man mit ungleichmäßig großen Blobs umgeht, indem man die Anzahl der zufälligen Initialisierungen erhöht.

y_pred = KMeans(n_clusters=3, **common_params).fit_predict(X)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.title("Optimal Number of Clusters")
plt.show()

y_pred = KMeans(n_clusters=3, n_init=10, random_state=random_state).fit_predict(
    X_filtered
)
plt.scatter(X_filtered[:, 0], X_filtered[:, 1], c=y_pred)
plt.title("Unevenly Sized Blobs \nwith several initializations")
plt.show()

Gauß'sches Mischmodell

Wir werden die Verwendung des Gauß'schen Mischmodells untersuchen, das anisotrope und ungleiche Varianzverteilungen behandeln kann. Im folgenden Codeblock verwenden wir GaussianMixture, um die zweiten und dritten Datensätze zu clustern.

from sklearn.mixture import GaussianMixture

fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(12, 6))

y_pred = GaussianMixture(n_components=3).fit_predict(X_aniso)
ax1.scatter(X_aniso[:, 0], X_aniso[:, 1], c=y_pred)
ax1.set_title("Anisotropically Distributed Blobs")

y_pred = GaussianMixture(n_components=3).fit_predict(X_varied)
ax2.scatter(X_varied[:, 0], X_varied[:, 1], c=y_pred)
ax2.set_title("Unequal Variance")

plt.suptitle("Gaussian mixture clusters").set_y(0.95)
plt.show()

Zusammenfassung

In diesem Lab haben wir den k-Means-Clustering-Algorithmus und seine Annahmen untersucht. Wir haben verschiedene Datensätze mit unterschiedlichen Verteilungen erzeugt und visualisiert, wie k-Means diese Daten in Cluster aufteilt. Wir haben auch einige der Einschränkungen des Algorithmus diskutiert und mögliche Lösungen, um sie zu überwinden, darunter das Finden der richtigen Anzahl von Clustern, die Erhöhung der Anzahl der zufälligen Initialisierungen und die Verwendung des Gauß'schen Mischmodells.