Análisis de Clúster (Conglomerados)

Análisis de conglomerados

1. Explique en que consiste el análisis de conglomerados.

El análisis de conglomerados (cluster analysis) es una técnica estadística que sirve para agrupar observaciones en conjuntos homogéneos. La idea central es que los elementos dentro de un mismo grupo se parezcan mucho entre sí, mientras que los grupos entre sí sean distintos.

Lo que significa que se pueden clasificar países, regiones, empresas o individuos según sus características económicas, sociales o financieras, sin necesidad de imponer categorías previas, por lo que se puede enfocar en:

Segmentación de países o regiones: agrupar economías según indicadores como PIB per cápita, inflación, desempleo, inversión extranjera o desigualdad.

Clasificación de empresas: identificar conglomerados de firmas con estructuras de costos, productividad o estrategias similares.

Agrupación de consumidores: dividir poblaciones según ingresos, hábitos de consumo o sensibilidad al precio.

Política pública: detectar territorios con problemas comunes (pobreza, desempleo, baja inversión) para diseñar políticas diferenciadas.

Cuadro comparativo

Resumen del Análisis de Clúster (Basado en PDF)
Análisis de Clúster Técnicas disponibles Ventajas Desventajas
Jerárquico:
Método que agrupa objetos basándose en su similitud. No requiere pre-especificar el número de clústeres. El resultado es una representación basada en un árbol (dendrograma). Puede ser Aglomerativo (de abajo hacia arriba) o Divisivo (de arriba hacia abajo).
  • Aglomerativo (AGNES)
  • Divisivo (DIANA)
  • Métodos de Vinculación (Linkage):
    • Ward.D / Ward.D2
    • Completo (Complete)
    • Simple (Single)
    • Promedio (Average)
    • Centroide (Centroid)
  • No requiere pre-especificar el número de clústeres.
  • Genera un dendrograma, que es una representación visual basada en árbol de los objetos.
  • Permite decidir el nivel (número de grupos) al cortar el árbol.
  • El método aglomerativo es bueno identificando clústeres pequeños; el divisivo es bueno para clústeres grandes.
  • No indica automáticamente cuántos clústeres hay.
  • El analista debe decidir dónde cortar el dendrograma para formar los clústeres.
No Jerárquico (Partitioning):
Métodos que clasifican observaciones en múltiples grupos (k) basándose en su similitud. Requieren que el analista especifique el número de clústeres (k) a generar por adelantado.
  • K-Means (K-Medias)
  • K-Medoids (PAM)
  • CLARA (Clustering Large Applications)
  • DBSCAN (Método de partición basado en densidad)
  • K-Means: Es un algoritmo muy simple y rápido. Puede manejar eficientemente datasets muy grandes.
  • PAM (K-Medoids): Es una alternativa robusta a K-Means y menos sensible al ruido y a los outliers.
  • CLARA: Adaptado para datasets muy grandes, reduce el tiempo de cómputo y el uso de RAM.
  • DBSCAN: Puede encontrar clústeres de cualquier forma e puede identificar outliers/ruido.
  • La mayoría (K-Means, PAM) requiere que el analista especifique el número de clústeres (k) por adelantado. [cite: 276, 347, 373]
  • K-Means: Sensible a la selección aleatoria inicial de los centroides.
  • K-Means: Es sensible a los outliers.
  • K-Means/PAM: Aptos para encontrar clústeres de forma esférica o convexa, pero no formas arbitrarias.
  • PAM: Puede requerir demasiada memoria o tiempo de cómputo en datasets grandes.
  • DBSCAN: Es sensible a la elección del parámetro ‘eps’, especialmente si los clústeres tienen diferentes densidades.

Fuente: elaboración propia con base en: Kassambara, A. (2017). Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning (Multivariate Analysis) (1st ed.). STHDA, disponible en: https://xsliulab.github.io/Workshop/week10/r-cluster-book.pdf.

Tecnicas

3. Describa las técnicas disponibles para realizar el análisis de clúster, tanto jerárquicas como no jerárquicas, presentadas en el cuadro anterior, incluya una explicación de la librería y sintaxis para implementarla en R.

1. Clúster de Partición (No Jerárquico) Los métodos de partición requieren que el analista especifique previamente el número de grupos (\(k\)).

A. K-Means (K-Medias): Es el método de partición más común. Clasifica las observaciones en \(k\) clústeres, asignando cada observación al centroide (media) del clúster más cercano, basándose en la distancia Euclidiana. El algoritmo opera iterativamente para minimizar la variación total dentro del clúster. Librería y Sintaxis en R: Se utiliza la función kmeans() del paquete stats (paquete base de R).

Ejemplo: kmeans(x, centers, iter.max = 10, nstart = 1)

B. K-Medoids (PAM): PAM (Partitioning Around Medoids) es una alternativa más robusta a K-Means. Utiliza medoides (observaciones reales en el clúster) en lugar de centroides. Su objetivo es minimizar la suma de las disimilitudes entre las observaciones y su medoide más cercano.

Librería y Sintaxis en R: Se utiliza la función pam() del paquete cluster.

Ejemplo: pam(x, k, metric = “euclidean”, stand = FALSE)

C. CLARA (Clustering Large Applications): Es una extensión de PAM diseñada para manejar datasets muy grandes. CLARA toma múltiples muestras aleatorias del conjunto de datos y aplica el algoritmo PAM a cada subconjunto, eligiendo la mejor partición como resultado final.

Librería y Sintaxis en R: Se utiliza la función clara() del paquete cluster.

Ejemplo: clara(x, k, metric = “euclidean”, stand = FALSE, samples = 5, pamLike = FALSE)

D. DBSCAN (Density-Based Spatial Clustering of Applications with Noise): Es un método de partición avanzado basado en densidad. Tiene la capacidad de encontrar clústeres de diferentes formas y tamaños, y puede identificar ruido u outliers en los datos. Es especialmente útil cuando los clústeres no son esféricos.

Librería y Sintaxis en R: Se implementa con el paquete dbscan en R.

2. Clúster Jerárquico El clúster jerárquico no requiere pre-especificar el número de clústeres (\(k\)). Su resultado es un dendrograma.

A. Aglomerativo (AGNES): También conocido como método bottom-up (de abajo hacia arriba). Inicia con cada objeto como su propio clúster y en cada paso, fusiona los dos clústeres más cercanos hasta que todos los objetos están en un solo clúster.

Librería y Sintaxis en R: Se usa la función agnes() del paquete cluster.

Ejemplo: res.agnes <- agnes(x=USArrests, # data matrix stand = TRUE, # Standardize the data metric = “euclidean”, # metric for distance matrix method = “ward” # Linkage method )

B. Divisivo (DIANA): También conocido como método top-down (de arriba hacia abajo). Inicia con un solo clúster grande que contiene todas las observaciones y, en cada paso, lo divide en clústeres más pequeños hasta que cada objeto está en su propio clúster.

Librería y Sintaxis en R: Se utiliza la función diana() del paquete cluster.

Ejemplo: res.diana <- diana(x=USArrests, # data matrix stand = TRUE, # standardize the data metric = “euclidean” # metric for distance matrix )

C.Métodos de Vinculación (Linkage): Se refieren a cómo se define la “cercanía” entre clústeres, algunos ejemplos son ward.D2, complete, single (simple), y average (promedio).

Librería y Sintaxis en R: Se puede usar la función base hclust() (que requiere un cálculo previo de la distancia)

Ejemplo: res.hc<-hclust(d=res.dist,method=“ward.D2”)

Ejemplos

4. Del texto: Kassambara, A. (2017). Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning (Multivariate Analysis) (1st ed.). STHDA, disponible en: https://xsliulab.github.io/Workshop/week10/r-cluster-book.pdf, desarrolle los ejemplos presentados en los capítulos: 4,5,6,7,8,9.

4. k-means

data("USArrests")
 df<-scale(USArrests)
 head(df,n=3)
##             Murder   Assault   UrbanPop         Rape
## Alabama 1.24256408 0.7828393 -0.5209066 -0.003416473
## Alaska  0.50786248 1.1068225 -1.2117642  2.484202941
## Arizona 0.07163341 1.4788032  0.9989801  1.042878388
 library(factoextra)
 fviz_nbclust(df, kmeans, method = "wss")+
 geom_vline(xintercept = 4, linetype = 2)

CÁLCULO DE CLÚSTERES K-MEANS EN R

 set.seed(123)
 km.res<-kmeans(df,4,nstart=25)
 print(km.res)
## K-means clustering with 4 clusters of sizes 8, 13, 16, 13
## 
## Cluster means:
##       Murder    Assault   UrbanPop        Rape
## 1  1.4118898  0.8743346 -0.8145211  0.01927104
## 2 -0.9615407 -1.1066010 -0.9301069 -0.96676331
## 3 -0.4894375 -0.3826001  0.5758298 -0.26165379
## 4  0.6950701  1.0394414  0.7226370  1.27693964
## 
## Clustering vector:
##        Alabama         Alaska        Arizona       Arkansas     California 
##              1              4              4              1              4 
##       Colorado    Connecticut       Delaware        Florida        Georgia 
##              4              3              3              4              1 
##         Hawaii          Idaho       Illinois        Indiana           Iowa 
##              3              2              4              3              2 
##         Kansas       Kentucky      Louisiana          Maine       Maryland 
##              3              2              1              2              4 
##  Massachusetts       Michigan      Minnesota    Mississippi       Missouri 
##              3              4              2              1              4 
##        Montana       Nebraska         Nevada  New Hampshire     New Jersey 
##              2              2              4              2              3 
##     New Mexico       New York North Carolina   North Dakota           Ohio 
##              4              4              1              2              3 
##       Oklahoma         Oregon   Pennsylvania   Rhode Island South Carolina 
##              3              3              3              3              1 
##   South Dakota      Tennessee          Texas           Utah        Vermont 
##              2              1              4              3              2 
##       Virginia     Washington  West Virginia      Wisconsin        Wyoming 
##              3              3              2              2              3 
## 
## Within cluster sum of squares by cluster:
## [1]  8.316061 11.952463 16.212213 19.922437
##  (between_SS / total_SS =  71.2 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Es posible calcular la media de cada variable por clústeres usando los datos originales:

 aggregate(USArrests, by=list(cluster=km.res$cluster), mean)
##   cluster   Murder   Assault UrbanPop     Rape
## 1       1 13.93750 243.62500 53.75000 21.41250
## 2       2  3.60000  78.53846 52.07692 12.17692
## 3       3  5.65625 138.87500 73.87500 18.78125
## 4       4 10.81538 257.38462 76.00000 33.19231

CÁLCULO DE CLÚSTERES K-MEANS EN R

 dd <- cbind(USArrests, cluster = km.res$cluster)
 head(dd)
##            Murder Assault UrbanPop Rape cluster
## Alabama      13.2     236       58 21.2       1
## Alaska       10.0     263       48 44.5       4
## Arizona       8.1     294       80 31.0       4
## Arkansas      8.8     190       50 19.5       1
## California    9.0     276       91 40.6       4
## Colorado      7.9     204       78 38.7       4

Accediendo a los resultados de la función kmeans()

# Número de clúster para cada una de las observaciones
head(km.res$cluster, 4)
##  Alabama   Alaska  Arizona Arkansas 
##        1        4        4        1
#Tamaño del clúster
km.res$size
## [1]  8 13 16 13
# Cluster means
 km.res$centers
##       Murder    Assault   UrbanPop        Rape
## 1  1.4118898  0.8743346 -0.8145211  0.01927104
## 2 -0.9615407 -1.1066010 -0.9301069 -0.96676331
## 3 -0.4894375 -0.3826001  0.5758298 -0.26165379
## 4  0.6950701  1.0394414  0.7226370  1.27693964

5. K-Medoids

Data

 data("USArrests")
 df <- scale(USArrests)
 head(df, n=3)
##             Murder   Assault   UrbanPop         Rape
## Alabama 1.24256408 0.7828393 -0.5209066 -0.003416473
## Alaska  0.50786248 1.1068225 -1.2117642  2.484202941
## Arizona 0.07163341 1.4788032  0.9989801  1.042878388
library(cluster)
 library(factoextra)
 fviz_nbclust(df, pam, method = "silhouette")+
 theme_classic()

Clustering PAM en informática

pam.res<-pam(df,2)
 print(pam.res)
## Medoids:
##            ID     Murder    Assault   UrbanPop       Rape
## New Mexico 31  0.8292944  1.3708088  0.3081225  1.1603196
## Nebraska   27 -0.8008247 -0.8250772 -0.2445636 -0.5052109
## Clustering vector:
##        Alabama         Alaska        Arizona       Arkansas     California 
##              1              1              1              2              1 
##       Colorado    Connecticut       Delaware        Florida        Georgia 
##              1              2              2              1              1 
##         Hawaii          Idaho       Illinois        Indiana           Iowa 
##              2              2              1              2              2 
##         Kansas       Kentucky      Louisiana          Maine       Maryland 
##              2              2              1              2              1 
##  Massachusetts       Michigan      Minnesota    Mississippi       Missouri 
##              2              1              2              1              1 
##        Montana       Nebraska         Nevada  New Hampshire     New Jersey 
##              2              2              1              2              2 
##     New Mexico       New York North Carolina   North Dakota           Ohio 
##              1              1              1              2              2 
##       Oklahoma         Oregon   Pennsylvania   Rhode Island South Carolina 
##              2              2              2              2              1 
##   South Dakota      Tennessee          Texas           Utah        Vermont 
##              2              1              1              2              2 
##       Virginia     Washington  West Virginia      Wisconsin        Wyoming 
##              2              2              2              2              2 
## Objective function:
##    build     swap 
## 1.441358 1.368969 
## 
## Available components:
##  [1] "medoids"    "id.med"     "clustering" "objective"  "isolation" 
##  [6] "clusinfo"   "silinfo"    "diss"       "call"       "data"

Las clasificaciones de puntos en los datos originales:

 dd <- cbind(USArrests, cluster = pam.res$cluster)
 head(dd, n=3)
##         Murder Assault UrbanPop Rape cluster
## Alabama   13.2     236       58 21.2       1
## Alaska    10.0     263       48 44.5       1
## Arizona    8.1     294       80 31.0       1

Accediendo a los resultados de la función pam()

# Cluster medoids: New Mexico, Nebraska
 pam.res$medoids
##                Murder    Assault   UrbanPop       Rape
## New Mexico  0.8292944  1.3708088  0.3081225  1.1603196
## Nebraska   -0.8008247 -0.8250772 -0.2445636 -0.5052109
# numeros de cluster
 head(pam.res$clustering)
##    Alabama     Alaska    Arizona   Arkansas California   Colorado 
##          1          1          1          2          1          1

6. CLARA: Agrupamiento de Grandes Aplicaciones

 set.seed(1234)
 # Gnerar 500 objetos divididos en 2 clusters.
 df <- rbind(cbind(rnorm(200,0,8), rnorm(200,0,8)),
 cbind(rnorm(300,50,8), rnorm(300,50,8)))
 # Espificar los nombres de columnas y filas
 colnames(df) <- c("x", "y")
 rownames(df) <- paste0("S", 1:nrow(df))
 # Vista previa de los datos:
 head(df, nrow = 6)
##             x        y
## S1  -9.656526 3.881815
## S2   2.219434 5.574150
## S3   8.675529 1.484111
## S4 -18.765582 5.605868
## S5   3.432998 2.493448
## S6   4.048447 6.083699

Estimando el número óptimo de clústeres

library(cluster)
 library(factoextra)
 fviz_nbclust(df, clara, method = "silhouette")+
 theme_classic()

Se calcula el algoritmo PAM con k = 2:

 clara.res <- clara(df, 2, samples = 50, pamLike = TRUE)
 print(clara.res)
## Call:     clara(x = df, k = 2, samples = 50, pamLike = TRUE) 
## Medoids:
##              x         y
## S121 -1.531137  1.145057
## S455 48.357304 50.233499
## Objective function:   9.87862
## Clustering vector:    Named int [1:500] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
##  - attr(*, "names")= chr [1:500] "S1" "S2" "S3" "S4" "S5" "S6" "S7" ...
## Cluster sizes:            200 300 
## Best sample:
##  [1] S37  S49  S54  S63  S68  S71  S76  S80  S82  S101 S103 S108 S109 S118 S121
## [16] S128 S132 S138 S144 S162 S203 S210 S216 S231 S234 S249 S260 S261 S286 S299
## [31] S304 S305 S312 S315 S322 S350 S403 S450 S454 S455 S456 S465 S488 S497
## 
## Available components:
##  [1] "sample"     "medoids"    "i.med"      "clustering" "objective" 
##  [6] "clusinfo"   "diss"       "call"       "silinfo"    "data"

Las clasificaciones de puntos en los datos originales:

 dd <- cbind(df, cluster = clara.res$cluster)
 head(dd, n=4)
##             x        y cluster
## S1  -9.656526 3.881815       1
## S2   2.219434 5.574150       1
## S3   8.675529 1.484111       1
## S4 -18.765582 5.605868       1

Resultados

clara.res$medoids
##              x         y
## S121 -1.531137  1.145057
## S455 48.357304 50.233499
 # Clustering
 head(clara.res$clustering,10)
##  S1  S2  S3  S4  S5  S6  S7  S8  S9 S10 
##   1   1   1   1   1   1   1   1   1   1

7. Agrupamiento Aglomerativo

 # Data
 data("USArrests")
 df <- scale(USArrests)
 head(df, nrow = 6)
##                Murder   Assault   UrbanPop         Rape
## Alabama    1.24256408 0.7828393 -0.5209066 -0.003416473
## Alaska     0.50786248 1.1068225 -1.2117642  2.484202941
## Arizona    0.07163341 1.4788032  0.9989801  1.042878388
## Arkansas   0.23234938 0.2308680 -1.0735927 -0.184916602
## California 0.27826823 1.2628144  1.7589234  2.067820292
## Colorado   0.02571456 0.3988593  0.8608085  1.864967207
 # Calculo de la matriz de similitud
 res.dist <- dist(df, method = "euclidean")
as.matrix(res.dist)[1:6, 1:6]
##             Alabama   Alaska  Arizona Arkansas California Colorado
## Alabama    0.000000 2.703754 2.293520 1.289810   3.263110 2.651067
## Alaska     2.703754 0.000000 2.700643 2.826039   3.012541 2.326519
## Arizona    2.293520 2.700643 0.000000 2.717758   1.310484 1.365031
## Arkansas   1.289810 2.826039 2.717758 0.000000   3.763641 2.831051
## California 3.263110 3.012541 1.310484 3.763641   0.000000 1.287619
## Colorado   2.651067 2.326519 1.365031 2.831051   1.287619 0.000000

Vinculación

res.hc<-hclust(d=res.dist,method="ward.D2")

Dendrograma

 library("factoextra")
 fviz_dend(res.hc,cex=0.5)

8. Comparando Dendrogramas

df <- scale(USArrests)
 set.seed(123)
 ss <- sample(1:50, 10)
 df <- df[ss,]

Comparando dendrogramas

library(dendextend)
 res.dist <- dist(df, method = "euclidean")
 hc1 <- hclust(res.dist, method = "average")
 hc2 <- hclust(res.dist, method = "ward.D2")
 # Crear dos dendogramas
 dend1 <- as.dendrogram (hc1)
 dend2 <- as.dendrogram (hc2)
 # Crear una lista para guardar los dendogramas
 dend_list <- dendlist(dend1, dend2)

Comparación visual de dos dendrogramas

 tanglegram(dend1,dend2)

9. Visualización de Dendrogramas

# Dta
 data(USArrests)
  dd <- dist(scale(USArrests), method = "euclidean")
 hc <- hclust(dd, method = "ward.D2")
 fviz_dend(hc, k=4,
 cex = 0.5,
 k_colors = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
 color_labels_by_k = TRUE,
 ggthemes=theme_gray()
 )