Ejemplo K-means

# ── Importaciones ─────────────────────────────────────────────────────
import numpy as np                  # para operaciones numéricas
import matplotlib.pyplot as plt     # para hacer gráficos
from sklearn.cluster import KMeans  # el algoritmo K-Means
from sklearn.datasets import make_blobs  # generador de datos de ejemplo


# ── PASO 1: Crear datos de ejemplo ────────────────────────────────────
#
# make_blobs() genera puntos artificiales agrupados en 'manchas' (blobs).
# Es como inventarse datos ya organizados para practicar.
#
# n_samples  = cuántos puntos queremos generar en total
# centers    = cuántos grupos/manchas queremos que tenga
# cluster_std = qué tan dispersos están los puntos dentro de cada grupo
#               (número pequeño = puntos muy juntos, número grande = dispersos)
# random_state = semilla aleatoria (garantiza que siempre salga igual)
#
X, y_real = make_blobs(
    n_samples=300,    # 300 puntos en total
    centers=4,        # distribuidos en 4 grupos
    cluster_std=0.8,  # puntos bastante juntos en cada grupo
    random_state=42   # para reproducibilidad
)
#
# X tiene forma (300, 2): 300 filas (puntos) y 2 columnas (coordenadas x, y)
# y_real contiene el grupo real de cada punto (solo para comparar después)


# ── PASO 2: Crear el modelo K-Means ───────────────────────────────────
#
# Aquí solo DEFINIMOS el modelo, todavía no lo entrenamos.
# Parámetros importantes:
#
# n_clusters  = el K: cuántos grupos queremos encontrar
#               Elegimos 4 porque sabemos que los datos tienen 4 grupos.
#               En la vida real no sabremos esto y usaremos el Método del Codo.
#
# n_init      = cuántas veces reinicia el algoritmo con centroides distintos.
#               Por defecto prueba 10 inicializaciones y elige la mejor.
#               Más intentos = más fiable, pero más lento.
#
# random_state = semilla para que el resultado sea siempre el mismo.
#
kmeans = KMeans(
    n_clusters=4,
    n_init=10,
    random_state=42
)


# ── PASO 3: Entrenar el modelo ─────────────────────────────────────────
#
# .fit(X) ejecuta el algoritmo K-Means sobre nuestros datos X.
# Internamente hace todos los pasos descritos antes:
# coloca centroides → asigna puntos → recalcula centroides → repite.
#
kmeans.fit(X)


# ── PASO 4: Obtener los resultados ────────────────────────────────────
#
# Después del entrenamiento, el modelo guarda sus resultados en atributos:
#
# .labels_          → array con el número de cluster asignado a cada punto
#                     Ejemplo: [0, 2, 1, 0, 3, 1, 2, ...] (un número por punto)
#
# .cluster_centers_ → array con las coordenadas de los K centroides finales
#                     Tiene forma (K, n_características)
#
# .inertia_         → el valor WCSS final (qué tan compactos son los clusters)
#
etiquetas  = kmeans.labels_
centroides = kmeans.cluster_centers_
inercia    = kmeans.inertia_

print(f'Inercia (WCSS): {inercia:.2f}')
print(f'Centroides encontrados:')
print(centroides)


# ── PASO 5: Visualizar los resultados ─────────────────────────────────
#
# Hacemos un scatter plot (nube de puntos).
# Cada punto se colorea según el cluster al que fue asignado.
# Los centroides se marcan con una X grande en rojo.
#
plt.figure(figsize=(8, 6))

# scatter() dibuja los puntos:
# X[:, 0] = primera columna (coordenada x de todos los puntos)
# X[:, 1] = segunda columna (coordenada y de todos los puntos)
# c=etiquetas → el color de cada punto depende de su cluster
# cmap='viridis' → la paleta de colores a usar
# alpha=0.7 → transparencia (0=invisible, 1=sólido)
plt.scatter(X[:, 0], X[:, 1], c=etiquetas, cmap='viridis', s=50, alpha=0.7)

# Dibujamos los centroides con una X roja más grande:
# centroides[:, 0] = coordenadas x de todos los centroides
# centroides[:, 1] = coordenadas y de todos los centroides
# marker='X' → símbolo de X
# zorder=5   → se dibuja por encima de los puntos
plt.scatter(centroides[:, 0], centroides[:, 1],
            c='red', marker='X', s=200, zorder=5, label='Centroides')

plt.title('K-Means: Resultado del clustering')
plt.xlabel('Característica 1')
plt.ylabel('Característica 2')
plt.legend()
plt.colorbar(label='Número de cluster')
plt.tight_layout()
plt.show()

Publicado por

Juan Pablo Fuentes

Formador de programación y bases de datos