K-means (05-01) te obligó a decidir K antes de ver un solo resultado. El clustering jerárquico invierte el orden: primero construye todas las agrupaciones posibles —desde cada cliente aislado hasta un único grupo con todos— y después tú eliges a qué nivel cortar. El resultado es una estructura en árbol, el dendrograma, que muestra qué clientes se parecen más, en qué orden se fusionan los grupos y a qué "distancia" ocurre cada fusión. En esta lección aprenderás la mecánica aglomerativa paso a paso (con un ejemplo a mano), las medidas de enlace que determinan la forma de los clusters, cómo construir y leer un dendrograma con scipy, cómo aplicar AgglomerativeClustering a los clientes de MercaFresh y comparar sus segmentos con los de K-means, y cuándo el precio computacional del jerárquico merece la pena.
Contenido
- Aglomerativo vs. divisivo
- Medidas de enlace: cómo se mide la distancia entre grupos
- Ejemplo a mano: las primeras fusiones
- El dendrograma: construcción y lectura
- Cortar el árbol: de jerarquía a segmentos
- Clientes MercaFresh con
AgglomerativeClustering - Comparación con los segmentos de K-means
- Ventajas, coste computacional y cuándo preferirlo
Aglomerativo vs. divisivo
Hay dos maneras de construir una jerarquía de grupos:
| Estrategia | Dirección | Idea | Uso en la práctica |
|---|---|---|---|
| Aglomerativa (bottom-up) | De $n$ clusters a 1 | Cada punto empieza solo; en cada paso se fusionan los dos clusters más cercanos | La estándar: es la que implementan scipy y scikit-learn |
| Divisiva (top-down) | De 1 cluster a $n$ | Todos los puntos empiezan juntos; en cada paso se parte el cluster más heterogéneo | Rara: decidir la mejor partición de un grupo es mucho más costoso que la mejor fusión |
Nos centraremos en la aglomerativa. Su algoritmo es de una simplicidad notable:
- Empieza con $n$ clusters de un punto cada uno.
- Calcula la distancia entre todos los pares de clusters.
- Fusiona los dos clusters más cercanos.
- Repite 2-3 hasta que quede un único cluster.
Cada fusión queda registrada con su distancia, y esa secuencia de fusiones es la jerarquía. Sin inicialización aleatoria, sin iterar hasta converger: el resultado es determinista (a igualdad de datos y parámetros, siempre sale lo mismo — a diferencia de K-means y su random_state).
Medidas de enlace: cómo se mide la distancia entre grupos
El paso 2 esconde la única decisión de diseño importante: la distancia entre dos puntos es la euclídea de siempre (04-05), pero ¿qué es la distancia entre dos grupos de puntos? Cada respuesta es una medida de enlace (linkage), y cambia el carácter del clustering:
| Enlace | Distancia entre clusters A y B | Tendencia | Riesgo típico |
|---|---|---|---|
| Single | La mínima entre un punto de A y uno de B | Clusters alargados, en cadena; detecta formas irregulares | Chaining: une grupos distintos a través de un puente de puntos intermedios |
| Complete | La máxima entre un punto de A y uno de B | Clusters compactos y de diámetro similar | Muy sensible a outliers (un punto lejano infla la distancia máxima) |
| Average | La media de todas las distancias punto a punto entre A y B | Compromiso entre single y complete | Menos interpretable geométricamente |
| Ward | El incremento de varianza interna que causaría la fusión | Clusters esféricos y equilibrados, muy parecidos a K-means | Solo tiene sentido con distancia euclídea |
Dos apuntes prácticos:
- Ward es el defecto sensato para segmentación de clientes: minimiza en cada fusión el mismo tipo de criterio (varianza intra-cluster) que K-means minimiza globalmente con la inercia, así que produce grupos comparables y estables.
- Single linkage es el diferente de la familia: donde Ward y complete ven esferas, single sigue cadenas de vecinos y puede recuperar formas serpenteantes. Esa idea de "conectar por proximidad local" reaparecerá, llevada al extremo y bien resuelta, en DBSCAN (05-04).
Como todos los enlaces se apoyan en distancias, la regla de 03-05 sigue vigente: escala las features antes o las unidades decidirán por ti.
Ejemplo a mano: las primeras fusiones
Tomemos 5 clientes de MercaFresh con una sola feature, recencia_dias, y enlace single (el más cómodo de calcular a mano):
Paso 1. Distancias entre pares: AB=2, AC=5, BC=3, DE=5, CD=32, y el resto mayores. La mínima es AB=2 → fusionamos {A,B} a distancia 2.
Paso 2. Distancias con el nuevo cluster (single = mínimo): d({A,B}, C) = min(5, 3) = 3; d({A,B}, D) = 35; DE = 5. La mínima es 3 → fusionamos {A,B,C}.
Paso 3. d({A,B,C}, D) = 32; d({A,B,C}, E) = 37; DE = 5. La mínima es 5 → fusionamos {D,E}.
Paso 4. Solo quedan {A,B,C} y {D,E}: se fusionan a distancia min(32, 37) = 32.
La secuencia completa — (A,B) a 2, (+C) a 3, (D,E) a 5, (todo) a 32 — cuenta la historia entera: hay dos grupos naturales, uno de clientes recientes y otro de fríos, y la enorme distancia de la última fusión (32 frente a 5) es la evidencia. Esa historia es exactamente lo que el dendrograma dibuja.
El dendrograma: construcción y lectura
Un dendrograma es el árbol de fusiones: las hojas son los puntos, cada unión en forma de puente representa una fusión, y la altura del puente es la distancia a la que ocurrió. En scipy:
import numpy as np
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import linkage, dendrogram
X = np.array([[3], [5], [8], [40], [45]]) # el ejemplo a mano
Z = linkage(X, method="single") # matriz de fusiones
dendrogram(Z, labels=["A", "B", "C", "D", "E"])
plt.ylabel("Distancia de fusión")
plt.show()Qué hace cada pieza:
linkage(X, method=...)ejecuta el algoritmo aglomerativo completo y devuelveZ, una matriz con una fila por fusión: qué dos clusters se unieron, a qué distancia y cuántos puntos suma el resultado. Para nuestro ejemplo, sus distancias son exactamente las que calculamos a mano: 2, 3, 5, 32.dendrogram(Z)dibuja el árbol.methodacepta"single","complete","average"y"ward".
Cómo leer un dendrograma (la habilidad importante):
- Puentes bajos = fusiones tempranas = puntos muy similares. A y B son casi el mismo cliente.
- Puentes altos = fusiones forzadas entre grupos que se parecen poco. El salto de 5 a 32 grita "aquí hay dos poblaciones distintas".
- El número de clusters a una altura dada = número de líneas verticales que corta una horizontal trazada a esa altura. A altura 10, nuestra horizontal corta 2 líneas: dos clusters.
flowchart TD
R["Fusión final (dist. 32)"] --- G1["{A, B, C} (dist. 3)"]
R --- G2["{D, E} (dist. 5)"]
G1 --- AB["{A, B} (dist. 2)"]
G1 --- C["C"]
AB --- A["A"]
AB --- B["B"]
G2 --- D["D"]
G2 --- E["E"]
Cortar el árbol: de jerarquía a segmentos
La jerarquía completa es informativa, pero para actuar necesitas una partición concreta: se obtiene cortando el dendrograma a una altura. Criterios habituales:
- Cortar donde el salto de distancias es mayor: justo debajo del puente desproporcionadamente alto. Es el equivalente jerárquico del codo de 05-01.
- Cortar para obtener un K deseado: si negocio quiere 4 segmentos, se baja la horizontal hasta que corte 4 ramas.
- Un mismo árbol admite varios cortes útiles: a gran altura, "activos vs. dormidos" (2 grupos, para un informe ejecutivo); más abajo, 4-5 segmentos operativos (para campañas). Esa multi-escala es algo que K-means no ofrece: cada K exige reentrenar desde cero.
En scipy, fcluster(Z, t=10, criterion="distance") devuelve las etiquetas del corte a altura 10.
Clientes MercaFresh con AgglomerativeClustering
En scikit-learn el estimador es AgglomerativeClustering. Reutilizamos la matriz X_esc de 05-01 (RFM + ratio_inactividad, escaladas con StandardScaler):
from scipy.cluster.hierarchy import linkage, dendrogram
from sklearn.cluster import AgglomerativeClustering
import matplotlib.pyplot as plt
# 1. Dendrograma exploratorio con scipy (sobre datos ESCALADOS)
Z = linkage(X_esc, method="ward")
plt.figure(figsize=(10, 4))
dendrogram(Z, truncate_mode="lastp", p=20) # muestra solo las 20 últimas fusiones
plt.ylabel("Distancia (Ward)")
plt.show()
# 2. Corte en 4 clusters con scikit-learn
agg = AgglomerativeClustering(n_clusters=4, linkage="ward")
rfm["segmento_jer"] = agg.fit_predict(X_esc)
print(rfm["segmento_jer"].value_counts())Explicación para principiantes:
- Con cientos de clientes, un dendrograma completo es una maraña de hojas ilegible;
truncate_mode="lastp", p=20dibuja solo las 20 fusiones finales, que son las que informan la decisión de corte. Buscamos el tramo donde los puentes pegan el estirón: si el salto grande ocurre al pasar de 4 a 3 ramas, 4 clusters es un corte natural. AgglomerativeClusteringpide on_clusters(corta el árbol por ti) odistance_threshold(corta a una altura, dejando K libre).linkage="ward"es el defecto y nuestro consejo para este caso.- No hay
random_state: el jerárquico es determinista. - Un detalle honesto: aunque el dendrograma permite no fijar K a priori, al final del día cortas en algún sitio — la diferencia es que decides viendo toda la estructura, no a ciegas probando Ks.
Comparación con los segmentos de K-means
¿Coinciden los 4 segmentos jerárquicos con los 4 de K-means de 05-01? Podemos cruzarlos con una tabla de contingencia (pd.crosstab, que ya usaste en 03-04):
import pandas as pd
print(pd.crosstab(rfm["segmento"], rfm["segmento_jer"],
rownames=["K-means"], colnames=["Jerárquico"]))Un resultado típico:
| K-means \ Jerárquico | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
| 0 (VIP) | 171 | 9 | 0 | 0 |
| 1 (Habituales) | 6 | 385 | 0 | 19 |
| 2 (Dormidos) | 0 | 0 | 148 | 2 |
| 3 (Ocasionales) | 0 | 31 | 4 | 225 |
La lectura: cada fila concentra su masa en una columna — ambos algoritmos han descubierto esencialmente los mismos cuatro grupos (recuerda que los números de cluster son arbitrarios; lo que importa es la correspondencia). No es casualidad: Ward y K-means optimizan criterios de varianza muy parecidos. Los desacuerdos (los ~70 clientes fuera de la diagonal) son puntos fronterizos entre segmentos — precisamente los que tendrían silhouette cercano a 0 en 05-01. Cuando dos algoritmos distintos coinciden así, la confianza en que los segmentos son estructura real (y no un artefacto del método) sube mucho; si discreparan por completo, tocaría sospechar de una estructura débil.
Ventajas, coste computacional y cuándo preferirlo
| Aspecto | Clustering jerárquico | K-means |
|---|---|---|
| K a priori | No: se decide viendo el dendrograma | Sí, antes de ejecutar |
| Resultado | Jerarquía completa multi-escala | Una partición para ese K |
| Determinismo | Total | Depende de la inicialización (n_init mitiga) |
| Formas de cluster | Según enlace (single permite formas alargadas) | Esféricas |
| Coste | $O(n^2)$ memoria, $O(n^2)$–$O(n^3)$ tiempo | $O(n \cdot K \cdot i)$: casi lineal |
| Escala práctica | Miles de puntos | Millones de puntos |
El coste merece detenerse: el paso 2 del algoritmo necesita la matriz de distancias entre todos los pares de puntos — con $n$ clientes son del orden de $n^2/2$ distancias. Con los ~1.000 clientes de MercaFresh, medio millón de distancias: instantáneo. Con 10 millones de clientes de una gran cadena, $5 \times 10^{13}$ pares: sencillamente inviable, mientras K-means seguiría funcionando.
Cuándo preferir el jerárquico:
- Dataset pequeño o mediano (hasta decenas de miles de puntos).
- No tienes ni idea de cuántos grupos hay y quieres ver la estructura antes de decidir.
- La jerarquía en sí tiene valor de negocio: taxonomías de productos (bebidas > refrescos > colas), grupos dentro de grupos, informes a distintos niveles de detalle.
- Quieres un resultado reproducible sin semillas ni inicializaciones.
Cuándo K-means: datasets grandes, K razonablemente claro, o cuando necesitas re-segmentar a menudo y rápido.
Errores Comunes y Consejos
- Ejecutar
linkagesobre datos sin escalar. El mismo pecado capital de 05-01: el dendrograma resultante ordena por la feature de mayor magnitud. Escala siempre antes. - Dibujar el dendrograma completo con miles de puntos. Ilegible y lento. Usa
truncate_mode="lastp"conpentre 15 y 30: las fusiones finales son las que informan el corte. - Usar Ward con distancias no euclídeas. Ward está definido sobre varianzas, que presuponen euclídea. Si necesitas otra distancia (Manhattan, coseno), cambia a average o complete linkage.
- Esperar que single linkage dé grupos compactos. Su especialidad son las cadenas; con datos ruidosos suele producir un mega-cluster y varios puntos sueltos. Para segmentación de clientes, Ward o complete.
- Consejo: valida el corte con el silhouette de 05-01 (
silhouette_score(X_esc, etiquetas)funciona con cualquier clustering, no solo K-means) y compara dos o tres cortes candidatos.
Ejercicios
Ejercicio 1. Repite a mano el ejemplo de la lección (A=3, B=5, C=8, D=40, E=45) pero con enlace complete. Escribe la secuencia de fusiones con sus distancias. ¿Cambia el orden de las fusiones respecto a single? ¿Cambia la estructura final de dos grupos?
Ejercicio 2. Genera el dendrograma Ward de los clientes MercaFresh (o de un dataset sintético con make_blobs(n_samples=200, centers=4, random_state=7), escalado). Localiza visualmente el mayor salto de distancias y decide un número de clusters. Después corta con AgglomerativeClustering a ese K y calcula el silhouette. ¿Coincide tu corte visual con el mejor silhouette entre K=2 y K=6?
Ejercicio 3. Sobre el mismo dataset, compara linkage="ward" y linkage="single" con n_clusters=4: imprime el value_counts() de las etiquetas de cada uno. ¿Qué patrón de tamaños produce cada enlace y por qué?
Soluciones
Ejercicio 1
Con complete (máximo en lugar de mínimo):
- Fusión 1: la mínima distancia entre pares sigue siendo AB=2 → {A,B} a 2.
- Fusión 2: d({A,B}, C) = max(5, 3) = 5; DE = 5. Empate a 5; scipy fusiona el primero que encuentra — digamos {A,B,C} a 5 (con complete, da igual el orden del empate para el resultado final).
- Fusión 3: {D,E} a 5.
- Fusión 4: d({A,B,C}, {D,E}) = max de todas las distancias cruzadas = d(A,E) = 42 → fusión final a 42.
El orden es esencialmente el mismo y la estructura final también ({A,B,C} vs. {D,E}): con grupos tan separados, todos los enlaces coinciden. Las diferencias entre enlaces afloran con datos ambiguos, puentes de puntos intermedios u outliers — no con islas limpias. Nota cómo la fusión final sube de 32 (single, distancia entre los puntos más próximos de ambos grupos) a 42 (complete, los más lejanos).
Ejercicio 2
from sklearn.datasets import make_blobs
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import AgglomerativeClustering
from sklearn.metrics import silhouette_score
from scipy.cluster.hierarchy import linkage, dendrogram
X, _ = make_blobs(n_samples=200, centers=4, random_state=7)
X_esc = StandardScaler().fit_transform(X)
dendrogram(linkage(X_esc, method="ward"), truncate_mode="lastp", p=20)
plt.show()
for k in range(2, 7):
lab = AgglomerativeClustering(n_clusters=k, linkage="ward").fit_predict(X_esc)
print(f"K={k} | silhouette = {silhouette_score(X_esc, lab):.3f}")En el dendrograma, el salto más grande de altura ocurre al pasar de 4 ramas a 3 (los cuatro blobs son reales), y el silhouette máximo aparece también en K=4. Cuando el criterio visual y el numérico coinciden, la decisión está bien fundamentada; si discrepan, suele ser señal de clusters de densidad o tamaño desiguales — merece mirar el scatter.
Ejercicio 3
Ward produce 4 grupos de tamaños comparables (reparte varianza de forma equilibrada). Single suele producir un patrón muy distinto: uno o dos clusters enormes y otros con un puñado de puntos (incluso 1), porque el encadenamiento va anexionando todo lo conectable por vecinos próximos y solo deja fuera los puntos verdaderamente aislados. Ese comportamiento, que aquí parece un defecto, es casi una detección de outliers — una intuición que DBSCAN (05-04) convertirá en virtud con la noción explícita de ruido.
Conclusión
Ya dominas la segunda familia del clustering: el enfoque aglomerativo que fusiona en cada paso los dos grupos más cercanos, las cuatro medidas de enlace y su efecto en la forma de los clusters (Ward como pariente de K-means, single como rastreador de cadenas), el dendrograma como radiografía multi-escala de la estructura y el corte que lo convierte en segmentos. Sobre MercaFresh comprobaste además algo valioso: jerárquico y K-means coinciden en los mismos cuatro segmentos, señal de que la estructura es real. Y conoces el precio: $O(n^2)$ que lo hace inviable a gran escala.
Hasta ahora hemos agrupado a los clientes usando sus 4 features RFM, y las hemos podido imaginar de dos en dos. Pero el dataset final de 03-06 tiene muchas más columnas, y en 04-05 quedó anotada una amenaza: la maldición de la dimensionalidad, que degrada las distancias — el ingrediente básico de todo lo que hemos hecho en este módulo. La siguiente lección ataca ese problema de frente: PCA, la técnica que comprime muchas dimensiones en pocas conservando el máximo de información, y que además nos permitirá por fin dibujar nuestros segmentos.
Curso de Machine Learning
Módulo 1: Introducción al Machine Learning
- ¿Qué es el Machine Learning?
- Historia y evolución del Machine Learning
- Tipos de Machine Learning
- Aplicaciones del Machine Learning
- El flujo de trabajo de un proyecto de Machine Learning
Módulo 2: Fundamentos de Estadística y Probabilidad
- Conceptos básicos de estadística
- Distribuciones de probabilidad
- Correlación y covarianza
- Inferencia estadística
- Teorema de Bayes
Módulo 3: Preprocesamiento de Datos
- Limpieza de datos
- Manejo de datos faltantes
- Transformación de datos
- Codificación de variables categóricas
- Normalización y estandarización
- Ingeniería de características
Módulo 4: Algoritmos de Machine Learning Supervisado
- Regresión lineal
- Regresión logística
- Árboles de decisión
- Máquinas de soporte vectorial (SVM)
- K-Vecinos más cercanos (K-NN)
- Naive Bayes
- Redes neuronales
Módulo 5: Algoritmos de Machine Learning No Supervisado
- Clustering: K-means
- Clustering jerárquico
- Análisis de componentes principales (PCA)
- Análisis de agrupamiento DBSCAN
- Visualización de datos con t-SNE y UMAP
Módulo 6: Evaluación y Validación de Modelos
- División de datos: entrenamiento, validación y prueba
- Métricas de evaluación
- Validación cruzada
- Curva ROC y AUC
- Overfitting y underfitting
Módulo 7: Técnicas Avanzadas y Optimización
- Regularización: Ridge, Lasso y Elastic Net
- Ensemble Learning
- Gradient Boosting
- Redes neuronales profundas (Deep Learning)
- Optimización de hiperparámetros
Módulo 8: Implementación y Despliegue de Modelos
- Frameworks y bibliotecas populares
- Implementación de modelos en producción
- Mantenimiento y monitoreo de modelos
- Consideraciones éticas y de privacidad
Módulo 9: Proyectos Prácticos
- Proyecto 1: Predicción de precios de viviendas
- Proyecto 2: Clasificación de imágenes
- Proyecto 3: Análisis de sentimientos en redes sociales
- Proyecto 4: Detección de fraudes
- Proyecto 5: Segmentación de clientes
