Explorando los supuestos del agrupamiento k - means

Beginner

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

Introducción

En este laboratorio, exploraremos el algoritmo de agrupamiento k-means y sus supuestos. Generaremos datos con diferentes distribuciones y visualizaremos cómo k-means particiona estos datos en clusters. También discutiremos algunas de las limitaciones del algoritmo y posibles soluciones para superarlas.

Consejos sobre la VM

Una vez que se haya completado la inicialización de la VM, haga clic en la esquina superior izquierda para cambiar a la pestaña Cuaderno y acceder a Jupyter Notebook para practicar.

A veces, es posible que tenga que esperar unos segundos a que Jupyter Notebook termine de cargarse. La validación de las operaciones no se puede automatizar debido a las limitaciones de Jupyter Notebook.

Si tiene problemas durante el aprendizaje, no dude en preguntar a Labby. Deje comentarios después de la sesión y lo resolveremos rápidamente para usted.

Generación de datos

Utilizaremos la función make_blobs de scikit-learn para generar diferentes conjuntos de datos con distribuciones variables. En el siguiente bloque de código, generamos cuatro conjuntos de datos:

  • Una mezcla de cúmulos gaussianos
  • Cúmulos con distribución anisotrópica
  • Cúmulos con varianza desigual
  • Cúmulos de tamaños desiguales
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)  ## Cúmulos anisotrópicos
X_varied, y_varied = make_blobs(
    n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state
)  ## Varianza desigual
X_filtered = np.vstack(
    (X[y == 0][:500], X[y == 1][:100], X[y == 2][:10])
)  ## Cúmulos de tamaños desiguales
y_filtered = [0] * 500 + [1] * 100 + [2] * 10

Visualizar datos

Utilizaremos Matplotlib para visualizar los conjuntos de datos generados. En el siguiente bloque de código, creamos una gráfica de 2x2 que muestra los clusters de verdad básica para cada conjunto de datos.

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()

Agrupamiento k - means

Utilizaremos la clase KMeans de scikit - learn para agrupar los datos. En el siguiente bloque de código, creamos una gráfica de 2x2 que muestra los clusters obtenidos por k - means para cada conjunto de datos.

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()

Posibles soluciones

Discutiremos algunas posibles soluciones a las limitaciones del agrupamiento k - means. En el siguiente bloque de código, mostramos cómo encontrar el número correcto de clusters para el primer conjunto de datos y cómo lidiar con cúmulos de tamaños desiguales aumentando el número de inicializaciones aleatorias.

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()

Modelo de mezcla gaussiana

Exploraremos el uso del Modelo de Mezcla Gaussiana, que puede manejar distribuciones anisotrópicas y con varianza desigual. En el siguiente bloque de código, usamos GaussianMixture para agrupar el segundo y el tercer conjuntos de datos.

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()

Resumen

En este laboratorio, exploramos el algoritmo de agrupamiento k - means y sus supuestos. Generamos diferentes conjuntos de datos con distribuciones variables y visualizamos cómo k - means particiona estos datos en clusters. También discutimos algunas de las limitaciones del algoritmo y posibles soluciones para superarlas, incluyendo encontrar el número correcto de clusters, aumentar el número de inicializaciones aleatorias y usar el Modelo de Mezcla Gaussiana.