Introducción
En este laboratorio, usaremos la biblioteca scikit-learn de Python para realizar un agrupamiento jerárquico en algunos conjuntos de datos de muestra. El agrupamiento jerárquico es un método de agrupamiento en el que se construye una jerarquía de clusters, ya sea de forma top-down o bottom-up. El objetivo del agrupamiento jerárquico es encontrar clusters de puntos que se parezcan entre sí y sean diferentes de los puntos de otros clusters.
Consejos sobre la VM
Una vez que se haya iniciado 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 sus comentarios después de la sesión y lo resolveremos rápidamente para usted.
Importar bibliotecas y cargar datos
Comenzaremos importando las bibliotecas necesarias y cargando los conjuntos de datos de muestra que usaremos para nuestros ejemplos de agrupamiento jerárquico.
import time
import warnings
import numpy as np
import matplotlib.pyplot as plt
from sklearn import cluster, datasets
from sklearn.preprocessing import StandardScaler
from itertools import cycle, islice
np.random.seed(0)
## %%
## Generar conjuntos de datos. Elegimos un tamaño lo suficientemente grande
## para ver la escalabilidad de los algoritmos, pero no demasiado grande
## para evitar tiempos de ejecución demasiado largos
n_samples = 1500
noisy_circles = datasets.make_circles(n_samples=n_samples, factor=0.5, noise=0.05)
noisy_moons = datasets.make_moons(n_samples=n_samples, noise=0.05)
blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)
no_structure = np.random.rand(n_samples, 2), None
## Datos distribuidos anisotrópicamente
random_state = 170
X, y = datasets.make_blobs(n_samples=n_samples, random_state=random_state)
transformation = [[0.6, -0.6], [-0.4, 0.8]]
X_aniso = np.dot(X, transformation)
aniso = (X_aniso, y)
## Blobs con varianzas variadas
varied = datasets.make_blobs(
n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state
)
Realizar agrupamiento jerárquico
Ahora realizaremos el agrupamiento jerárquico en los conjuntos de datos de muestra que cargamos en el paso 1. Usaremos diferentes métodos de enlace, como single, average, complete y ward, para construir nuestros clusters.
## Establecer parámetros del cluster
plt.figure(figsize=(9 * 1.3 + 2, 14.5))
plt.subplots_adjust(
left=0.02, right=0.98, bottom=0.001, top=0.96, wspace=0.05, hspace=0.01
)
plot_num = 1
default_base = {"n_neighbors": 10, "n_clusters": 3}
datasets = [
(noisy_circles, {"n_clusters": 2}),
(noisy_moons, {"n_clusters": 2}),
(varied, {"n_neighbors": 2}),
(aniso, {"n_neighbors": 2}),
(blobs, {}),
(no_structure, {}),
]
for i_dataset, (dataset, algo_params) in enumerate(datasets):
## actualizar parámetros con valores específicos del conjunto de datos
params = default_base.copy()
params.update(algo_params)
X, y = dataset
## normalizar el conjunto de datos para una selección de parámetros más fácil
X = StandardScaler().fit_transform(X)
## ============
## Crear objetos de cluster
## ============
ward = cluster.AgglomerativeClustering(
n_clusters=params["n_clusters"], linkage="ward"
)
complete = cluster.AgglomerativeClustering(
n_clusters=params["n_clusters"], linkage="complete"
)
average = cluster.AgglomerativeClustering(
n_clusters=params["n_clusters"], linkage="average"
)
single = cluster.AgglomerativeClustering(
n_clusters=params["n_clusters"], linkage="single"
)
clustering_algorithms = (
("Single Linkage", single),
("Average Linkage", average),
("Complete Linkage", complete),
("Ward Linkage", ward),
)
for name, algorithm in clustering_algorithms:
t0 = time.time()
## capturar advertencias relacionadas con kneighbors_graph
with warnings.catch_warnings():
warnings.filterwarnings(
"ignore",
message="the number of connected components of the "
+ "connectivity matrix is [0-9]{1,2}"
+ " > 1. Completing it to avoid stopping the tree early.",
category=UserWarning,
)
algorithm.fit(X)
t1 = time.time()
if hasattr(algorithm, "labels_"):
y_pred = algorithm.labels_.astype(int)
else:
y_pred = algorithm.predict(X)
plt.subplot(len(datasets), len(clustering_algorithms), plot_num)
if i_dataset == 0:
plt.title(name, size=18)
colors = np.array(
list(
islice(
cycle(
[
"#377eb8",
"#ff7f00",
"#4daf4a",
"#f781bf",
"#a65628",
"#984ea3",
"#999999",
"#e41a1c",
"#dede00",
]
),
int(max(y_pred) + 1),
)
)
)
plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[y_pred])
plt.xlim(-2.5, 2.5)
plt.ylim(-2.5, 2.5)
plt.xticks(())
plt.yticks(())
plt.text(
0.99,
0.01,
("%.2fs" % (t1 - t0)).lstrip("0"),
transform=plt.gca().transAxes,
size=15,
horizontalalignment="right",
)
plot_num += 1
plt.show()
Analizar los resultados
Ahora analizaremos los resultados de nuestro agrupamiento jerárquico. Basados en los conjuntos de datos de muestra que usamos, podemos hacer las siguientes observaciones:
- El enlace simple es rápido y puede funcionar bien con datos no globulares, pero funciona mal en presencia de ruido.
- El enlace promedio y el enlace completo funcionan bien con clusters globulares claramente separados, pero tienen resultados mixtos en caso contrario.
- Ward es el método más efectivo para datos ruidosos.
Es importante destacar que aunque estas observaciones nos dan alguna intuición sobre los algoritmos, esta intuición puede no aplicarse a datos de dimensión muy alta.
Resumen
En este laboratorio, aprendimos cómo realizar un agrupamiento jerárquico utilizando la biblioteca scikit-learn de Python. Usamos diferentes métodos de enlace, como single, average, complete y ward, para construir nuestros clusters y analizamos los resultados basados en algunos conjuntos de datos de muestra. El agrupamiento jerárquico es una técnica poderosa que se puede utilizar para identificar clusters de puntos de datos similares y puede ser útil en una variedad de campos, como biología, marketing y finanzas.