Está en la página 1de 35

Inteligencia de Negocio Práctica 2:

Análisis Relacional mediante


Segmentación
Germán José Padua Pleguezuelo
germanpadua@correo.ugr.es

Grupo 1 - 5º DGIIM

8 de diciembre de 2023

1
Índice

1. Introducción 3

2. Caso de estudio 1 5

2.1. Descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2. Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2.1. Estudio de parámetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.3. Interpretación de la segmentación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3. Caso de estudio 2 14

3.1. Descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.2. Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.2.1. Estudio de parámetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3.3. Interpretación de la segmentación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

4. Caso de estudio 3 26

4.1. Descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

4.2. Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

4.2.1. Estudio de parámetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

4.3. Interpretación de la segmentación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

2
1. Introducción

La práctica consiste en aplicar y analizar técnicas de agrupamiento para descubrir grupos en dis-
tintos conjuntos de datos seleccionados. El trabajo se realizará empleando bibliotecas y paquetes de
Python, principalmente numpy, pandas, scikit-learn, matplotlib y seaborn.

En este proyecto nos proponemos analizar la encuesta publicada el 6 de noviembre de 2023 de la


empresa 40db, donde se recoge la intención de voto de la población y otros asuntos de actualidad. Por
comodidad, se emplerán los datos proporcionados por el profesor, a los que se han realizado algunas
modificaciones mı́nimas y una transformación numérica.

Los datos consisten en 2000 respuestas y más de 50 variables que recogen datos demográficos, socio-
económicos, intención de voto, ideologı́a y opinión sobre temas de actualidad. Existen algunas variables
numéricas como la edad o la posición ideológica en una escala de 0 a 10, y otras que, al ser ordinales,
se pueden hacer numéricas. Sin embargo, algunas variables son nominales sin orden (por ejemplo, la
provincia de residencia) y no servirán para aplicar clustering. Pero sı́ se podrán emplear para definir
casos de uso o para comparar resultados entre distintos grupos. Además, los datos se acompañan con
una ponderación que determina el grado de representatividad de cada sujeto respecto a la población
general. Estos pesos se considerarán, siempre que sea posible, en la ejecución de los algoritmos y en
las visualizaciones para reflejar mejor la realidad.

Antes de aplicar cualquier algoritmo, aplicaremos una normalización a los datos e imputaremos los
valores desconocidos por vecinos más cercanos. Esto es necesario ya que para las distancias todas las
variables deben estar normalizadas y algunos algoritmos no funcionan con valores perdidos. También,
en cada caso de estudio indicaremos si hay que hacer algún tratamiento extra por si existieran valores
del tipo “no sabe” o “no contesta”.

En cada caso de estudio se analizarán 6 algoritmos distintos de agrupamiento [1]:

K-Means: Es un estándar en clustering, que asigna cada punto de datos al clúster cuyo centroide
es el más cercano. Es eficiente y fácil de entender, siendo adecuado para conjuntos de datos
grandes. Además, permite tener en cuenta el peso de cada dato.
Mean-Shift: Este algoritmo no requiere la especificación a priori del número de clústeres y es
capaz de encontrar automáticamente el número óptimo. Funciona desplazando iterativamente
los centroides hacia las regiones de alta densidad de datos.
DBSCAN (Density-Based Spatial Clustering of Applications with Noise): Es capaz de descubrir
clústeres de forma arbitraria y es robusto frente a ruido y valores atı́picos. Se basa en la densidad
de los puntos en el espacio de caracterı́sticas. Al igual que K-Means, permite tener en cuenta las
ponderaciones de la muestra.
HDBSCAN (Hierarchical Density-Based Spatial Clustering of Applications with Noise): A dife-
rencia de DBSCAN, HDBSCAN incorpora un enfoque jerárquico que permite identificar clústeres
de diferentes escalas. Este algoritmo asigna automáticamente la densidad a diferentes niveles, lo
que le brinda flexibilidad para detectar clústeres de distintos tamaños y formas en el conjunto
de datos.
Agglomerative Clustering: Este enfoque es de tipo jerárquico, comenzando con muchos pequeños
clústeres y fusionándolos gradualmente en clústeres más grandes. Puede proporcionar una visión
jerárquica de la estructura de los datos.
Spectral Clustering: Utiliza la información espectral del grafo de similitud de datos para realizar el
agrupamiento. Es eficaz para identificar clústeres no convexos y puede funcionar bien en conjuntos
de datos de alta dimensionalidad.

Además, se estudiará el efecto de algunos de sus párametros determinantes en al menos 2 algoritmos


para cada caso.

3
Las métricas de rendimiento que utilizaremos para comparar los resultados de los algoritmos ante-
riores son [2]:

Coeficiente Silhouette: Mide qué tan similar es un objeto a su propio clúster en comparación
con otros clústeres. Toma valores en el rango [-1, 1], donde valores más altos indican una mejor
separación de clústeres.
Índice de Calinski-Harabasz : Evalúa la relación entre la dispersión intraclúster y la dispersión
interclúster. Valores más altos indican una mejor separación entre los clústeres.

Índice de Dunn: Busca clústeres compactos y bien separados. Se define como la mı́nima relación
entre la distancia mı́nima entre puntos de diferentes clústeres y la distancia máxima entre puntos
del mismo clúster. [3]
Índice de Davies-Bouldin: Cuanto más bajo sea el valor, mejor será la partición. Mide la “bondad”
de la partición al evaluar la similitud promedio entre cada clúster y su clúster más similar.

4
2. Caso de estudio 1

2.1. Descripción

En primer lugar, vamos a intentar estudiar cuál es el nivel de preocupación de la población por
el cambio climático. Para ello, seleccionamos las siguientes variables: edad, ideologı́a, educación y la
respuesta a la pregunta 8.1 (en qué grado siente como amenaza el cambio climático). A menudo se
argumenta que los jóvenes suelen reciclar más y muestran una mayor conciencia ambiental, en este
caso de estudio intentaremos probar si esto es cierto o no.

2.2. Resultados

A continuación, presentamos las tablas con los resultados obtenidos por los distintos algoritmos de
clústering empleados:

Algoritmo Nº Clústers Tiempo (s) Silhouette Calinski-Harabasz Dunn Davies-Bouldin


K-Means 3 0.09 0.29991 793.816 0.66041 1.23721
Mean-Shift 2 0.67 0.30318 944.141 0.62414 1.36368
DBSCAN 1 0.06 0.263 205.831 593438 1.60316
HDBSCAN 2 0.10 0.278 623.994 800146 1.236
Agglomerative 3 0.16 0.262 642.685 0.63065 1.35869
Spectral 3 0.65 0.276 774.85 0.63033 1.35505

Cuadro 1: Resultados en el primer caso de estudio.

Hemos utilizado los siguientes parámetros: K-Means (k=3), Mean-Shift (bandwidth=0.5), DBS-
CAN (eps=0.25, min samples=15), HDBSCAN (min cluster size=300, min-samples=1), Agglomera-
tive (n clusters=3), Spectral (n clusters=3)

Para comparar gráficamente las métricas, hacemos uso de un radial plot:

Calinski-Harabasz
K-Means
Mean-Shift
DBSCAN
HDBSCAN
Agglomerative
Spectral
Silhouette

Davies-Bouldin

Nº Clústers

Tiempo (s)

Figura 1: Resultados en un gráfico radial (normalizados en el intervalo [0.3, 1.0])

5
Observamos que Mean-Shift es el que mejores métricas tiene en general. No obstante, es importante
señalar que este algoritmo solo logra generar 2 clústeres y su tiempo de ejecución es más prolongado en
comparación con los demás. Sorprendentemente, DBSCAN es el que peores métricas obtiene, lo que
sugiere la posibilidad de que no se hayan ajustado adecuadamente sus parámetros. Entre los algoritmos
que generan 3 clústeres, el que ofrece mejores resultados es K-Means.

Mostramos parte del código utilizado para hacer el gráfico radial:

1 import matplotlib . pyplot as plt


2 import numpy as np
3
4 # Normalizar las metricas seleccionadas
5 n o r m a l i z e d _ m e t r i c s = [ normalize ( metric ) for metric in s e l e c te d _ m e t r i c s ]
6
7 # Crear un grafico radial
8 fig , ax = plt . subplots ( figsize =(8 , 8) , subplot_kw = dict ( polar = True ) )
9
10
11 # Superponer los graficos radiales
12 for i , algoritmo in enumerate ( algoritmos ) :
13 data = [ metric [ i ] for metric in n o r m a l i z e d _ m e t r i c s ]
14
15 angles = np . linspace (0 , 2 * np . pi , len ( data ) + 1 , endpoint = True ) # Aniadir 1 al
tamanio de data
16 angles += np . pi /6 # Alinea los angulos con las etiquetas de las categorias
17
18 # Pintar solo las lineas y cambiar el color para cada algoritmo
19 ax . plot ( angles , data + [ data [0]] , label = algoritmo , color = colors [ i ] , linewidth =2.5)
20
21 ax . s e t_ yt ic k la be ls ([]) # Oculta las etiquetas del eje y
22 ax . set_xticks ( angles [: -1]) # Eliminar el ultimo angulo para evitar superposicion
23 ax . s e t_ xt ic k la be ls ([ ’ Silhouette ’ , ’ Calinski - Harabasz ’ , ’ Davies - Bouldin ’ , ’ Tiempo ( s ) ’ ,
’N Clusters ’ ])
24 ax . legend ( loc = ’ upper left ’) # Agregar leyenda
Listing 1: Extracto del código para crear un gráfico radial

6
2.2.1. Estudio de parámetros

Vamos a estudiar también cómo evoluciona el coeficiente de Silhouette y el ı́ndice de Calinski-


Harabasz para distintos valores de k en K-Means y para distintos valores de min cluster size y
min samples en HDBSCAN.

k Tiempo (s) Silhouette Calinski-Harabasz Davies-Bouldin


2 0.029486 0.303331 944.915710 1.363419
3 0.077718 0.299906 793.815648 1.237208
4 0.055130 0.228605 687.072271 1.529001
5 0.093189 0.225778 635.309987 1.484503
6 0.076821 0.223041 592.540362 1.524788
7 0.087246 0.220795 577.358331 1.410766
8 0.130253 0.221227 556.156949 1.379014
9 0.093615 0.217650 522.043278 1.368536
10 0.089802 0.221440 506.447149 1.338476
11 0.110525 0.218139 475.471102 1.350590
12 0.176297 0.216809 466.751787 1.309598
13 0.154415 0.227175 450.826506 1.281808
14 0.141084 0.226304 438.166840 1.331106
15 0.170165 0.245699 429.809396 1.185629
16 0.109250 0.240794 428.553172 1.259590
17 0.177949 0.247728 417.424776 1.222057
18 0.182712 0.249516 415.678088 1.239673
19 0.170097 0.267534 412.186938 1.208559
20 0.145797 0.263065 403.144369 1.213179

Cuadro 2: Medidas en K-Means para distintos valores de k

Evolución de Silhouette para distintos valores de k Evolución del Índice Calinski-Harabasz para distintos valores de k

0.30
900

0.28 800
Calinski-Harabasz Index
Silhouette Coefficient

700
0.26

600

0.24

500

0.22
400
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Número de Clusters (k) Número de Clusters (k)

Figura 2: Evolución de Silhouette y Calinski-Harabasz en K-Means

Vemos que en K-Means el coeficiente de Silhouette es alto para k=2, 3, pero luego disminuye drásti-
camente. Para valores mayores de k, vuelve a aumentar pero si eligiésemos estudiar esos resultados,
serı́an muy difı́ciles de interpretar debido al gran número de clústers. Destacamos el decrecimiento del
ı́ndice de Calinski-Harabasz, por lo que conforme aumentamos el número de clústers formados, peor es
la separación entre ellos.

7
HDBSCAN Parameter Tuning Heatmap (Silhouette Score) HDBSCAN Parameter Tuning Heatmap (Calinski-Harabasz Index)
600
0.0052 -0.015 0.022 0.078 0.12 0.051 74.88877 67.67568 107.50845 151.58804 172.82532 164.96293

10

10
0.25

500
0.079 0.064 0.15 0.16 0.12 0.051 154.98439 171.47704 216.60910 221.81018 183.24690 164.96293
25

25
0.20

400

Calinski-Harabasz Index
0.2 0.2 0.19 0.16 0.11 0.051 326.61160 321.68093 298.09612 231.49757 185.54825 176.63094
50

50
0.15
min_cluster_size

min_cluster_size
Silhouette Score
0.18 0.18 0.17 0.14 0.09 0.076 344.74185 340.34112 319.81102 254.12177 257.08531 258.66441 300
100

100
0.10

0.032 0.031 0.029 0.25 0.15 0.14 232.09061 231.74665 229.55442 497.52330 315.28735 292.57641
200

200
0.05 200

0.28 0.28 0.27 0.25 0.15 0.14 623.99448 619.78611 589.03363 497.52330 315.28735 292.57641
300

300
0.00 100

1 2 5 10 15 20 1 2 5 10 15 20
min_samples min_samples

Figura 3: Heatmaps de Silhouette y Calinski-Harabasz para distintos valores de parámetros en HDBS-


CAN

Por otro lado, vemos que la distribución de ambas medidas en HDBSCAN es muy similar. Las
dos son altas para min cluster size=50, 100, 300 y min samples=1, 2, 5, 10, 15, 20. Esto puede ser
debido a que para los valores bajos de mı́nimo tamaño de clúster y mı́nimas muestras, el algoritmo
tiende a identificar más clústers pequeños y ruidosos que no tienen un significado real. En cambio, al
forzar que los clústers estén formados por un mı́nimo de 300 puntos, aumentan las métricas. Además,
el parámetro min samples indica el número mı́nimo de vecinos que un punto debe tener para que
se le considere núcleo. Por lo que, a pesar de obtener mejores resultados con min cluster size=300 y
min samples=1, será “más fiable” estudiar los casos con mayor min samples.

Vamos a mostrar parte del código utilizado para crear los heatmaps previos:
1
2 def v i s u a l i z e _ h d b s c a n _ c o n f i g u r a t i o n s _ s i l h o u e t t e ( conf iguratio ns ) :
3 # Convert the confi guratio ns to a DataFrame
4 df = pd . DataFrame ( config uration s )
5
6 # Create a subplot for silhouette scores
7 plt . figure ( figsize =(18 , 8) )
8 plt . subplot (1 , 2 , 1)
9 h e a t m a p _ d a t a _ s i l h o u e t t e = df . pivot_table ( index = ’ m i n _ c l u s t e r _ s i z e ’ , columns = ’
min_samples ’ , values = ’ s i l ho u e t t e _ s c o r e ’)
10 sns . heatmap ( heatmap_data_silhouette , annot = True , cmap = " YlGnBu " , cbar_kws ={ ’ label ’:
’ Silhouette Score ’ })
11 plt . title ( ’ HDBSCAN Parameter Tuning Heatmap ( Silhouette Score ) ’)
Listing 2: Extracto del código para crear un heatmap para HDBSCAN

8
1 def m u l t i p l e _ h d b s c a n _ s i l h o u e t t e ( conj_dat , min_cluster_sizes , min_samples ,
cluster_selection_methods ):
2 s i l h o u e t t e _ s c o r e s = []
3
4 for m i n _ c l u s t e r _ s i z e in m i n _ c l u s t e r _ s i z e s :
5 for min_sample in min_samples :
6 h d b s c a n _ c l u s t e r e r = hdbscan . HDBSCAN (
7 m i n _ c l u s t e r _ s i z e = min_cluster_size ,
8 min_samples = min_sample ,
9 )
10
11 c lu st er _ pr ed ic t = h d b s c a n _ c l u s t e r e r . fit_predict ( conj_dat )
12
13 # Check the number of unique clusters before calculating silhouette score
14 u ni qu e_ c lu st er s = len ( np . unique ( c l us te r_ p re di ct ) )
15 if un iq u e_ cl us t er s > 1:
16 silho uette_a vg = s i l h o u e t t e _ s c o r e ( conj_dat , cl us t er _p r ed ic t )
17 s i l h o u e t t e _ s c o r e s . append ({
18 ’ m i n _ c l u s t e r _ s i z e ’: min_cluster_size ,
19 ’ min_samples ’: min_sample ,
20 ’ s i l h o u e t t e _ s c o r e ’: silhouette_avg ,
21 ’ num_clusters ’: un iq ue _ cl us te r s
22 })
23
24 # Visualize all c onfigura tions using a heatmap
25 visualize_hdbscan_configurations_silhouette ( silhouette_scores )
26
27 return s i l h o u e t t e _ s c o r e s
Listing 3: Extracto del código para ejecutar HDBSCAN con múltiples parámetros

Ejemplo de uso:
1
2 m i n _ c l u s t e r _ s i z e s = [10 , 25 , 50 , 100 , 200 , 300]
3 min_samples = [1 , 2 , 5 , 10 , 15 , 20]
4 c l u s t e r _ s e l e c t i o n _ m e t h o d s = [ ’ eom ’]
5
6 a l l _ c o n f i g u r a t i o n s _ s i l h o u e t t e = m u l t i p l e _ h d b s c a n _ s i l h o u e t t e ( X2_norm , min_cluster_sizes
, min_samples , c l u s t e r _ s e l e c t i o n _ m e t h o d s )
Listing 4: Extracto del código para ejecutar y mostrar HDBSCAN con múltiples parámetros

9
2.3. Interpretación de la segmentación

En este apartado nos basaremos en los resultados de los algoritmos que han obtenido un coeficiente
Silhouette mayor, en nuestro caso estudiaremos K-Means.

Comenzamos viendo los distintos valores del coeficiente para los clústers formados:
K-Means (K=3)
The silhouette plot.

2
Cluster label

0.1 0.0 0.2 0.4 0.6 0.8 1.0


The silhouette coefficient values

Figura 4: Coeficiente de Silhouette en cada clúster

Podemos destacar la diferencia de tamaño entre los agrupamientos. En primer lugar, tenemos el
clúster 1 con un 46.95 % de los individuos; luego el clúster 3 con un 37 % y por último el clúster 2
con 16.05 %. Este último grupo no está muy bien formado, ya que podemos ver que algunos de sus
individuos tienen un coeficiente muy bajo, incluso negativo.

Lo siguiente que vamos a visualizar será la distancia que hay entre los distintos clústers. Para ello,
haremos uso de Multi Dimensional Scaling reduciendo ası́ las dimensiones del problema a 2. Veremos
dos gráficos, el primero solamente con los centroides de cada grupo y luego otro con todos los puntos.

Visualización de Centroides después de MDS


1.2

1.0

0.8
Dimensión 2 (MDS)

0.6

0.4

0.2
Cluster 1
Cluster 2
Cluster 3
0.0
0.36 0.38 0.40 0.42 0.44 0.46 0.48 0.50
Dimensión 1 (MDS)

Figura 5: Distancia relativa entre centroides de clústers (radio del cı́rculo proporcional a la suma de
los pesos de los objetos en cada clúster)

10
Visualización de Clusters después de MDS
Cluster 1
1.00 Cluster 2
Cluster 3

0.75

0.50

Dimensión 2 (MDS)
0.25

0.00

0.25

0.50

0.75

1.00 0.75 0.50 0.25 0.00 0.25 0.50 0.75


Dimensión 1 (MDS)

Figura 6: Distancia relativa entre todos los puntos (tamaño de cada punto proporcional a su pondera-
ción)

Tal y como muestran las gráficas previas, apreciamos que a pesar de que los centroides de los
clústers 2 y 3 están a una distancia pequeña, luego vemos que el clúster 2 se mezcla con ambos grupos.
Sin embargo, es clara la separación entre los clústers 1 y 3, que son los que mayor tamaño tienen.

Para ejecutar Multi Dimensional Scaling es tan simple como indicar el número de dimensiones y
el DataFrame:
1
2 from sklearn . manifold import MDS
3 import matplotlib . pyplot as plt
4
5 # Aplicar MDS a 2 dimensiones
6 mds = MDS ( n_components =2 , random_state =123456)
7 X_mds = mds . fit_transform ( X2_norm )
8
9 # Aniadir la columna de c lu st e r_ pr ed i ct y peso al DataFrame original
10 X 2 _ w i t h _ c l u s t e r s = X2 . copy ()
11 X 2 _ w i t h _ c l u s t e r s [ ’ cluster ’] = cl us t er _p re d ic t
12 X 2 _ w i t h _ c l u s t e r s [ ’ peso ’] = datos [ ’ ponde ’]
Listing 5: Extracto del código para ejecutar MDS

Y para mostrar el gráfico anterior hacemos uso de la función scatter de matplotlib.pyplot:


1 plt . figure ( figsize =(12 , 8) )
2
3 for cluster in range ( k_means . n_clusters ) :
4 clus ter_poin ts = X 2 _ w i t h _ c l u s t e r s [ X 2 _ w i t h _c l u s t e r s [ ’ cluster ’] == cluster ]
5 plt . scatter (
6 X_mds [ clust er_point s . index , 0] ,
7 X_mds [ clust er_point s . index , 1] ,
8 label = f ’ Cluster { cluster + 1} ’ ,
9 color = colors [ cluster ] ,
10 s = X 2 _ w i t h _ c l u s t e r s . loc [ clus ter_poin ts . index , ’ peso ’] * 70 , # Ajusta la escala
11 alpha =0.7 # Ajusta la transparencia de los puntos
12 )
13
14 plt . title ( ’ Visualizacion de Clusters despues de MDS ’)
15 plt . xlabel ( ’ Dimension 1 ( MDS ) ’)
16 plt . ylabel ( ’ Dimension 2 ( MDS ) ’)
17 plt . legend ()
Listing 6: Extracto del código para mostrar el resultado de MDS

11
Ahora procederemos a representar visualmente la matriz de dispersión de los resultados obtenidos
mediante el algoritmo. Esta herramienta nos permitirá derivar conclusiones al graficar, en cada celda
de la matriz, un gráfico de dispersión de cada par de las variables seleccionadas para el estudio.






HGDG











HGXFDFLyQ






FOXVWHU
 



FDPELRFOLPiWLFR













LGHRORJtD






                       
HGDG HGXFDFLyQ FDPELRFOLPiWLFR LGHRORJtD

Figura 7: Scatter Matrix K-Means (cada punto es proporcional a su ponderación)

Empezamos analizando la primera fila, observamos que individuos de todas las edades pertenecen
a todos los grupos. Además, por los respectivos histogramas concluimos que el grupo 1 tiene una
educación más baja, mientras que al clúster 3 pertenecen individuos con un nivel educativo mayor.
Y que las personas del clúster 2 no sienten como amenaza el cambio climático, al contrario de lo que
ocurre en los clústers 1 y 3. También podemos destacar que el clúster 2 está compuesto por personas
con una ideologı́a más de derechas.

En resumen, el clúster 1 lo forman personas de edad variada, baja educación, de todas las ideologı́as
y que les preocupa el cambio climático. En el clúster 2 también encontramos edades e ideologı́as diversas
que se preocupan por esta amenaza, pero que tienen un nivel de estudios mayor. Por último, el clúster
3 tiene individuos mayormente de derechas que no ven en el cambio climático un peligro.

12
Las conclusiones anteriores las podemos respaldar igualmente con el siguiente gráfico:

Cluster 2

0.0 0.2 0.4 0.6 0.8 1.0 0.0 0.2 0.4 0.6 0.8 1.0 0.0 0.2 0.4 0.6 0.8 1.0 0.0 0.2 0.4 0.6 0.8 1.0
Cluster 1

0.0 0.2 0.4 0.6 0.8 1.0 0.0 0.2 0.4 0.6 0.8 1.0 0.0 0.2 0.4 0.6 0.8 1.0 0.0 0.2 0.4 0.6 0.8 1.0
Cluster 3

0.0 0.2 0.4 0.6 0.8 1.0 0.0 0.2 0.4 0.6 0.8 1.0 0.0 0.2 0.4 0.6 0.8 1.0 0.0 0.2 0.4 0.6 0.8 1.0
edad educación cambio climático ideología

Figura 8: Distribución de los grupos ordenados de menor a mayor preocupación por el cambio climático

Como conclusión final, hemos visto que personas de todas las edades e ideologı́as, ası́ como con
niveles variados de educación, muestran una preocupación generalizada por la amenaza climática. En
cambio, existe una minorı́a que se identifica mayormente con pensamientos de derecha y que no percibe
este problema como una amenaza.

13
3. Caso de estudio 2

3.1. Descripción

En el segundo caso de estudio, nos centraremos en analizar la situación económica de la población


española. Para ello, seleccionamos las siguientes variables: edad, si convive con algún hijo, situación
económica (cuánto ahorra cada mes), nivel de preocupación por la crisis de inflación y su situación
laboral.

3.2. Resultados

A continuación, presentamos las tablas con los resultados obtenidos por los distintos algoritmos de
clústering empleados:

Algoritmo Nº Clústers Tiempo (s) Silhouette Calinski-Harabasz Dunn Davies-Bouldin


K-Means 3 0.04 0.35975 1019.091 0.6138 1.124
Mean-Shift 5 0.81 0.338 659.437 0.61658 1.1264
DBSCAN 108 0.08 0.353 85.4 0.2729 1.242
HDBSCAN 2 0.11 0.222 430.015 0.61887 2.20028
Agglomerative 4 0.12 0.352 798.603 0.6008 1.0427
Spectral 3 2.96 0.357 1012.604 0.60498 1.14135

Cuadro 3: Resultados en el segundo caso de estudio.

Hemos utilizado los siguientes parámetros: K-Means (k=3), Mean-Shift (bandwidth=0.5), DBSCAN
(eps=0.2, min samples=3), HDBSCAN (min cluster size=100, min-samples=2, cluster selection epsilon=0.75),
Agglomerative (n clusters=4), Spectral (n clusters=3)

Para comparar gráficamente las métricas, hacemos uso de un radial plot:

Calinski-Harabasz
K-Means
Mean-Shift
DBSCAN
HDBSCAN
Agglomerative
Spectral
Silhouette

Davies-Bouldin

Nº Clústers

Tiempo (s)

Figura 9: Resultados en un gráfico radial (normalizados en el intervalo [0.3, 1.0])

14
Observamos que todos los algoritmos menos HDBSCAN, obtienen un coeficiente de Silhouette
similar. Respecto a las demás métricas, Spectral Clustering y Agglomerative Clustering obtienen unos
buenos resultados. Debido a que HDBSCAN obtiene un número elevado de clústers, indicamos con
el parámetro cluster selection epsilon que los clústers por debajo de ese umbral de distancia serán
fusionados.

3.2.1. Estudio de parámetros

Vamos a estudiar también cómo evoluciona el coeficiente de Silhouette y los ı́ndices de Calinski-
Harabasz y de Davies-Bouldin para distintos valores de bandwidth en Mean-Shift y para distintos
valores de n clusters y linkage en Agglomerative Clustering. Linkage determina que distancia usar
entre dos conjuntos. En este caso probaremos con ward, que minimiza la varianza de los clústers
fusionados, y average, que usa la media de las distancias de cada observación de los dos conjuntos.

Bandwidth Nº Clústers Tiempo (s) Silhouette Calinski-Harabasz Davies-Bouldin


0.1 387 1.365786 0.538044 429.372762 0.332109
0.15 292 1.320150 0.563645 349.343651 0.430777
0.2 238 1.244179 0.496297 261.175893 0.581243
0.25 178 1.153581 0.401931 211.316407 0.723495
0.5 5 0.906851 0.338005 659.437208 1.126391
0.75 1 0.403107 - - -
1.0 1 0.173346 - - -

Cuadro 4: Medidas en Mean-Shift para distintos valores de bandwidth

Silhouette and Davies-Bouldin Scores vs Bandwidth Calinski-Harabasz Score vs Bandwidth


Silhouette
Davies-Bouldin
1.0 600

500
0.8
Calinski-Harabasz Score

400
0.6
Score

300

0.4
200

0.2
100

0.0 0
0.2 0.4 0.6 0.8 1.0 0.2 0.4 0.6 0.8 1.0
Bandwidth Bandwidth

Figura 10: Evolución de las medidas en Mean-Shift

Aunque para valores bajos de bandwidth el algoritmo obtiene un número muy elevado de clústers.
Vemos que para un bandwidth=0.2 se obtienen los mejores coeficiente de Silhouette e ı́ndice Davies-
Bouldin, pero el valor del ı́ndice de Calinski-Harabasz más alto se alcanza para bandwidth=0.5.

15
Nº Clústers Tiempo (s) Silhouette Calinski-Harabasz Davies-Bouldin
2 0.113 0.3340 1000.9376 1.2272
3 0.105 0.3520 984.7088 1.1051
4 0.116 0.3521 798.6025 1.0426
5 0.1095 0.2465 727.2721 1.2150
6 0.1308 0.2571 668.1198 1.1985
7 0.111 0.2336 638.7525 1.3596
8 0.1079 0.2520 621.2147 1.2846
9 0.1205 0.2455 594.7110 1.3626
10 0.1433 0.2307 577.6341 1.4337

Cuadro 5: Medidas en Agglomerative Clustering con linkage=ward para distinto número de clúster

Nº Clústers Tiempo (s) Silhouette Calinski-Harabasz Davies-Bouldin


2 0.1070 0.3391 994.3712 1.1989
3 0.1212 0.2980 525.4948 1.1793
4 0.1173 0.2809 441.0265 1.0823
5 0.1396 0.3416 637.8667 1.0373
6 0.1552 0.3364 519.1233 0.9941
7 0.1417 0.3227 436.2028 0.9370
8 0.1270 0.2797 413.3993 0.9855
9 0.1334 0.2740 362.4264 0.9026
10 0.1148 0.2638 335.2540 0.9441

Cuadro 6: Medidas en Agglomerative Clustering con linkage=average para distinto número de clúster

Silhouette and Davies-Bouldin Scores vs Number of Clusters Calinski-Harabasz Score vs Number of Clusters
Silhouette (average) 1000 Calinski-Harabasz (average)
1.4 Davies-Bouldin (average) Calinski-Harabasz (ward)
Silhouette (ward)
Davies-Bouldin (ward)
900
1.2

800
Calinski-Harabasz Score

1.0
700
Score

0.8
600

0.6
500

0.4 400

0.2 300
2 4 6 8 10 2 4 6 8 10
Number of Clusters Number of Clusters

Figura 11: Evolución de las medidas en Agglomerative Clustering

En este caso, el rendimiento del algoritmo con linkage=average es superior si nos fijamos en las
primeras medidas. Esto puede indicar que realiza una mejor separación entre los clústers y su simili-
tud promedio es más baja. Por otro lado, si nos fijamos en los resultados de Calinski-Harabasz, con
linkage=ward obtenemos una separación entre clústers mejor.

16
Mostramos el fragmento de código utilizado para la creación de los gráficos anteriores:
1 # Lista de valores de n_clusters que deseas probar
2 n_clust = [2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11]
3
4 # Inicializar listas para almacenar los resultados para linkage = ’ average ’
5 s i l h o u e t t e _ s c o r e s _ a v g = []
6 d a v i e s _ b o u l d i n _ s c o r e s _ a v g = []
7 c a l i n s k i _ h a r a b a s z _ s c o r e s _ a v g = []
8
9 # Inicializar listas para almacenar los resultados para linkage = ’ ward ’
10
11 for n in n_clust :
12 # Agglomerative Clustering con linkage = ’ average ’
13 t = time . time ()
14 agg_avg = A g g l o m e r a t i v e C l u s t e r i n g ( n_clusters =n , linkage = ’ average ’) . fit ( X3_norm )
15 tiempo = time . time () - t
16
17 labels_avg = agg_avg . labels_
18
19 l a b e l s _ u n i q u e _ a v g = np . unique ( labels_avg )
20 n_cl usters_a vg = len ( l a b e l s _ u n i q u e _ a v g )
21
22 if n_ clusters _avg == 1:
23 metric_CH_avg = 0
24 silh ouette_a vg = 0
25 metric_DB_avg = 0
26 else :
27 metric_CH_avg = metrics . c a l i n s k i _ h a r a b a s z _ s c o r e ( X3_norm , labels_avg )
28 silh ouette_a vg = metrics . s i l h o u e t t e_ s c o r e ( X3_norm , labels_avg )
29 metric_DB_avg = d a v i e s _ b o u l d i n _ s c o r e ( X3_norm , labels_avg )
30
31 # Almacenar resultados para linkage = ’ average ’
32 s i l h o u e t t e _ s c o r e s _ a v g . append ( silho uette_a vg )
33 d a v i e s _ b o u l d i n _ s c o r e s _ a v g . append ( metric_DB_avg )
34 c a l i n s k i _ h a r a b a s z _ s c o r e s _ a v g . append ( metric_CH_avg )
35
36 # Lo mismo para linkage = ’ ward ’
37
38 # Plot Silhouette and Davies - Bouldin together
39 plt . figure ( figsize =(14 , 7) )
40 plt . subplot (121)
41
42 # Plot Silhouette for linkage = ’ average ’
43 plt . plot ( n_clust , silhouette_scores_avg , marker = ’o ’ , color = ’ blue ’ , label = ’ Silhouette (
average ) ’)
44 # Plot Davies - Bouldin for linkage = ’ average ’
45 plt . plot ( n_clust , davies_bouldin_scores_avg , marker = ’o ’ , color = ’ orange ’ , label = ’ Davies
- Bouldin ( average ) ’)
46
47 # Plot Silhouette for linkage = ’ ward ’
48 # Plot Davies - Bouldin for linkage = ’ ward ’
49
50 plt . title ( ’ Silhouette and Davies - Bouldin Scores vs Number of Clusters ’)
51 plt . xlabel ( ’ Number of Clusters ’)
52 plt . ylabel ( ’ Score ’)
53 plt . legend ()
54
55 # Analogo para Calinski - Harabasz
56
57 plt . savefig ( ’ p a r a m e t r o s A g g l o m e r a t i v e . pdf ’)
58 plt . show ()
Listing 7: Extracto del código para ejecutar y mostrar con distintos parámetros Agglomerative
Clustering

17
3.3. Interpretación de la segmentación

En este apartado nos basaremos en los resultados de Mean-Shift y del algoritmo jerárquico aglo-
merativo. Comentaremos primero los resultados de Mean-Shift y más tarde los comparemos con los de
Agglomerative Clustering.

Comenzamos viendo los distintos valores de coeficiente de Silhouette de todos los puntos:
MeanShiftSilhouette
5
4

2
Cluster label

0.1 0.0 0.2 0.4 0.6 0.8 1.0


The silhouette coefficient values

Figura 12: Coeficiente de Silhouette en cada clúster

Clúster Nº Individuos % del total


1 987 49.35 %
2 591 29.55 %
3 306 15.3 %
4 84 4.2 %
5 32 1.6 %

Cuadro 7: Tamaño de los clústers en Mean-Shift

Destacamos la diferencia en tamaño que hay entre los distintos clústers obtenidos. En primer lugar,
el clúster 1 contiene a prácticamente la mitad de la población estudiada (987 individuos). Luego el
clúster 2 con un 29.55 % de los datos y el clúster 3 con un 15.3 %. Por último, el algoritmo obtiene dos
clústers muy minoritarios pero que tienen un alto valor del coeficiente, el clúster 4 con 84 individuos
y el clúster 5 con solamente 1.6 % de los datos.

Para ver la distancia entre los grupos y comprobar si realmente están bien diferenciados, haremos
uso de Multi Dimensional Scaling para reducir las dimensiones del problema a 2. Veremos dos gráficos,
el primero solamente con los centros de cada grupo y luego otro con todos los puntos.

18
Visualización de centros después de MDS
Cluster 1
1.0 Cluster 2
Cluster 3
Cluster 4
0.8 Cluster 5

0.6

Dimensión 2 (MDS) 0.4

0.2

0.0

0.2
0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7
Dimensión 1 (MDS)

Figura 13: Distancia relativa entre centros de clústers (radio del cı́rculo proporcional a la suma de los
pesos de los objetos en cada clúster)

Visualización de Clusters después de MDS


Cluster 1
1.00 Cluster 2
Cluster 3
Cluster 4
Cluster 5
0.75

0.50

0.25
Dimensión 2 (MDS)

0.00

0.25

0.50

0.75

1.00
1.0 0.5 0.0 0.5 1.0
Dimensión 1 (MDS)

Figura 14: Distancia relativa entre todos los puntos (tamaño de cada punto proporcional a su ponde-
ración)

Apreciamos una clara separación entre los clústers 1, 2, 3 y 4. Sin embargo, en la proyección a 2
dimensiones realizada por Multi Dimensional Scaling, el clúster 5 está muy disperso.

Ahora procederemos a representar visualmente la distribución por variables de cada clúster.

19
Cluster 5

0.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.00
Cluster 1

0.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.00
Cluster 2

0.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.00
Cluster 3

0.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.00
Cluster 4

0.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.00
edad hijos ahorro preocupación inflación situación laboral

Figura 15: Distribución de los grupos ordenados de menor a mayor preocupación por la inflación

Como los últimos clústers son tan minoritarios que no se aprecian en la imagen, realizamos otro
gráfico pero solamente con esos grupos:
Cluster 5

0.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.00
Cluster 4

0.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.00
edad hijos ahorro preocupación inflación situación laboral

Figura 16: Distribución de los grupos 4 y 5 ordenados de menor a mayor preocupación por la inflación

20
Para apoyar el análisis, mostraremos un heatmap de los centros de los clústers:

0.467 0.091 0.646 0.851 0.811


1

0.8

0.536 0.835 0.616 0.867 0.784


2

0.6

0.232 0.033 0.624 0.875 0.126


3

0.4

0.509 0.868 0.430 0.935 0.000


4

0.2

0.309 0.050 0.000 0.067 0.750


5

0.0
edad

preocupación inflación
hijos

ahorro

situación laboral

Figura 17: Centros de los grupos

Vamos a ir comentando las caracterı́sticas de cada clúster. El clúster 1 está compuesto por personas
que no conviven con ningún hijo o si lo hacen es con un hijo de 0 a 8 años, que llegan justas a final
de mes o ahorran un poco de dinero, trabajan o son pensionistas y tienen una preocupación alta por
inflación. El clúster 2 es similar al primer grupo pero conviven con hijos mayores. Por otro lado, el
clúster 3 lo forman individuos jóvenes, que no conviven con hijos, que no trabajan (ya sea porque
estudian o porque están parados) y que también les preocupa la inflación. Al clúster 4 pertenecen
personas de edad media en paro, que conviven con hijos mayores y que difı́cilmente llegan a final de
mes. Por último, las personas del clúster 5 son jóvenes que trabajan, que no tienen hijos y que no
sienten la inflación como una amenaza. A este grupo también pertenecen algunos individuos que han
tenido que contraer deuda en el último mes, lo que choca con que no les preocupe el problema de este
caso de estudio.

En conclusión, la población española, sin importar su edad o situación laboral, enfrenta dificultades
para llegar cómodamente a fin de mes, y solo un pequeño sector tiene la capacidad de ahorrar bastante
dinero al mes. Este panorama refleja la importancia crı́tica de las crisis de inflación, que elevan el costo
de vida y demandan soluciones urgentes para mejorar la situación de los ciudadanos en España.

21
Pasamos ahora a ver los resultados obtenidos por Agglomerative Clustering. Visualizamos los dis-
tintos valores de coeficiente de Silhouette de todos los puntos:
AggSilhouette
4

Cluster label 1

0.1 0.0 0.2 0.4 0.6 0.8 1.0


The silhouette coefficient values

Figura 18: Coeficiente de Silhouette en cada clúster

Clúster Nº Individuos % del total


1 1028 51.4 %
2 601 30.05 %
3 300 15 %
4 71 3.55 %

Cuadro 8: Tamaño de los clústers en Agglomerative Clustering

Al igual que en el anterior algoritmo, el tamaño de los clústers es muy dispar, con 2 grupos muy
mayoritarios. Vamos ver la separación entre los puntos con Multi Dimensional Scaling:

Visualización de Clusters después de MDS


Cluster 1
1.00 Cluster 2
Cluster 3
Cluster 4
0.75

0.50

0.25
Dimensión 2 (MDS)

0.00

0.25

0.50

0.75

1.00
1.0 0.5 0.0 0.5 1.0
Dimensión 1 (MDS)

Figura 19: Distancia relativa entre todos los puntos (tamaño de cada punto proporcional a su ponde-
ración)

Se ve la división entre los 4 clústers. Aunque hay algunos puntos, sobretodo del clúster 2, que están
“mal” asignados a su clústers.

22
Visualizamos ahora dos dendogramas de los resultados. Ambos dendogramas parten de los 20
clústers de nivel más alto.

Dendograma Truncado

20

15

10

0
(71)
(58)
(109)
(141)
(157)
(107)
(29)
(56)
(62)
(56)
(126)
(117)
(188)
(40)
(93)
(73)
(108)
(143)
(124)
(142)
Número de puntos por nodo

Figura 20: Dendograma Truncado

1.0
0.8
0.6
0.4
0.2

16 5 14 3 9 4 6 18 0 17 13 12 1 15 8 11 19 10 2 7
0.0

cluster
edad

preocupación inflación
hijos

ahorro

situación laboral

Figura 21: Heat Dendograma

Para la segunda visualización hemos hecho la media de cada uno de los 20 clústers y lo representamos
en el mapa de calor. Esto es muy útil para destacar cómo se van uniendo los clústers en el algoritmo.
La diferencia más clara se da en la columna hijos, los clústers inferiores los forman las personas que
no conviven con ningún hijo o conviven con un hijo de muy baja edad. Por el contrario, los clústers
superiores están formados por individuos que viven con un hijo mayor.

23
Mostramos un extracto del script utilizado para mostrar el dendograma con el mapa de calor:
1 def sintetizar (X , nclusters ) :
2 agg = A g g l o m e r a t i v e C l u s t e r i n g ( n_clusters = nclusters )
3 c = agg . fit_predict ( X )
4 sinte = pd . concat ([ X , pd . DataFrame (c , index = X . index , columns =[ ’ cluster ’ ]) ] , axis
=1)
5 sinte = sinte . groupby ([ ’ cluster ’ ]) . mean ()
6 return sinte
7
8 sint = sintetizar ( X3_norm , 20)
9
10 # Agglomerative Clustering
11 agg = A g g l o m e r a t i v e C l u s t e r i n g ( n_clusters =4) . fit ( sint )
12
13 # Crear un clustermap
14 clustermap = sns . clustermap ( sint , method = ’ ward ’ , col_cluster = False , row_cluster = True ,
cmap = ’ viridis ’ , figsize =(12 , 8) )
15
16 # Agregar colores de cluster a las filas
17 clust er_colo rs = sns . color_palette ( ’ viridis ’ , n_colors = len ( set ( agg . labels_ ) ) )
18 row_colors = [ clu ster_co lors [ label ] for label in agg . labels_ ]
19 clustermap . ax_row_colors = row_colors
20
21 # Mostrar el clustermap
22 plt . title ( ’ ’)
23 plt . savefig ( ’ De nd o gr am aH e at 3 . pdf ’)
24 plt . show ()
Listing 8: Extracto del código para mostrar el resultado de MDS

24
Por último veamos la distribución de cada clúster:

Cluster 1

0.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.00
Cluster 2

0.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.00
Cluster 3

0.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.00
Cluster 4

0.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.00
edad hijos ahorro preocupación inflación situación laboral

Figura 22: Distribuciones de los clústers formados


Cluster 4

0.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.000.00 0.25 0.50 0.75 1.00
edad hijos ahorro preocupación inflación situación laboral

Figura 23: Distribución del grupo 4

Hemos notado que los clústers 1, 2, 3 y 4 exhiben una notable similitud con aquellos obtenidos
mediante el algoritmo Mean-Shift. No obstante, los miembros del quinto grupo en Mean-Shift, que eran
una minorı́a, se han distribuido entre los demás clústers.

Por lo tanto, con Agglomerative Clustering llegamos a las mismas conclusiones ya mencionadas con
Mean-Shift.

25
4. Caso de estudio 3

4.1. Descripción

En este último caso, evaluaremos la posible variación en las preferencias electorales de la población
española desde los últimos comicios. Para ello, hemos identifdicado las siguientes variables: edad,
ideologı́a, clase social, situación laboral, si votó a algún partido o no, si votarı́a o no ahora a algún
partido y si ha cambiado su voto. Estas últimas variables no están directamente disponibles en los
datos proporcionados, por lo que será necesario realizar algunas transformaciones para obtener la
información deseada. Concretamente, dado que contamos con los datos sobre el voto pasado y el voto
actual, optamos por agrupar todos los partidos como una categorı́a, y las opciones de voto en blanco,
nulo y abstención en otra.

4.2. Resultados

A continuación, presentamos las tablas con los resultados obtenidos por los distintos algoritmos de
clústering empleados:

Algoritmo Nº Clústers Tiempo (s) Silhouette Calinski-Harabasz Dunn Davies-Bouldin


K-Means 6 0.05 0.35904 809.114 0.58394 1.103
Mean-Shift 5 0.58 0.37681 555.988 0.757 1.186
DBSCAN 4 0.15 0.377 555.988 0.757 1.186
HDBSCAN 6 0.15 0.299 641.184 0.598 1.49
Agglomerative 6 0.10 0.354 787.698 0.55465 1.1089
Spectral 6 2.61 0.3568 796.384 0.757 1.1126

Cuadro 9: Resultados en el tercer caso de estudio.

Hemos utilizado los siguientes parámetros: K-Means (k=6), Mean-Shift (bandwidth=0.8), DBSCAN
(eps=0.75, min samples=50), HDBSCAN (min cluster size=100, min samples=30, cluster selection method=’eom’),
Agglomerative (n clusters=6), Spectral (n clusters=6, assign labels=’discretize’)

Para comparar gráficamente las métricas, hacemos uso de un radial plot:

Calinski-Harabasz
K-Means
Mean-Shift
DBSCAN
HDBSCAN
Agglomerative
Spectral
Silhouette

Davies-Bouldin

Nº Clústers

Tiempo (s)

Figura 24: Resultados en un gráfico radial (normalizados en el intervalo [0.3, 1.0])

26
En este caso, HDBSCAN no obtiene buenos resultados. Es curioso que las medidas obtenidas por
Mean-Shift y DBSCAN son idénticas. Sin embargo, al explorar los clústers generados, se percibe que
son iguales, salvo por la distinción de que DBSCAN ha categorizado como ruido el clúster de menor
tamaño de Mean-Shift.

Clúster Nº Individuos % del total


1 1308 65.4 %
2 281 14.05 %
3 188 9.4 %
4 161 9.05 %
5 62 3.1 %

Cuadro 10: Tamaño de los clústers en Mean-Shift

Clúster Nº Individuos % del total


1 1308 65.4 %
2 281 14.05 %
3 188 9.4 %
4 161 9.05 %
Ruido 62 3.1 %

Cuadro 11: Tamaño de los clústers en DBSCAN

27
4.2.1. Estudio de parámetros

Vamos a estudiar también cómo evoluciona el coeficiente de Silhouette y el ı́ndice de Calinski-


Harabasz para distintos valores de eps y min samples en DBSCAN y para distintos valores de as-
sign labels y n clusters en Spectral Clustering . En el caso de assign labels, este indica la estrategia
para asignar etiquetas en el espacio embedido, siendo kmeans el valor por defecto, pero puede ser
sensible a la inicialización. Por lo tanto, probaremos también con la opción discretize.

DBSCAN Parameter Tuning Heatmap (Silhouette Score) DBSCAN Parameter Tuning Heatmap (Calinski-Harabasz Index)

0.094 -0.19 -0.12 88.04242 33.39161 60.40183


0.1

0.1
0.3
500

0.098 0.23 0.12 0.068 0.06 -0.017 125.47678 179.71218 194.89131 177.67332 227.57969 145.16889
0.25

0.25
0.2
400

Calinski-Harabasz Index
Silhouette Score
0.3 0.29 0.33 0.28 0.2 0.26 0.14 0.1 254.99154 288.20859 284.14638 392.53614 329.34665 453.82482 333.47406
eps

eps
0.5

0.5
300

0.0
0.38 0.38 0.38 0.38 0.38 0.32 0.32 555.98754 555.98754 555.98754 555.98754 552.11878 576.05359 573.89172 200
0.75

0.75
0.1
100
0.37 0.27 0.36 0.32 472.58788 283.87224 586.99783 525.64610
1.0

1.0

1 10 25 50 100 200 300 1 10 25 50 100 200 300


min_samples min_samples

Figura 25: Heatmaps de Silhouette y Calinski-Harabasz para distintos valores de parámetros en DBS-
CAN

Se observa que los valores más elevados de las métricas se logran con un valor de eps de 0.75.
Este parámetro indica la distancia máxima entre dos individuos para considerar que uno está en el
vecindario del otro. En valores bajos de eps, se generan numerosos clústers, lo que resulta en métricas
bajas. Además, el parámetro min samples determina la cantidad de datos en el vecindario de un punto
para considerarlo un core point. Si este valor es alto, DBSCAN identificará clústers más densos. Los
resultados más favorables se obtienen para valores comprendidos entre 50 y 200.

28
Presentamos ahora los resultados obtenidos en Spectral Clustering

Nº Clústers Tiempo (s) Silhouette Calinski-Harabasz Davies-Bouldin


2 2.5634 0.3702 472.5879 1.0247
3 2.4541 0.3842 737.2891 1.1592
4 2.8018 0.3394 806.0927 1.1412
5 2.6824 0.3687 770.4439 1.1412
6 2.6411 0.3539 786.4150 1.0863
7 2.7727 0.3445 710.9841 1.1353
8 2.6698 0.3451 665.2760 1.1190
9 2.6872 0.3359 593.6357 1.0922
10 2.7431 0.3413 545.1675 1.0149
11 2.7359 0.3432 510.1766 0.9830
12 2.8253 0.3419 518.3956 1.0843

Cuadro 12: Medidas en Spectral Clustering con assign labels=’kmeans’ para distinto número de clúster

Nº Clústers Tiempo (s) Silhouette Calinski-Harabasz Davies-Bouldin


2 2.5583 0.3746 619.2792 1.4753
3 2.5683 0.3858 746.7912 1.1768
4 2.9342 0.3379 794.9705 1.1561
5 2.5421 0.3368 755.3664 1.1749
6 2.5347 0.3568 796.3842 1.1125
7 2.8750 0.3477 720.4264 1.1770
8 3.5059 0.3489 671.7593 1.1523
9 2.8064 0.2960 608.9398 1.2481
10 2.8547 0.3114 586.4069 1.2021
11 2.8450 0.2799 551.8066 1.1647
12 2.9570 0.2594 512.3090 1.1775

Cuadro 13: Medidas en Spectral Clustering con assign labels=’discretize’ para distinto número de
clúster

Silhouette and Davies-Bouldin Scores vs Number of Clusters Calinski-Harabasz Score vs Number of Clusters
Silhouette (kmeans) Calinski-Harabasz (kmeans)
Davies-Bouldin (kmeans) 800 Calinski-Harabasz (discretize)
1.4 Silhouette (discretize)
Davies-Bouldin (discretize)
750
1.2
700
Calinski-Harabasz Score

1.0
650
Score

0.8
600

0.6
550

0.4 500

2 4 6 8 10 2 4 6 8 10
Number of Clusters Number of Clusters

Figura 26: Evolución de las medidas en Spectral Clustering

Podemos ver que para discretize y kmeans los resultados son muy similares. Aunque generalmente
las métricas son un poco superiores para discretize. Observamos que el coeficiente de Silhouette y el
ı́ndice de Davies-Bouldin se mantienen más o menos estables para distintos valores de k. Sin embargo,
esto no ocurre para el ı́ndice de Calinski-Harabasz, en el que los valores más altos se obtienen para
k=4 y k=6.

29
4.3. Interpretación de la segmentación

En este apartado estudiaremos las agrupaciones obtenidas por DBSCAN, ya que hemos obtenido
unas métricas altas.

Comenzamos viendo los distintos valores del coeficiente para los clústers formados:
DBSCAN Silhouette

2
Cluster label

0.1 0.0 0.2 0.4 0.6 0.8 1.0


The silhouette coefficient values

Figura 27: Coeficiente de Silhouette en cada clúster

Clúster Nº Individuos % del total


1 1038 65.4 %
2 188 9.4 %
3 281 14.05 %
4 161 8.05 %
Ruido 62 1.6 %

Cuadro 14: Tamaño de los clústers en Mean-Shift

Todos los elementos tienen un coeficiente alto por lo que todos los clústers están bien formados.
Observamos que hay un grupo mayoritario con más del 50 % de la población.

Lo siguiente que vamos a visualizar será la distancia que hay entre los distintos clústers. Para ello
haremos uso de Multi Dimensional Scaling para reducir las dimensiones del problema a 2.

Visualización de Clusters después de MDS


Cluster 1
1.5 Cluster 2
Cluster 3
Cluster 4

1.0

0.5
Dimensión 2 (MDS)

0.0

0.5

1.0

1.5

1.5 1.0 0.5 0.0 0.5 1.0 1.5


Dimensión 1 (MDS)

Figura 28: Distancia relativa entre todos los puntos (tamaño de cada punto proporcional a su ponde-
ración)

30
En la gráfica anterior se ven claramente los 4 clústers diferenciados. Los dos más cercanos son el 2
y 3. Y el grupo más alejado del resto es el 4.

Ahora procederemos a representar visualmente la matriz de dispersión de los resultados obtenidos


mediante el algoritmo.



LGHRORJtD








HGDG






FODVHVRFLDO







VLWXDFLyQODERUDO

 FOXVWHU

 
 




SDUWLGRTXHYRWy






SDUWLGRTXHYRWDUtD








FDPELRBYRWR





                    
LGHRORJtD HGDG FODVHVRFLDO VLWXDFLyQODERUDO SDUWLGRTXHYRWy SDUWLGRTXHYRWDUtD FDPELRBYRWR

Figura 29: Scatter Matrix DBSCAN (cada punto es proporcional a su ponderación)

Observamos que las mayores diferencias entre los grupos se dan en los votos. Por ejemplo, el clúster
4 lo forman personas que no votaron a ningún partido y que ahora tampoco lo harı́an. En cambio, el
clúster 3 está formado por individuos que no votaron pero que ahora sı́ lo harı́an.

Debido que el grupo 1 tiene una diferencia de tamaño tan grande con respecto a los demás, en
algunos gráficos de dispersión e histogramas es difı́cil sacar conclusiones. Por lo que nos disponemos a
visualizar los histogramas de los clústers por separado:

31
Cluster 1

0.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.0
Cluster 2

0.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.0
Cluster 3

0.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.0
Cluster 4

0.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.00.0 0.5 1.0
ideología edad clase social situación laboral partido que votó partido que votaría cambio_voto

Figura 30: Distribución de los clústers

En resumen, no apreciamos una diferencia significativa en la edad, ideologı́a, clase social ni situación
laboral de los clústers obtenidos. Pero sı́ se diferencian en sus intenciones de voto. En primer lugar, el
clúster 1 son personas que mantienen su voto, votaron y votarı́an al mismo partido. Por el contrario,
el clúster 2 lo componen individuos que no votarı́an al mismo partido. En tercer lugar, las personas
pertenecientes al clúster 3 no votaron pero ahora sı́ lo harı́an. Por último, el clúster 4 son personas que
seguirı́an votando en blanco, nulo o se abstendrı́an.

Como conclusión, hay una proporción significativa de la sociedad española que mantiene su voto
(clúster 1) y otra proporción que lo cambiarı́a (clúster 2). El hecho de que el clúster 3 consista en
personas que ahora votarı́an, aunque no lo hicieron en el pasado, podrı́a reflejar un aumento en la
participación polı́tica o un cambio en la motivación para votar en este grupo, ya sea por sucesos
recientes como la guerra Israel-Hamás.

32
Vamos a intentar estudiar más en detalle el clúster 2 para intentar caracterizar mejor a las personas
que cambiarı́an su voto. Para ello, nos apoyaremos en gráficos de coordenadas paralelas [4]. Vamos a
mostrar cómo han cambiado los votos de cada uno de los partidos mayoritarios:

Figura 31: Personas que votaron a PSOE

Figura 32: Personas que votaron a PP

Figura 33: Personas que votaron a VOX

33
Figura 34: Personas que votaron a SUMAR

Viendo los gráficos anteriores, podemos llegar a algunas conclusiones interesantes sobre las personas
que han cambiado su voto. Las personas que votaron a partidos de izquierdas (PSOE y SUMAR), dis-
tribuyen su voto a más partidos diferentes. En cambio, los votantes pasados de PP y VOX, cambiarı́an
su voto a menos partidos. Eso sı́, la gran mayorı́a seguirı́a votando a otro partido mayoritario, ya que
vemos en todas las gráficas hay un número alto de lı́neas que se quedan en el intervalo [0, 1.5] (0 :
PSOE, 0.5 : PP, 1 : VOX, 1.5: SUMAR).

El código utilizado para mostrar el último gráfico de lı́neas es el siguiente. Para seleccionar las
lı́neas en las que estamos interesados debemos abrir el fichero html en el navegador y seleccionarlas
con el ratón, posteriormente podemos descargar la imagen png.
1
2 def p lo t_ li n es _a ux x (X , k , usadas ) :
3
4 df = X . copy ()
5
6 fig = px . p a r a l l e l _ c o o r d i n a t e s ( df , dimensions = usadas ,
7 color = " Cluster " ,
8 c o l o r _ c o n t i n u o u s _ s c a l e = ’ Purples ’)
9 fig . update_layout ( c o l o r a x i s _ c o l o r b a r = dict (
10 title = " Clusters " ,
11 tickvals =[ i for i in range ( k ) ] ,
12 ticktext =[ " Cluster " + str ( i + 2) for i in range ( k ) ] ,
13 lenmode = " pixels " , len =500 ,
14 ))
15
16 fig . write_html ( " parallel3 . html " )
17 # fig . write_pdf (" parallel . pdf ")
18
19 # Llama a la funcion con los parametros necesarios
20 # plot_lines (X , k , usadas )
Listing 9: Extracto del código para mostrar un gráfico de coordenadas paralelas

34
Referencias
[1] url: https://scikit-learn.org/stable/modules/clustering.html.
[2] url: https : / / towardsdatascience . com / performance - metrics - in - machine - learning -
part-3-clustering-d69550662dc6.
[3] url: https://en.wikipedia.org/wiki/Dunn_index.
[4] url: https://plotly.com/python/parallel-coordinates-plot/.

35

También podría gustarte