Saltar al contenido

Archivos de categoría Clustering

Agrupación en clúster jerárquica en Python

Clustering Jerárquico – Aglomerativo

Vamos a ver la técnica de Clustering Jerárquico Aglomerativo. Es un enfoque de abajo hacia arriba (bottom up). Este enfonque es más popular que el Clustering Divisivo. También vamos a utilizar el enlace completo como Criterio de Enlaces. También se podría usar Enlaces Promedio.

Primero, importemos las librerías necesarias:

import numpy as np 
import pandas as pd
from scipy import ndimage 
from scipy.cluster import hierarchy 
from scipy.spatial import distance_matrix 
from matplotlib import pyplot as plt 
from sklearn import manifold, datasets 
from sklearn.cluster import AgglomerativeClustering 
from sklearn.datasets.samples_generator import make_blobs 
%matplotlib inline

Generando los Datos Aleatorios

Vamos a generar un conjunto de datos usando la clase make_blobs. Para ello usamos los siguientes parámetros:

  • n_samples: Total de puntos divididos equitativamente entre los clusters. Elegimos un número entre 10-1500
  • centers: El número de centros para generar, o las ubicaciones de centro fijas. Elegimos arrays de coordenadas x, y para generar los centros.
  • cluster_std: El desvío estándar de los clusters. Mientras más grande el número, más separados estarán los clusters. Elegimos un número entre 0.5-1.5

Guarda el resultado en X1 y en y1.

X1, y1 = make_blobs(n_samples=50, centers=[[4,4], [-2, -1], [1, 1], [10,4]], cluster_std=0.9)

Dibujo de la distribución de los puntos de los datos generados al azar

plt.scatter(X1[:, 0], X1[:, 1], marker='o') 
<matplotlib.collections.PathCollection at 0x7f9669b85dd8>

Clustering Aglomerativo

Comenzaremos haciendo el clustering de los datos aleatorios de los puntos que hemos creado.
La clase de Clustering Aglomerativo necesita dos entradas:

  • n_clusters: El número de clusters a formar y el número de centroides a generar. Pondremos 4
  • linkage: Criterio de Enlace a utilizar. El criterio de enlace determina la distancia a usar entre varias observaciones. El algoritmos agrupará en pares los clusters que minimizarán este criterio. El valor que vamos a utilizar es ‘complete’ (Se recomienda también intentar todo con ‘average’)

Guardamos el resultado en una variable llamada agglom

agglom = AgglomerativeClustering(n_clusters = 4, linkage = 'average')

Ajustamos el modelo con X2 y y2 a partir de los datos generados anteriormente.

agglom.fit(X1,y1)
AgglomerativeClustering(affinity='euclidean', compute_full_tree='auto',
            connectivity=None, linkage='average', memory=None,
            n_clusters=4, pooling_func='deprecated')

El siguiente código muestra el clustering.

# Crear una figura de 6 pulgadas (aprox 15cm) por 4 pulgadas (aprox 10 cm).
plt.figure(figsize=(6,4))

# Estas dos líneas de código se usan para reducir los puntos de datos,
# porque sino los puntos de datos se verían muy separados y dispersos.

# Crear un rango mínimo y máximo de X1.
x_min, x_max = np.min(X1, axis=0), np.max(X1, axis=0)

# Obtener la distancia promedio para X1.
X1 = (X1 - x_min) / (x_max - x_min)

# Este loop muestra todos los puntos de datos.
for i in range(X1.shape[0]):
    # Reemplaza los puntos de datos con su valor de cluster respectivo 
    # (ej. 0) está codificado con un mapa de colores (plt.cm.spectral)
    plt.text(X1[i, 0], X1[i, 1], str(y1[i]),
             color=plt.cm.nipy_spectral(agglom.labels_[i] / 10.),
             fontdict={'weight': 'bold', 'size': 9})

# Elimina los ticks x, ticks y, y los ejes x e y
plt.xticks([])
plt.yticks([])
#plt.axis('off')

# Muestra el punteado de los datos originales ántes de clustering
plt.scatter(X1[:, 0], X1[:, 1], marker='.')
# Muestra el punteo
plt.show()

Dendograma Asociado al Clustering Aglomerativo Jerárquico

Recuerda que una matriz de distancia contiene la distancia de cada punto hacia cualquier otro punto del set de datos. Usamos la función distance_matrix, la cual necesita dos entradas. Usamos la Matriz de Confusión, X2 como ambas entradas para guardar la matriz de distancia en una variable de nombre dist_matrix. Recuerda que los valores de distancia son simétricos, con una diagonal de ceros. Esta es una forma de asegurarse que tu matriz es correcta. Imprimimos dist_matrix para asegurarnos que es correcta:

dist_matrix = distance_matrix(X1,X1) 
print(dist_matrix)
[[0.         0.768101   0.99584945 ... 0.3722758  1.09321893 0.97574908]
 [0.768101   0.         0.243825   ... 0.63657093 0.34126614 0.24149435]
 [0.99584945 0.243825   0.         ... 0.87975678 0.09840829 0.04685827]
 ...
 [0.3722758  0.63657093 0.87975678 ... 0.         0.97587667 0.87704455]
 [1.09321893 0.34126614 0.09840829 ... 0.97587667 0.         0.1212985 ]
 [0.97574908 0.24149435 0.04685827 ... 0.87704455 0.1212985  0.        ]]

Usando la clase de enlace de la jerarquía, pasamos los parámetros:

  • La matriz de distancia
  • ‘complete’ se refiere al enlace completo

Guardamos el resultado en una variable de nombre Z

Z = hierarchy.linkage(dist_matrix, 'complete')

Un clustering jerárquico se visualiza como un dendograma. Cada agrupamiento se representa por una linea horizontal. La coordenada y de la linea horizontal se refiere a la similitud entre dos clusters que se agruparon, donde las observaciones se visualizan como clusters individuales. Moviéndose para arriba desde la capa inferior hacia el nodo superior, un dendograma nos permite reconstruir la historia de agrupamientos que resultaron en el clustering representado.
Guardamos el dendograma en una variable llamada dendro. Al hacer esto, el dendograma también se dibujará. Utilizando la clase dendrograma de la jerarquía, se pasa en el parámetro Z

Z = hierarchy.linkage(dist_matrix, 'complete')

Si usamos el enlace promedio podemos ver cómo el dendograma cambia.

Z = hierarchy.linkage(dist_matrix, 'average')
dendro = hierarchy.dendrogram(Z)

Ejmplo con datos de Vehículos

Imaginemos que una fábrica de vehículos desarrolla prototipos para un nuevo vehículo. Antes de presentar el nuevo modelo, el fabracante quiere saber que vehículos existen en el mercado similares al prototipo, es decir, cómo se pueden agrupar los vehículos, qué grupo es el más parecido al del modelo y de esta forma, qué modelos competirán con el nuevo.
Nuestro objetivo es utilizar métodos de clustering para encontrar los clusters más diferentes de vehículos. Se resumirán los vehículos actuales y ayudará al proceso de fabricación para tomar mejores decisiones para hacer modelos más simples.

Descargar los datos

Para descargar los datos, usaremos !wget

!wget -O cars_clus.csv https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/ML0101ENv3/labs/cars_clus.csv
--2020-02-21 17:21:39--  https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/ML0101ENv3/labs/cars_clus.csv
Resolving s3-api.us-geo.objectstorage.softlayer.net (s3-api.us-geo.objectstorage.softlayer.net)... 67.228.254.196
Connecting to s3-api.us-geo.objectstorage.softlayer.net (s3-api.us-geo.objectstorage.softlayer.net)|67.228.254.196|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 17774 (17K)

Saving to: ‘cars_clus.csv’

cars_clus.csv 100%[===================>] 17.36K –.-KB/s in 0.02s

2020-02-21 17:21:40 (833 KB/s) – ‘cars_clus.csv’ saved [17774/17774]

Veamos las características de los fabricantes que se han secopilado sobre los modelos existentes.

filename = 'cars_clus.csv'

#Read csv
pdf = pd.read_csv(filename)
print ("Forma del set de datos: ", pdf.shape)

pdf.head(5)
Forma del set de datos:  (159, 16)
manufact model sales resale type price engine_s horsepow wheelbas width length curb_wgt fuel_cap mpg lnsales partition
0 Acura Integra 16.919 16.360 0.000 21.500 1.800 140.000 101.200 67.300 172.400 2.639 13.200 28.000 2.828 0.0
1 Acura TL 39.384 19.875 0.000 28.400 3.200 225.000 108.100 70.300 192.900 3.517 17.200 25.000 3.673 0.0
2 Acura CL 14.114 18.225 0.000  

null

3.200 225.000 106.900 70.600 192.000 3.470 17.200 26.000 2.647 0.0
3 Acura RL 8.588 29.725 0.000 42.000 3.500 210.000 114.600 71.400 196.600 3.850 18.000 22.000 2.150 0.0
4 Audi A4 20.397 22.255 0.000 23.990 1.800 150.000 102.600 68.200 178.000 2.998 16.400 27.000 3.015 0.0

Los conjuntos de datos incluyen el precio en miles (price), tamaño de motor (engine_s), caballos de fuerza (horsepow), distancia entre ejes (wheelbas), ancho (width), largo (length), peso en vació (curb_wgt), capacidad de combustible (fuel_cap) y eficiencia de combustible (mpg).

Limpieza de Datos

Limpiemos el set de datos eliminando filas que tienen valores nulos:

print ("Shape of dataset before cleaning: ", pdf.size)
pdf[[ 'sales', 'resale', 'type', 'price', 'engine_s',
       'horsepow', 'wheelbas', 'width', 'length', 'curb_wgt', 'fuel_cap',
       'mpg', 'lnsales']] = pdf[['sales', 'resale', 'type', 'price', 'engine_s',
       'horsepow', 'wheelbas', 'width', 'length', 'curb_wgt', 'fuel_cap',
       'mpg', 'lnsales']].apply(pd.to_numeric, errors='coerce')
pdf = pdf.dropna()
pdf = pdf.reset_index(drop=True)
print ("Forma del dataset luego de la limpieza: ", pdf.size)
pdf.head(5)
Shape of dataset before cleaning:  2544
Forma del dataset luego de la limpieza:  1872
manufact model sales resale type price engine_s horsepow wheelbas width length curb_wgt fuel_cap mpg lnsales partition
0 Acura Integra 16.919 16.360 0.0 21.50 1.8 140.0 101.2 67.3 172.4 2.639 13.2 28.0 2.828 0.0
1 Acura TL 39.384 19.875 0.0 28.40 3.2 225.0 108.1 70.3 192.9 3.517 17.2 25.0 3.673 0.0
2 Acura RL 8.588 29.725 0.0 42.00 3.5 210.0 114.6 71.4 196.6 3.850 18.0 22.0 2.150 0.0
3 Audi A4 20.397 22.255 0.0 23.99 1.8 150.0 102.6 68.2 178.0 2.998 16.4 27.0 3.015 0.0
4 Audi A6 18.780 23.555 0.0 33.95 2.8 200.0 108.7 76.1 192.0 3.561 18.5 22.0 2.933 0.0

Selección de Característica

Elijamos nuestro set en cuestión:

featureset = pdf[['engine_s',  'horsepow', 'wheelbas', 'width', 'length', 'curb_wgt', 'fuel_cap', 'mpg']]

Normalización

Ahora podemos normalizar el set. MinMaxScaler transforma poniendo en escala a un rango. Por omisión es (0, 1). Es decir, las escalas dee estimación se traducen cada una individualmente de forma tal de quedar entre cero y uno.

from sklearn.preprocessing import MinMaxScaler
x = featureset.values #returns a numpy array
min_max_scaler = MinMaxScaler()
feature_mtx = min_max_scaler.fit_transform(x)
feature_mtx [0:5]
array([[0.11428571, 0.21518987, 0.18655098, 0.28143713, 0.30625832,
        0.2310559 , 0.13364055, 0.43333333],
       [0.31428571, 0.43037975, 0.3362256 , 0.46107784, 0.5792277 ,
        0.50372671, 0.31797235, 0.33333333],
       [0.35714286, 0.39240506, 0.47722343, 0.52694611, 0.62849534,
        0.60714286, 0.35483871, 0.23333333],
       [0.11428571, 0.24050633, 0.21691974, 0.33532934, 0.38082557,
        0.34254658, 0.28110599, 0.4       ],
       [0.25714286, 0.36708861, 0.34924078, 0.80838323, 0.56724368,
        0.5173913 , 0.37788018, 0.23333333]])

Agrupando utilizando Scipy

En esta parte, usaremos el paquete Scipy para agrupar el set de datos. Primero, calcularemos la matriz de distancia.

import scipy
leng = feature_mtx.shape[0]
D = scipy.zeros([leng,leng])
for i in range(leng):
    for j in range(leng):
        D[i,j] = scipy.spatial.distance.euclidean(feature_mtx[i], feature_mtx[j])

En el clustering aglomerativo, en cada iteración, el algoritmo debe actualizar la matriz para refrejar la distancia del nuevo cluster formado a partir de los clusters restantes. Los métodos siguientes los soporta Scipy para calcular la distancia entre los recientementes formados clusters y para cada: – simple – completo – promedio – ponderado – centroide
Usaremos completo para nuestro caso, pero si deseas puedes cambiar para ver los diferentes resultados.

import pylab
import scipy.cluster.hierarchy
Z = hierarchy.linkage(D, 'complete')

Esencencialmente, el clustering jerárquico no necesita de un número específico de clusters. Sin embargo, algunas aplicaciones que queremos una partición de clusters disjuntos como si fueran clustering tradicional. Por lo tanto podrás usar una linea en el medio:

from scipy.cluster.hierarchy import fcluster
max_d = 3
clusters = fcluster(Z, max_d, criterion='distance')
clusters
array([ 1,  5,  5,  6,  5,  4,  6,  5,  5,  5,  5,  5,  4,  4,  5,  1,  6,
        5,  5,  5,  4,  2, 11,  6,  6,  5,  6,  5,  1,  6,  6, 10,  9,  8,
        9,  3,  5,  1,  7,  6,  5,  3,  5,  3,  8,  7,  9,  2,  6,  6,  5,
        4,  2,  1,  6,  5,  2,  7,  5,  5,  5,  4,  4,  3,  2,  6,  6,  5,
        7,  4,  7,  6,  6,  5,  3,  5,  5,  6,  5,  4,  4,  1,  6,  5,  5,
        5,  6,  4,  5,  4,  1,  6,  5,  6,  6,  5,  5,  5,  7,  7,  7,  2,
        2,  1,  2,  6,  5,  1,  1,  1,  7,  8,  1,  1,  6,  1,  1],
      dtype=int32)

También, podrás determinar la cantidad de clusters directamente:

from scipy.cluster.hierarchy import fcluster
k = 5
clusters = fcluster(Z, k, criterion='maxclust')
clusters
array([1, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 2, 2, 3, 1, 3, 3, 3, 3, 2, 1,
       5, 3, 3, 3, 3, 3, 1, 3, 3, 4, 4, 4, 4, 2, 3, 1, 3, 3, 3, 2, 3, 2,
       4, 3, 4, 1, 3, 3, 3, 2, 1, 1, 3, 3, 1, 3, 3, 3, 3, 2, 2, 2, 1, 3,
       3, 3, 3, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 2, 1, 3, 3, 3, 3, 3, 2,
       3, 2, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1,
       3, 4, 1, 1, 3, 1, 1], dtype=int32)

Ahora, se trazará el dendograma:

fig = pylab.figure(figsize=(18,50))
def llf(id):
    return '[%s %s %s]' % (pdf['manufact'][id], pdf['model'][id], int(float(pdf['type'][id])) )

dendro = hierarchy.dendrogram(Z,  leaf_label_func=llf, leaf_rotation=0, leaf_font_size =12, orientation = 'right')

Clustering utilizando scikit-learn

Volvamos a construir el cluster, pero esta vez usando el paquete scikit-learn:

dist_matrix = distance_matrix(feature_mtx,feature_mtx) 
print(dist_matrix)
[[0.         0.57777143 0.75455727 ... 0.28530295 0.24917241 0.18879995]
 [0.57777143 0.         0.22798938 ... 0.36087756 0.66346677 0.62201282]
 [0.75455727 0.22798938 0.         ... 0.51727787 0.81786095 0.77930119]
 ...
 [0.28530295 0.36087756 0.51727787 ... 0.         0.41797928 0.35720492]
 [0.24917241 0.66346677 0.81786095 ... 0.41797928 0.         0.15212198]
 [0.18879995 0.62201282 0.77930119 ... 0.35720492 0.15212198 0.        ]]

Ahora, podemos usar la función ‘AgglomerativeClustering’ de la librería scikit-learn para agrupar el set de datos. Esta función hace un clustering jerárquico por medio de un enfoque de abajo hacia arriba (bottom up). El criterio de enlace determina la métrica utilizada para la estrategia de unificación:

  • Ward minimiza la suma de las diferencias cuadráticas dentro de todos los clusters. Es una enfoque minimizado y en este sentido se parece al la función de objetivo de k-medias pero está encarado con un enfoque jerárquico aglomerativo.
  • El Enlace máximo o completo, minimiza la distancia máxima entre las observaciones de pares de clusters.
  • El Enlace promedio minimiza el promedio de las distancias entre todas las observaciones de pares de clusters.
agglom = AgglomerativeClustering(n_clusters = 6, linkage = 'complete')
agglom.fit(feature_mtx)
agglom.labels_
array([1, 2, 2, 1, 2, 3, 1, 2, 2, 2, 2, 2, 3, 3, 2, 1, 1, 2, 2, 2, 5, 1,
       4, 1, 1, 2, 1, 2, 1, 1, 1, 5, 0, 0, 0, 3, 2, 1, 2, 1, 2, 3, 2, 3,
       0, 3, 0, 1, 1, 1, 2, 3, 1, 1, 1, 2, 1, 1, 2, 2, 2, 3, 3, 3, 1, 1,
       1, 2, 1, 2, 2, 1, 1, 2, 3, 2, 3, 1, 2, 3, 5, 1, 1, 2, 3, 2, 1, 3,
       2, 3, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1,
       2, 0, 1, 1, 1, 1, 1])

Podemos agregar un nuevo campo a nuestro marco de datos para mostrar el cluster de cada fila:

pdf['cluster_'] = agglom.labels_
pdf.head()
manufact model sales resale type price engine_s horsepow wheelbas width length curb_wgt fuel_cap mpg lnsales partition cluster_
0 Acura Integra 16.919 16.360 0.0 21.50 1.8 140.0 101.2 67.3 172.4 2.639 13.2 28.0 2.828 0.0 1
1 Acura TL 39.384 19.875 0.0 28.40 3.2 225.0 108.1 70.3 192.9 3.517 17.2 25.0 3.673 0.0 2
2 Acura RL 8.588 29.725 0.0 42.00 3.5 210.0 114.6 71.4 196.6 3.850 18.0 22.0 2.150 0.0 2
3 Audi A4 20.397 22.255 0.0 23.99 1.8 150.0 102.6 68.2 178.0 2.998 16.4 27.0 3.015 0.0 1
4 Audi A6 18.780 23.555 0.0 33.95 2.8 200.0 108.7 76.1 192.0 3.561 18.5 22.0 2.933 0.0 2
import matplotlib.cm as cm
n_clusters = max(agglom.labels_)+1
colors = cm.rainbow(np.linspace(0, 1, n_clusters))
cluster_labels = list(range(0, n_clusters))

# Crear una figura de 6 pulgadas (aprox 15cm) por 4 pulgadas (aprox 10cm).
plt.figure(figsize=(16,14))

for color, label in zip(colors, cluster_labels):
    subset = pdf[pdf.cluster_ == label]
    for i in subset.index:
            plt.text(subset.horsepow[i], subset.mpg[i],str(subset['model'][i]), rotation=25) 
    plt.scatter(subset.horsepow, subset.mpg, s= subset.price*10, c=color, label='cluster'+str(label),alpha=0.5)
#    plt.scatter(subset.horsepow, subset.mpg)
plt.legend()
plt.title('Clusters')
plt.xlabel('horsepow')
plt.ylabel('mpg')
Text(0, 0.5, 'mpg')


Como se puede ver, es una distribución de cada cluster utilizando una trama esparcida, pero no está muy claro dónde es el centroide de cada cluster. Es más, hay 2 tipos de vehículos en nuestro set de datos, «truck» (valor de 1 en la columna tipo) y «car» (valor 1 en la columna tipo). Asi que los usaremos para distinguir las clases y sumarizar el cluster. Primero contamos la cantidad de casos de cada grupo:

pdf.groupby(['cluster_','type'])['cluster_'].count()
cluster_  type
0         1.0      6
1         0.0     47
          1.0      5
2         0.0     27
          1.0     11
3         0.0     10
          1.0      7
4         0.0      1
5         0.0      3
Name: cluster_, dtype: int64

Ahora, podemos examinar a las características de cada cluster:

agg_cars = pdf.groupby(['cluster_','type'])['horsepow','engine_s','mpg','price'].mean()
agg_cars
horsepow engine_s mpg price
cluster_ type
0 1.0 211.666667 4.483333 16.166667 29.024667
1 0.0 146.531915 2.246809 27.021277 20.306128
1.0 145.000000 2.580000 22.200000 17.009200
2 0.0 203.111111 3.303704 24.214815 27.750593
1.0 182.090909 3.345455 20.181818 26.265364
3 0.0 256.500000 4.410000 21.500000 42.870400
1.0 160.571429 3.071429 21.428571 21.527714
4 0.0 55.000000 1.000000 45.000000 9.235000
5 0.0 365.666667 6.233333 19.333333 66.010000

Es obvio que tenemos 3 clusters principales donde están la mayoría de los vehículos en ellos.

  • Coches:
    • Cluster 1: con algo mpg, y poco caballos de fuerza.
    • Cluster 2: con buenos mpg y caballos de fuerza, pero un precio más alto que el promedio.
    • Cluster 3: con bajo mpg, muchos caballos de fuerza y el precio más alto de todos.
  • Camiones:
    • Cluster 1: con el más alto mpg entre los camiones, y lo más bajo en caballos de fuerza y precio.
    • Cluster 2: con bajo mpg y media de caballos de fuerza, pero el precio más alto que el promedio.
    • Cluster 3: con bueno mpg y caballos de fuerza, bajo precio.

Notar que no utilizamos type, y price de autos en el proceso de clustering, sino que utilizamos clustering Jerárquico para discriminar los clusters con una precisión bastante alta.

plt.figure(figsize=(16,10))
for color, label in zip(colors, cluster_labels):
    subset = agg_cars.loc[(label,),]
    for i in subset.index:
        plt.text(subset.loc[i][0]+5, subset.loc[i][2], 'type='+str(int(i)) + ', price='+str(int(subset.loc[i][3]))+'k')
    plt.scatter(subset.horsepow, subset.mpg, s=subset.price*20, c=color, label='cluster'+str(label))
plt.legend()
plt.title('Clusters')
plt.xlabel('horsepow')
plt.ylabel('mpg')
Text(0, 0.5, 'mpg')

0 Seguir leyendo →

Agrupación en clúster jerárquica

Agrupación en clúster jerárquica

Dendograma perrosEn el gráfico adjunto vemos un dendrograma de agrupación en clúster jerárquica para reportar datos genéticos de más de 900 perros de 85 razas y más de 200 lobos grises salvajes de alrededor del mundo, incluyendo poblaciones de norte América, Europa, Oriente Medio y Asia Oriental. Se usaron técnicas para analizar más de 48,000 marcadores genéticos. Este diagrama muestra la agrupación jerárquica de estos animales en función de la similitud en sus datos genéticos.

Los algoritmos de clústeres jerárquicos construyen una jerarquía de clústeres en el que cada nodo es un clúster que consta de los clústeres de sus nodos hijas. Las estrategias para la agrupación jerárquica en general se dividen en dos tipos: Divisivo y Aglomerativo. La división es descendente, por lo que se inicia con todas las observaciones en un clúster grande y se dividen en partes más pequeñas. Imagina divisivo como «dividir» el clúster. El aglomerativo es lo contrario de divisivo, por lo que es de abajo hacia arriba, donde cada observación se inicia en su propio clúster y los pares de clústeres se fusionan a medida que avanzan en la jerarquía. La aglomeración significa manipular o recoger cosas, que es exactamente lo que esto hace con el clúster.

El enfoque aglomerativo es más popular entre los «Data Scientists», por lo que vamos a verlo en esta entrada. Este método construye la jerarquía a partir de los elementos individuales mediante la fusión progresiva de clústeres. Vamos a ver un ejemplo en el que queremos agrupar 6 ciudades en Canadá basados en sus distancias unas de otras. Estos son: Toronto, Ottawa, Vancouver, Montreal, Winnipeg y Edmonton. Construimos una matriz de distancias donde los números de la fila i columna j son la distancia entre las ciudades. El algoritmo se inicia mediante la asignación de cada ciudad a su propio clúster. Así que, como tenemos 6 ciudades, tenemos 6 grupos, cada uno conteniendo sólo una ciudad. El primer paso es determinar qué ciudades (o grupos) se fusionan en un clúster. Para esto se seleccionan los dos clústers más cercanos según la distancia elegida. Mirando la matriz de distancia, Montreal y Ottawa son los clústers más cercanos. Así que, creamos un cluster de ellos. Sólo hemos usado una función de distancia unidimensional, pero nuestro objeto puede ser multidimensional, y la medición de distancia puede ser Euclidiana, Pearson, distancia promedio, o muchas otras, en función del tipo de datos y del conocimiento del dominio.

Dendograma 1Como se puede ver en la matriz de distancia, las filas y las columnas relacionadas con las ciudades de Montreal y Ottawa se fusionan a medida que se construye el clúster. En consecuencia, las distancias de todas las ciudades a este nuevo clúster fusionado se actualizan. Seleccionamos la distancia desde el centro del clúster de Otawa-Montreal hacia Winnipeg. Actualizando la matriz de distancia, ahora tenemos un clúster menos. A continuación, buscamos los clústeres más cercanos una vez más. En este caso, Ottawa-Montreal y Toronto son los más cercanos, lo que crea otro clúster. En el siguiente paso, la distancia más cercana es entre el clúster de Vancouver y el clúster de Edmonton Formando un nuevo clúster, sus datos en la matriz la tabla se actualizan. Esencialmente, las filas y las columnas se fusionan a medida que se fusionan los clústeres y se actualiza la distancia.

Dendograma 2
Dendograma 3
Dendograma 4
Dendograma 5

Esta es una forma común de implementar este tipo de clustering, y tiene el beneficio de almacenar caché de las distancias entre clústeres. De la misma manera, el algoritmo aglomerativo procede luego de una fusión de clústeres. Y lo repetimos hasta que todos los clústeres se fusionen y el árbol se complete, esto es, hasta que todas las ciudades están agrupadas en un solo clúster de tamaño 6. La agrupación jerárquica se visualiza normalmente como un dendrograma tal como se muestra en esta imagen. Cada fusión se representa mediante una línea horizontal. Al subir desde la capa inferior hasta el nodo superior, un dendrograma nos permite reconstruir el historial de fusiones que ha resultado en la agrupación en clústeres representados.

Cálculo de la proximidad

El primer paso es crear n clusteres, uno para cada punto de datos. A continuación, cada punto se asigna como un cluster. Luego claculamos la matriz de distancia/proximidad, que será n por n en la primera tabla. Después ejecutamos de forma iterativa ejecutamos la «unión» de los dos grupos más cercanos y actualizamos la matriz de proximidad con los nuevos valores. Nos detenemos después de que hayamos alcanzado el número especificado de clusteres, o sólo hay un cluster que queda, con el resultado almacenado en un dendrograma. Así que, en la matriz de proximidad, tenemos que medir las distancias entre clusteres, y también fusionar los clusteres que son «más cercanos». Por lo tanto, la operación clave es la computación de la proximidad entre los clusteres con un punto, y también clusteres con varios puntos de datos.

Podemos usar diferentes medidas de distancia para calcular la matriz de proximidad. Por ejemplo, la distancia euclidiana. Así que si tenemos un conjunto de datos de n observaciones, podemos construir una matriz de n por n distancia. Ésta nos dará la distancia de las agrupaciones con 1 punto de datos. Sin embargo, fusionamos los grupos en clustering aglomerativo, por lo que la distancia entre los clusteres se debe calcular con varias observaciones. Para ello podemos utilizar diferentes criterios. En general, depende completamente del tipo de datos, la dimensionalidad de los datos, y lo más importante, el conocimiento de dominio del conjunto de datos. De hecho, diferentes enfoques a la hora de definir la distancia entre clusteres, nos dan diferentes resultados. Podemos ver algunos:

  • Clustering de enlace único. El enlace único se define como la distancia más corta entre 2 puntos en cada cluster.
  • Complete-Linkage Clustering. Esta vez, estamos encontrando la distancia más larga entre los puntos de cada cluster.
  • Clustering promedio de enlaces, o la distancia media. Esto significa que estamos tomando la distancia promedio de cada punto de un cluster a cada uno de los puntos de otro cluster.
  • Clustering de enlaces centroide. Centroide es el promedio de los conjuntos de características de puntos en un cluster. Este enlace tiene en cuenta el centroide de cada cluster al determinar la distancia mínima.

Puedes ver un ejemplo en este artículo: Agrupación en clúster jerárquica en Python

Ventajas y desventajas

Hay 3 ventajas principales para utilizar el clustering jerárquico:

  1. No es necesario especificar el número de clusteres necesarios para el algoritmo.
  2. El clustering jerárquico es fácil de implementar.
  3. El dendrograma producido es muy útil para comprender los datos.

También hay algunas desventajas.

  1. El algoritmo nunca puede deshacer ninguna de los pasos anteriores. Si, por ejemplo, el algoritmo agrupa 2 puntos, y más tarde vemos que la conexión no era buena, el programa no puede deshacer ese paso.
  2. La complejidad del tiempo para el clustering puede dar lugar a tiempos de cálculo muy largos, en comparación con algoritmos eficientes, como K-Means.
  3. Si tenemos un conjunto de datos grande, puede ser difícil determinar el número correcto de clusteres por el dendrograma.

Comparación del clustering jerárquico con la k-Means.

  • Los K-means son más eficientes para los conjuntos de datos grandes.
  • El clustering jerárquico no requiere que se especifique el número de clusteres.
  • El clustering jerárquico da más de un particionamiento en función de la resolución, mientras que k-Means sólo da un solo particionamiento de los datos.
  • El clustering jerárquico siempre genera los mismos clusteres, en contraste con la k-Means que devuelve distintos clusteres cada vez que se ejecuta debido a la inicialización aleatoria de los centroides.

Ir al artículo anterior de la serie: Agrupación por K-medias

Ir al artículo siguiente de la serie:

0 Seguir leyendo →

Agrupación por K-medias

Agrupación por K-medias.

Existen varios tipos de algoritmos de agrupación, tales como agrupaciones basadas en particiones, basadas en jerarquías o basadas en densidades. K-medias es una agrupación basada en particiones, es decir, divide los datos en subconjuntos no solapados (o particiones) sin ninguna estructura interna. Esto significa, que es un algoritmo no supervisado. Los objetos dentro de una partición serán muy similares y los objetos de las distintas particiones serán muy diferentes o disimilares. Como puede verse, para usar K-medias, tenemos que encontrar muestras similares.

k-medias teoriaAunque el objetivo de K-medias es formar particiones de tal manera que muestras similares vayan a una partición y muestras disimilares caígan en diferentes particiones, se puede demostrar que en lugar de una métrica de similitud, podemos utilizar métricas de disimilitud. En otras palabras, la distancia de las muestras entre sí se utiliza para moldear las particiones. Así que, podemos decir que K-medias trata de minimizar las distancias «intra-partición» y maximiza las distancias «inter-partición».

Para calcular la disimulitud o la distancia de dos puntos, podemos utilizar un tipo específico de distancia de Minkowski, la distancia Euclidiana.

Dis(x_1, x_2) = \sqrt{\displaystyle\sum_{i=0}^{n} (x_{1i} - x_{2i})^2}

Por supuesto, tenemos que normalizar nuestro conjunto de características para obtener la medida de disimilitud precisa. También hay otras medidas de disimilitud que pueden ser utilizadas para este propósito, pero dependen en gran medida del tipo de datos y también del dominio para el cual se ha hecho la partición. Por ejemplo, se puede utilizar la distancia euclidiana, la similitud del coseno, la distancia promedio, etc… De hecho, la medida de similitud controla grandemente cómo se forman las particiones, por lo que se recomienda comprender el conocimiento de dominio de tu conjunto de datos y el tipo de datos de las características y después seleccionar la medida de distancia significativa.

Funcionamiento de la agrupación por K-medias

Lo primero es determinar el número de particiones que buscamos. El concepto clave del algoritmo K-medias es que escoge aleatoriamente un punto central para cada partición. Esto significa que tenemos que inicializar ‘k’, la cual representa «el número de particiones». Determinar el número de particiones en un conjunto de datos, o ‘k’, es un problema difícil en K-medias. Por ahora, vamos a proponer que ‘k’ sea igual a 3, así que tendremos 3 puntos representativos para nuestras particiones. Estos 3 puntos de datos se denominan centroides de las particiones, y deben ser del mismo tamaño que la característica de nuestro conjunto de características de cliente. Hay dos enfoques para elegir estos centroides:

  1. Podemos elegir aleatoriamente 3 observaciones fuera del conjunto de datos y utilizar estas observaciones como los medios iniciales.
  2. Podemos crear 3 puntos aleatorios como centroides de las particiones.

 

Después del paso de inicialización, que define el centroide de cada partición, tenemos que asignar cada observación al centroide más cercano. Con este fin, tenemos que calcular la distancia de cada punto de datos de los centroides. Como se ha mencionado antes, en función de la naturaleza de los datos y de la finalidad para la que el particionamiento es realizado, se pueden utilizar diferentes medidas de distancia para colocar los elementos en particiones. Por lo tanto, se formará una matriz en la que cada fila representa la distancia de una observación a cada centroide. Esta matriz se llama la «matriz de distancia».

El objetivo principal de la agrupación K-medias es minimizar la distancia de los puntos de datos al centroide de su partición y maximizar la distancia hacía los centroides de las otras particiones. Por lo tanto, en este paso tenemos que encontrar el centroide más cercano a cada punto de datos. Podemos utilizar la matriz de distancia para encontrar el centroide más cercano a los puntos de datos. Encontrando los centroides más cercanos para cada punto de datos, asignamos cada punto de datos a dicha partición. En otras palabras, todos los clientes caerán en una partición, basándose en su distancia hacía los centroides. Facilmente podemos decir que este procedimientos no logra buenas particiones, porque los centroides fueron escogidos al azar inicialmente. De hecho, el modelo tendá un gran error. Aquí,el error es la distancia total de cada punto a su centroide. Se puede mostrar como un error de la suma de los cuadrados dentro de una partición.

Movimiento de centroidesIntuitivamente, vamos a tratar de reducir este error. Debemos dar forma a las particiones de tal manera que la distancia total de todos los miembros
de una partición a su centroide se minimicen. Así que movemos los centroides para que sean la media de los puntos de datos de su partición. De hecho, cada centroide se mueve de acuerdo con los miembros de su partición. En otras palabras, el centroide de cada uno de los 3 grupos se convierte en la nueva media. Ahora tenemos nuevos centroides. Como puedes adivinar, una vez más, tendremos que calcular la distancia de todos los puntos a los nuevos centroides. Los puntos se vuelven a agrupar y los centroides se mueven de nuevo. Esto continúa hasta que los centroides ya no se muevan.

Sí, K-medias es un algoritmo iterativo, y tenemos que repetir los pasos hasta que el algoritmo converja. En cada iteración, moverá los centroides, calculará las distancias de los nuevos centroides, y asignará los puntos de datos al centroide más cercano. Esto resulta en particiones con un error mínimo, o particiones más consistentes. Sin embargo, como se trata de un algoritmo heurístico, no es garantía de que converja a la óptima global, y el resultado pueda depender de las particiones iniciales. Esto significa que este algoritmo está garantizado para converger a un resultado, pero el resultado puede ser un óptimo local (es decir, no necesariamente el mejor resultado posible). Para solucionar este problema, es común que se ejecute todo el proceso varias veces, con diferentes condiciones de partida. Esto significa, que con centroides iniciales aleatorizados, se puede obtener un mejor resultado. Y como el algoritmo es usualmente muy rápido, no sería ningún problema ejecutarlo varias veces.
Puedes ver un ejemplo en este artículo: Agrupación por K-medias en Python

Ir al artículo anterior de la serie: Introducción al clustering

Ir al artículo siguiente de la serie: Agrupación en clúster jerárquica

0 Seguir leyendo →

Introducción al clustering

Introducción al clustering

Vamos a ver una introducción al clustering, sus aplicaciones y diferentes tipos de algoritmos.
Imaginemos que tenemos un conjunto de datos y necesitamos aplicar una segmentación basándonos en datos históricos. La segmentación es la práctica de particionar una base de datos en grupos de observaciones que tienen características similares. Es una estrategia importante ya que permite que se pueda estudiar a grupos específicos para asignar más efectivamente los recursos. Por ejemplo, en un conjunto de datos de clientes de una empresa, un grupo puede contener clientes que son de alto beneficio y bajo riesgo, es decir, es más probable que compre productos o se suscriba a un servicio. Conocer esta información permite dedicar más tiempo y atención a aquellas observaciones que son más interesantes para el proyecto.

Un proceso de segmentación general no suele ser factible para grandes volúmenes de datos variados, por lo tanto, se necesita un enfoque analítico para derivar segmentos y grupos de grandes conjuntos de datos. El requisito importante es utilizar los datos disponibles para comprender e identificar cómo las diferentes unidades del conjunto son similares entre sí. Uno de los enfoques más adoptados que puede ser utilizado para la segmentación es el clustering. El clustering puede agrupar datos solo, sin supervisión, basado en la similitud de las observaciones entre sí. Dividirá el conjunto de datos en grupos mutuamente excluyentes. Las observaciones en cada grupo serán similares entre sí, pudiendo crear perfiles para cada grupo, considerando las características comunes de cada grupo. Finalmente, podemos asignar a cada observación de nuestro conjunto de datos a uno de estos grupos o segmentos. Esta información ayudaría a comprender y predecir las diferencias individuales y comportamientos.

El clustering significa encontrar agrupaciones en un conjunto de datos, sin supervisión. Un clúster es un grupo de puntos de datos u objetos en un conjunto de datos que son similares a otros objetos en el grupo y diferentes a los puntos de datos en otros grupos.

Difrencias entre clustering y clasificación

Los algoritmos de clasificación predicen categóricamenta las etiquetas de clase. Esto significa, asignar instancias a valores predefinidos de clases. Si un analista quiere analizar los datos de los clientes para saber qué clientes podrían incumplir sus pagos, utiliza un conjunto de datos etiquetado como datos de entrenamiento, y utiliza enfoques de clasificación como decisión, Máquinas de vectores de soporte (o SVM) o regresión logística para predecir el valor predeterminado para un nuevo o desconocido cliente. En términos generales, la clasificación es un modelo de aprendizaje supervisado donde cada instancia de datos de entrenamiento pertenece a una clase en particular.
Sin embargo, en el clustering, los datos no están etiquetados y el proceso no está supervisado. Podemos usar un algoritmo de clustering como k-Means, para agrupar clientes similares, y asignarlos a un clúster, en función de si comparten atributos similares, como edad, educación, etc.

Ejemplos de uso

  • En la industria minorista, el clustering se utiliza para encontrar asociaciones entre clientes sobre sus características demográficas y usar esa información para identificar patrones de compra de varios grupos de clientes. Además, se puede utilizar en sistemas de recomendación, para encontrar un grupo de elementos similares o usuarios similares, y usarlo para el filtrado colaborativo, recomendar cosas como libros o películas a los clientes.
  • En Banca, los analistas encuentran grupos de transacciones normales para encontrar los patrones fraudulentos de uso de tarjeta de crédito. Además, usan clustering para identificar clusters de clientes, por ejemplo, para encontrar clientes leales, frente a clientes abandonados.
  • En la industria de seguros, el clustering se utiliza para la detección de fraudes en el análisis de reclamos, o evaluar el riesgo de seguro de ciertos clientes en función de sus segmentos.
  • En Publication Media, el clustering se utiliza para clasificar automáticamente las noticias en función de su contenido, o etiquetar noticias, luego agruparlas, para recomendar artículos de noticias similares a los lectores.
  • En medicina: se puede utilizar para caracterizar el comportamiento del paciente, en función de sus características similares, para identificar terapias médicas exitosas para diferentes enfermedades.
  • En biología: el clustering se usa para agrupar genes con patrones de expresión similares, o agrupar marcadores genéticos para identificar los lazos familiares.

 

Tipos de clusteringSi mira a su alrededor, puede encontrar muchas otras aplicaciones de clustering, pero en general, se puede usar para uno de los siguientes propósitos: análisis exploratorio de datos, resumen generación o reducción de la escala, detección de valores atípicos, especialmente para el fraude detección o eliminación de ruido, encontrar duplicados en conjuntos de datos o, como paso previo al procesamiento ya sea para la predicción u otras tareas de minería de datos o como parte de un sistema complejo.

Algoritmos

Veamos brevemente diferentes algoritmos de clustering y sus características:

  • La agrupación basada en particiones es un grupo de algoritmos de agrupación que produce esferas de grupos, como k-Means, k-Median o Fuzzy c-Means. Estos algoritmos son relativamente eficientes y se utilizan para bases de datos de tamaño medio y grande.
  • Los algoritmos de agrupación jerárquica producen árboles de agrupaciones, como Agglomerative y Algoritmos divisivos. Este grupo de algoritmos son muy intuitivos y generalmente son buenos para usar con conjuntos de datos de pequeño tamaño.
  • Los algoritmos de agrupamiento basados en la densidad producen grupos de formas arbitrarias. Son especialmente buenos cuando se trata de grupos espaciales o cuando hay ruido en su conjunto de datos, por ejemplo, el algoritmo DBSCAN.

 

Ir al artículo anterior de la serie: Máquinas de soporte de vectores

Ir al artículo siguiente de la serie: Agrupación por K-medias

0 Seguir leyendo →