MÉTODOS PARA EL ANÁLISIS ECONÓMICO

TEMA DE INVESTIGACIÓN: ANÁLISIS DE CLÚSTER (CONGLOMERADOS)

1. Explicacion analisis de conglomerados.

El análisis de conglomerados es una técnica de aprendizaje no supervisado cuyo objetivo es agrupar un conjunto de objetos u observaciones en grupos o “conglomerados”, de manera que los elementos dentro de un mismo grupo sean más similares entre sí que con los objetos pertenecientes a otros grupos. Esta lógica de agrupamiento—basada en la similitud interna y la heterogeneidad externa—constituye el principio fundamental del clustering A. Kassambara (, 2017) .

Según Kassambara (2017), el análisis de conglomerados implica tres etapas principales:

Medir la similitud o disimilitud entre las observaciones mediante una métrica de distancia adecuada.

Aplicar un algoritmo de agrupamiento, ya sea jerárquico o no jerárquico, para estructurar los datos en grupos.

Interpretar los conglomerados, identificando patrones comunes dentro de cada grupo y diferencias relevantes entre ellos.

El análisis de conglomerados busca revelar estructuras ocultas o patrones naturales presentes en los datos sin utilizar información previa ni etiquetas de clasificación. En este sentido, su propósito central es descubrir, resumir y comprender la heterogeneidad de los datos mediante la formación de conglomerados que sean internamente homogéneos y externamente heterogéneos A. Kassambara (, 2017) .

2. Cuadro comparativo

Resumen análisis de clúster

Análisis de Clúster

Definición

Técnicas disponibles

Ventajas

Desventajas

 

 

 

 

Jerárquico

Es un método que construye una estructura incremental de agrupamiento mediante la aplicación repetida de medidas de proximidad entre observaciones.

 

El proceso genera un dendograma, que representa relaciones jerárquicas entre los objetos y permite identificar clústers a diferentes niveles.

Métodos de enlace (linkage methods):

-          Single linkage (puente más corto)

 

-          Complete linkage (puente más largo)

 

-          Average linkage (UPGMA)

 

-          Centroid linkage

 

-          Ward´s method (minimiza varianza)

 

Métodos aglomerativos vs. divisivos

-          No requiere definir el número de clústers (K). Se elige visualmente según el dendograma y la distancia de corte.

-          El dendograma permite interpretar la estructura subyacente de los datos, revelando patrones, subgrupos y niveles de similitud.

-          Flexibilidad para diferentes formas de clúster, dependiendo del método de enlace.

-          Habilidad para trabajar con datos mixtos usando distancias apropiadas (ej. Gower)

-          Útil para análisis exploratorio, especialmente cuando no existe hipótesis clara sobre el número de grupos.

-          Costo computacional alto, ya que requiere calcular una matriz de distancias completas (n x n). Kassambara enfatiza que no es recomendable para “n” muy grandes.

-          Los resultados dependen fuertemente del método de enlace y de la métrica de distancia. (distintas combinaciones = estructuras radicalmente diferentes).

-          El proceso es irreversible: una vez que dos clústeres se unen, no pueden separarse.

-          Puede ser inestable frente a outliers.

-          Sensibilidad elevada al reescalamiento de variables.

 

 

No Jerárquico

 

 

El clúster no jerárquico (o particional) es un conjunto de métodos que asignan directamente cada observación a uno de K clústeres definidos previamente.

-       K-Means: El algoritmo más conocido; usa medias (centroides). Requiere datos numéricos continuos.

-       K-Medoids (PAM – Partitioning Around Medoids): Más robusto que K-means, usa observaciones reales como centros. Ideal con outliers.

-       CLARA: Versión eficiente de PAM para bases grandes; trabaja con muestreos.

-       K-Modes / K-Prototypes: para datos categóricos o mixtos.

-       Fuzzy C-Means: Permite pertenencia simultánea a varios clústeres.

-          Altamente eficientes con grandes bases de datos.
K-means es uno de los métodos más rápidos en clustering.

-          Resultados más compactos y claros, especialmente con K-means o Ward.

-          Algoritmos iterativos que pueden reclasificar observaciones, mejorando la calidad final del agrupamiento.

-          Fáciles de interpretar, especialmente mediante centroides o medoids.

-          Disponibilidad de variaciones robustas (PAM, CLARA, K-prototypes).

-          Flexibles para grandes volúmenes de datos, donde los jerárquicos fallan.

 

-          Requiere especificar K antes de iniciar.
Es una de las limitaciones teóricas más importantes.

-       Puede converger en soluciones locales, no óptimas, especialmente K-means.

-          Sensibles a outliers, sobre todo K-means.

-          Supone clústeres convexos y de tamaño similar, lo que no siempre es realista.

-          Dependencia del reescalamiento.
Kassambara recomienda estandarización antes de aplicar K-means.

 

 

 

Fuente:Elaboración propia con base en Kassambara (2017)

3. Técnicas disponibles para realizar análisis de clúster (jerárquicas /no jerárquicas)

El análisis de clúster permite agrupar observaciones según su similitud. Kassambara (2017) distingue dos grandes familias de técnicas:

Métodos jerárquicos

Métodos no jerárquicos (o particionales)

A continuación se describen ambos tipos, sus variantes principales y cómo se implementan en R, incluyendo librerías recomendadas por Kassambara: stats, cluster, factoextra, dendextend.

3.1 Métodos jerárquicos

a) Single Linkage

Fusiona clústeres según la menor distancia entre pares de puntos.

  • Tiende a producir “chains” (efecto cadena).

b) Complete Linkage

Fusiona según la mayor distancia entre puntos de los clústeres.

  • Produce clústeres compactos.

c) Average Linkage

Utiliza el promedio de distancias entre todos los puntos de dos clústeres.

  • Balance entre single y complete linkage.

d) Centroid Linkage

Fusiona clústeres según la distancia entre sus centroides.

  • Puede generar inversión (inconsistencias en el dendrograma).

e) Método de Ward

Minimiza la varianza dentro de cada clúster.

  • Produce clústeres muy compactos y es recomendado por Kassambara.

3.1.1 Librerías y sintaxis en R

Cálculo de matriz de distancias dist_matrix <- dist(df, method = “euclidean”)

Clustering jerárquico hc <- hclust(dist_matrix, method = “ward.D2”)

Dendrograma plot(hc, hang = -1)

Corte del dendrograma para obtener k clústeres clusters <- cutree(hc, k = 4)

Visualización con factoextra library(factoextra) fviz_dend(hc, k = 4, rect = TRUE)

Personalización avanzada con dendextend library(dendextend) dend <- as.dendrogram(hc) dend %>% color_branches(k = 4) %>% plot()

3.2 Métodos no jerarquicos

a) K-means

  • Utiliza centroides (promedios).
  • Requiere datos numéricos.
  • Muy rápido.
  • Sensible a outliers y al escalado.

b) K-medoids (PAM – Partitioning Around Medoids)

  • Usa medoids, que son observaciones reales.
  • Mucho más robusto que K-means.

c) CLARA (Clustering Large Applications)

  • Versión de PAM para bases muy grandes.
  • Realiza muestreos y aplica PAM sobre ellos.

d) K-modes / K-prototypes

  • Para datos categóricos (K-modes).
  • Para datos mixtos (K-prototypes).

e) Fuzzy C-Means

  • Una observación puede pertenecer parcialmente a varios clústeres.

3.2.1 Librerías y sintaxis en R

K-means (librería: stats)

K-means (librería: stats) set.seed(123) km <- kmeans(df, centers = 3, nstart = 25) km$cluster

Visualización fviz_cluster(km, data = df)

PAM / CLARA (librería: cluster)

PAM library(cluster) pam_res <- pam(df, k = 3) fviz_cluster(pam_res, data = df)

CLARA clara_res <- clara(df, k = 3) fviz_cluster(clara_res, data = df)

4. Desarrollo ejemplos de los capitulos 4,5,6,7,8, y 9 (Kassambara)

Capitulo 4: Agrupamiento K-Means

Calcular la agrupacion de k-medias en R.

Datos

Carga de datos utilizando, data “USArrests”

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

Paquetes y funciones de R requeridos.

library(factoextra)

Estimacion del numero optimo de conglomerados

library(factoextra)
fviz_nbclust(df, kmeans, method = "wss") +
geom_vline(xintercept = 4, linetype = 2)

El grafico anterior representa la varianza dentro de los grupos. Disminuye a medida que k aumenta, pero se puede ver una curva (o “codo”) en k = 4.Esta curva indica que los grupos adicionales mas alla del cuarto tienen poco valor. En la siguiente seccion, clasificaremos las observaciones en 4 racimos.

Calculo de la agrupacion en clusteres de k-medias

El codigo R a continuacion realiza la agrupacion K-medias con K=4

# Calcule k-means con k = 4
set.seed(123)
km.res <- kmeans(df, 4, nstart = 25)
# Imprime los resultado
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"

La salida impresa muestra:

  • Las medias o centros de los clusteres : una matriz cuya fila son el numero de cluster(1 a 4) y las columnas son las variables.

  • El vector de agrupamiento: un vector de enteros(de 1 a k) que indica el cluster al que se asigna cada punto.

Calculo de la media de cada variable por conglomerados utilizando 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

Si desea agregar las clasificaciones de puntos a los datos originales, use esto:

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

Acceso a los resultados de la funcion kmeans()

#Numero de cluster para cada una de las observaciones
km.res$cluster
##        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
head(km.res$cluster, 4)
##  Alabama   Alaska  Arizona Arkansas 
##        1        4        4        1
#Tamaño del cluster
km.res$size
## [1]  8 13 16 13
#Cluster significa
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

Visualizacion de clusteres k-means

fviz_cluster(km.res,data = df,
             palette = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
             ellipse.type = "euclid",
             star.plot = TRUE,
             repel = TRUE,
             ggtheme = theme_minimal())

Capitulo 5: K-Medoids

Calculo de PAM en R

Datos

data("USArrests") # Cargar el conjunto de datos
df <- scale(USArrests) # Escalar los datos
head(df, n = 3) # Ver las primeras 3 filas de los datos
##             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

Estimacion del numero optimo de cluster

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

A partir del grafico el numero sugerido de clusters es 2.

Calculo de la agrupacion PAM

El siguiente código R calcula el algoritmo PAM con k = 2:

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"

La salida impresa muestra: • Los medoides del clúster: una matriz, cuyas filas son los medoides y las columnas son variables • El vector de agrupamiento: un vector de números enteros (de 1: k) que indica el grupo al que se asigna cada punto.

Si desea agregar las clasificaciones de puntos a los datos originales, use esto:

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

Acceso a los resultados de la funcion PAM

La funcion pam() devuelve un objeto de clase pam cuyos componentes incluyen: • Medoides : objetos que representan grupos(clusteres) • Clustering : un vector que contiene el numero de agrupacion de cada objeto

Se puede acceder a estos componentes de la siguiente manera:

# Medoides de cluster: Nuevo 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
# Números de cluster
head(pam.res$clustering)
##    Alabama     Alaska    Arizona   Arkansas California   Colorado 
##          1          1          1          2          1          1

Visualizacion de clusteres PAM

fviz_cluster(pam.res,
             palette = c("#00AFBB", "#FC4E07"),#paleta de colores
             ellipse.type = "t",#Eclipse de concentracion
             repel = TRUE,#Evitar la superposicion de etiquetas
             ggtheme = theme_classic())

Capitulo 6: CLARA- Agrupamiento de aplicaciones grandes

Calculo de CLARA en R

Formato y preparacion de datos

Para calcular el algoritmo CLARA en R,los datos deben prepararse como se indica en el capitulo 2. Aqui generaremos un conjunto de datos aleatorios. Para que el resultado sea reproducible, comenzamos utilizando la función set.seed ().

set.seed(1234)
#Generar 500 objetos, divididos en 2 grupos
df <- rbind(cbind(rnorm(200, 0, 8), rnorm(200, 0, 8)),
            cbind(rnorm(300, 50, 8), rnorm(300, 50, 8)))
#Especificar nombres de filas y columnas
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

Paquetes y funciones de R necesarios

library(cluster)
library(factoextra)

Estimacion del numero optimo de clusteres

Para estimar el numero optimo de clusteres en sus datos, es posible utilizar el metodo de silueta promedio,como se describe en el capitulo de agrupamiento de PAM (Capítulo 5). La function fviz_nbclust () [ paquete factoextra ] proporciona una solucion para facilitar este paso

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

A partir del gráfico, el número sugerido de grupos es 2.

Calculo de CLARA

El codigo R que se muestra a continuacion, calcula el algoritmo PAM con k = 2:

#Calculo de CLARA
clara.res <- clara(df, 2, samples = 50, pamLike = TRUE)
#Imprime los componentes de clara.res
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"

La salida de la función clara( ) incluye los siguientes componentes:

  • medoides: Objetos que representan clusteres(grupos)

  • agrupamiento: Un vector que contiene el numero de grupo de cada objeto

  • muestra: Etiquetas o numeros de caso de las observaciones en la mejor muestra, es decir, la muestra utilizada por el algoritmo clara para la particion final.

Si desea agregar las clasificaciones de puntos a los datos originales, utilize lo siguiente:

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

Puede acceder a los resultados devueltos por clara () de la siguiente manera:

# Medoides
clara.res$medoids
##              x         y
## S121 -1.531137  1.145057
## S455 48.357304 50.233499
# Agrupacion
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

Los medoides son S121, S455

Visualizacion de grupos CLARA

Para visualizar los resultados de la particion, usaremos la funcion fviz_cluster () [el paquete factoextra].

fviz_cluster(
  clara.res,
  palette = c("#00AFBB", "#FC4E07"),
  # color palette
  ellipse.type = "t",
  # Concentration ellipse
  geom = "point",
  pointsize = 1,
  ggtheme = theme_classic()
)

Capitulo 7: Agrupamiento aglomerativo

Estructura y preparacion de datos

# Cargar los datos
data("USArrests")
# Estandarizar los datos
df <- scale(USArrests)
# Mostrar las primeras 6 filas
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

Medidas de similitud

# Calcule la matriz de disimilitud
# df = los datos estandarizados
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

Vinculacion

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

Dendrograma

#  cex: tamaño de etiqueta
library("factoextra")
fviz_dend(res.hc, cex = 0.5)

Verificar el arbol del cluster

# Calcule la distancia cophentic
res.coph <- cophenetic(res.hc)
# Correlacion entre distancia cofenetica y
# la distancia original
cor(res.dist, res.coph)
## [1] 0.6975266

Ejecute la funcion hclust () nuevamente usando el metodo de vinculacion promedio. A continuacion, llame cophenetic () para evaluar la solucion de agrupamiento.

res.hc2 <- hclust(res.dist, method = "average")
cor(res.dist, cophenetic(res.hc2))
## [1] 0.7180382

Dividir el dendrograma en diferentes grupos

# Dividir el arbol en 4 grupos
grp <- cutree(res.hc, k = 4)
head(grp, n = 4)
##  Alabama   Alaska  Arizona Arkansas 
##        1        2        2        3
# Numero de miembros en cada grupo
table(grp)
## grp
##  1  2  3  4 
##  7 12 19 12
# Obtener los nombres de los miembros del grupo 1
rownames(df)[grp == 1]
## [1] "Alabama"        "Georgia"        "Louisiana"      "Mississippi"   
## [5] "North Carolina" "South Carolina" "Tennessee"

El resultado de los cortes se puede visualizar facilmente utilizando la funcion fviz_dend() [en factoextra]

#Dividir en 4 grupos y colorear por grupos
fviz_dend(
  res.hc,k = 4,#Cortar en 4 grupos
  cex = 0.5,#Tamaño de la etiqueta
  k_colors = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
  color_labels_by_k = TRUE,#Colorer etiquetas por grupos
  rect = TRUE #Agregar rectangulo alrededor de los grupos
)

Usando la funcion fviz_cluster () [in factoextra], tambien podemos visualizar el resultado en un diagrama de dispersion. Las observaciones estan representadas por puntos en la grafica, usando el metodo de componentes principales. Se dibuja un marco alrededor de cada grupo.

fviz_cluster(
  list(data = df, cluster = grp),
  palette = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
  ellipse.type = "convex",
  # Elipse de concentración
  repel = TRUE,
  # # Evite el trazado excesivo de etiquetas (lento)
  show.clust.cent = FALSE,
  ggtheme = theme_minimal()
)

Paquete Cluster R

Las funciones se pueden ejecutar de la siguiente manera:

library("cluster")
#Anidacion aglomerativa (agrupacion jerarquica)
res.agnes <- agnes(x = USArrests,#matriz de datos
                   stand = TRUE,#Estandarizar los datos
                   metric = "euclidean",#metrica para matriz de distancia
                   method = "ward" # Metodo de vinculacion
                   )

# Agrupacion de analisis visual
res.diana <- diana(x = USArrests, # matriz de datos
                   stand = TRUE, # estandarizar los datos
                   metric = "euclidean" # metrica para matriz de distancia
                   )

Despues de ejecutar agnes () y diana (), puede usar la funcion fviz_dend () [in factoextra] para visualizar la salida:

fviz_dend(res.agnes, cex = 0.6, k = 4)

Capitulo 8: Comparacion de dendrogramas

Preparacion de datos

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

Comparacion de dendrogramas

library(dendextend)
# Calcular la matriz de distancias
res.dist <- dist(df, method = "euclidean")
# Calcule 2 agrupaciones jerárquicas
hc1 <- hclust(res.dist, method = "average")
hc2 <- hclust(res.dist, method = "ward.D2")
# Crear dos dendogramas
dend1 <- as.dendrogram (hc1)
dend2 <- as.dendrogram (hc2)
# Crea una lista para contener dendrogramas
dend_list <- dendlist(dend1, dend2)

Comparacion visual de dos dendrogramas

Dibuja un tanglegrama:

tanglegram(dend1, dend2)

Personalizar el tanglegrama usando muchas otras opciones como se muestra a continuacion:

tanglegram(dend1, dend2,
highlight_distinct_edges = FALSE, #Desactivar lineas discontinuas
common_subtrees_color_lines = FALSE, #Desactivar colores de linea
common_subtrees_color_branches = TRUE, #Colorear ramas comunes
main = paste("entanglement =", round(entanglement(dend_list), 2))
)

Matriz de correlacion entre una lista de dendrogramas

# Matriz de correlacion cofenetica
cor.dendlist(dend_list, method = "cophenetic")
##           [,1]      [,2]
## [1,] 1.0000000 0.9925544
## [2,] 0.9925544 1.0000000
#Matriz de correlacion de Baker
cor.dendlist(dend_list, method = "baker")
##           [,1]      [,2]
## [1,] 1.0000000 0.9895528
## [2,] 0.9895528 1.0000000

La correlacion entre dos arboles tambien se puede calcular de la siguiente manera:

# Coeficiente de correlacion cofenetica
cor_cophenetic(dend1, dend2)
## [1] 0.9925544
# Coeficiente de correlacion de Baker
cor_bakers_gamma(dend1, dend2)
## [1] 0.9895528

Tambien es posible comparar simultaneamente varios dendrogramas. Se utiliza un operador de encadenamiento %>% para ejecutar varias funciones al mismo tiempo. Es util para simplificar el codigo:

#Crea múltiples dendrogramas encadenando
dend1 <- df %>% dist %>% hclust("complete") %>% as.dendrogram
dend2 <- df %>% dist %>% hclust("single") %>% as.dendrogram
dend3 <- df %>% dist %>% hclust("average") %>% as.dendrogram
dend4 <- df %>% dist %>% hclust("centroid") %>% as.dendrogram
#Calcular matriz de correlacion
dend_list <- dendlist("Complete" = dend1,"Single" = dend2,
                      "Average" = dend3,"Centroid" = dend4)
cors <- cor.dendlist(dend_list)
#Imprimir matriz de correlacion
round(cors, 2)
##          Complete Single Average Centroid
## Complete     1.00   0.46    0.45     0.30
## Single       0.46   1.00    0.23     0.17
## Average      0.45   0.23    1.00     0.31
## Centroid     0.30   0.17    0.31     1.00
# Visualice la matriz de correlacion usando el paquete corrplot
library(corrplot)
corrplot(cors, "pie", "lower")

Capitulo 9: Visualizacion de dendrodramas

Comenzamos calculando el agrupacion jerarquico utilizando los conjuntos de datos de USArrests:

#Cargar datos
data(USArrests)
#Calcular distancias y agrupamiento jerarquico
dd <- dist(scale(USArrests), method = "euclidean")
hc <- hclust(dd, method = "ward.D2")

Para crear un dendrograma basico, escriba lo siguiente:

library(factoextra)
fviz_dend(hc, cex = 0.5)

Puede usar los argumentos main, sub, xlab, ylab para cambiar los titulos de los graficos de la siguiente manera:

fviz_dend(hc, cex = 0.5,
main = "Dendrogram - ward.D2",
xlab = "Objects", ylab = "Distance", sub = "")

Para dibujar un dendrograma horizontal, escriba lo siguiente:

fviz_dend(hc, cex = 0.5, horiz = TRUE)

Tambien es posible cortar el arbol a una altura determinada para particionar los datos en multiples grupos, como se describe en el capitulo anterior: Agrupamiento jerarquico (Capitulo 7). En este caso, es posible colorear las ramas por grupos y añadir un rectangulo alrededor de cada grupo. Por Ejemplo:

fviz_dend(hc, k = 4, #Dividir en cuatro grupos 
cex = 0.5, # Tamaño de etiqueta
k_colors = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
color_labels_by_k = TRUE, #Colorear etiquetas por grupos
rect = TRUE, #Agregar un rectangulo alrededor del grupo
rect_border = "jco",
rect_fill = TRUE)

Para cambiar el tema del grafico, use el argumento ggtheme, cuyos valores permitidos incluyen los temas oficiales de ggplot2 [theme_gray (), theme_bw (), theme_minimal (), theme_classic (), theme_void ()] o cualquier otro tema de ggplot2 definido por el usuario.

fviz_dend(hc, k = 4, #Dividir en cuatro grupos
cex = 0.5, #tamaño de etiqueta
k_colors = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
color_labels_by_k = TRUE, #Colorear etiquetas por grupos
ggtheme = theme_gray() #Cambiar tema
)

Si desea dibujar un dendrograma horizontal con un rectangulo alrededor de los grupos, use esto:

fviz_dend(hc,k = 4,cex = 0.4,horiz = TRUE,k_colors = "jco",
          rect = TRUE,rect_border = "jco",rect_fill = TRUE)

Ademas, puede trazar un dendrograma circular usando la opcion type = “circular.”

fviz_dend(hc,cex = 0.5,k = 4,
          k_colors = "jco",type = "circular")

Para graficar un arbol filogenetico, use type = “phylogenic” y repel = TRUE (para evitar que las etiquetas se superpongan). Esta funcionalidad requiere el paquete igraph de R. Asegúrese de que este instalado antes de escribir el siguiente código de R.

require("igraph")
## Cargando paquete requerido: igraph
## Warning: package 'igraph' was built under R version 4.4.3
## 
## Adjuntando el paquete: 'igraph'
## The following objects are masked from 'package:stats':
## 
##     decompose, spectrum
## The following object is masked from 'package:base':
## 
##     union
fviz_dend(hc, k = 4, k_colors = "lancet",
type = "phylogenic", repel = TRUE)

La estructura predeterminada para los arboles filogeneticos es «layout.auto». Los valores permitidos son: c(“layout.auto”, “layout_with_drl”, “layout_as_tree”, “layout.gem”, “layout.mds”,“layout_with_lgl”). Para obtener más informacion sobre estas estructuras, consulte la documentacion del paquete igraph de R.

Probemos con phylo.layout = “layout.gem”:

require("igraph")
fviz_dend(hc, k = 4, #Dividir en cuatro grupos
k_colors = "jco",
type = "phylogenic", repel = TRUE,
phylo_layout = "layout.gem")

Caso de dendrograma con conjuntos de datos grandes

Ampliacion del dendrograma

fviz_dend(hc, xlim = c(1, 20), ylim = c(1, 8))

Graficacion de un subarbol de dendrogramas

Corte el dendrograma y visualice la version truncada

#Cree una grafica del dendograma completo,
#y extraiga los datos del dendrograma
dend_plot <- fviz_dend(hc,k = 4,
                       cex = 0.5,
                       k_colors = "jco")
dend_data <-attr(dend_plot, "dendrogram") #Extraer datos del dendrograma

#Cortar el dendrograma a la altura h= 10
dend_cuts <- cut(dend_data, h = 10)
#Visualizar la version truncada que contiene
#dos ramas
fviz_dend(dend_cuts$upper)

#Graficar el dendrograma completo
print(dend_plot)

#Graficar el subarbol 1
fviz_dend(dend_cuts$lower[[1]], main = "Subtree 1")

#Graficar el  subarbol 2
fviz_dend(dend_cuts$lower[[2]], main = "Subtree 2")

Tambien puede trazar arboles circulares de la siguiente manera:

fviz_dend(dend_cuts$lower[[2]], type = "circular")

Guardar un dendrograma en una pagina PDF grande

pdf("dendrogram.pdf", width=30, height=15) 
p <- fviz_dend(hc, k = 4, cex = 1, k_colors = "jco" ) 
print(p)
dev.off()
## png 
##   2

Manipulacion de dendogramas usando dendextend

Codigo R estandar para crear un dendrograma:

data <- scale(USArrests)
dist.res <- dist(data)
hc <- hclust(dist.res, method = "ward.D2")
dend <- as.dendrogram(hc)
plot(dend)

Codigo R para crear un dendrograma usando un operador de encadenamiento:

library(dendextend)
dend <- USArrests[1:5, ] %>% #datos
  scale %>% #Escala de datos
  dist %>% #calcular una matriz de distancia,
  hclust(method = "ward.D2") %>% #Agrupamiento jerarquico
  as.dendrogram #Convierte el objeto en un dendrograma.
plot(dend)

Funciones para personalizar dendrogramas: La funcion set() [del paquete dendextend] permite modificar los parametros de un dendrograma. El formato es:

set(object, what, value)

Ejemplos:

library(dendextend)
# 1.Crea un dendrograma personalizado
mycols <- c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07")
dend <- as.dendrogram(hc) %>%
  set("branches_lwd", 1) %>% # Ancho de linea de ramas
  set("branches_k_color", mycols, k = 4) %>% # Colorea ramas por grupos
  set("labels_colors", mycols, k = 4) %>% # Etiquetas de color por grupos
  set("labels_cex", 0.5) # Cambiar el tamaño de la etiqueta

# 2. Crea una trama
fviz_dend(dend)

5. Aplicación

Ejemplo de aplicación del Análisis de Clúster.

Caso: Diseño de un plan de segmentación de clientes

El objetivo de este caso es ofrecer una vision integrada de los pasos que requiere la aplicacion de un análisis de conglomerados. En este ejercicio aplicaremos el procedimiento al dataset Customer Personality Analysis (Kaggle), con el objetivo de identificar segmentos de clientes con perfiles de consumo y comportamiento similares para diseñar estrategias comerciales diferenciadas.

Carga de Datos

library(readr)
library(dplyr)
library(tidyverse)
library(MASS)
library(knitr)
library(kableExtra)
library(factoextra)


Customer_Personality <- read_delim("C:/Users/HP/Downloads/Customer_Personality.csv", 
    delim = "\t", escape_double = FALSE, 
    trim_ws = TRUE)

head(Customer_Personality)
## # A tibble: 6 × 29
##      ID Year_Birth Education  Marital_Status Income Kidhome Teenhome Dt_Customer
##   <dbl>      <dbl> <chr>      <chr>           <dbl>   <dbl>    <dbl> <chr>      
## 1  5524       1957 Graduation Single          58138       0        0 04-09-2012 
## 2  2174       1954 Graduation Single          46344       1        1 08-03-2014 
## 3  4141       1965 Graduation Together        71613       0        0 21-08-2013 
## 4  6182       1984 Graduation Together        26646       1        0 10-02-2014 
## 5  5324       1981 PhD        Married         58293       1        0 19-01-2014 
## 6  7446       1967 Master     Together        62513       0        1 09-09-2013 
## # ℹ 21 more variables: Recency <dbl>, MntWines <dbl>, MntFruits <dbl>,
## #   MntMeatProducts <dbl>, MntFishProducts <dbl>, MntSweetProducts <dbl>,
## #   MntGoldProds <dbl>, NumDealsPurchases <dbl>, NumWebPurchases <dbl>,
## #   NumCatalogPurchases <dbl>, NumStorePurchases <dbl>,
## #   NumWebVisitsMonth <dbl>, AcceptedCmp3 <dbl>, AcceptedCmp4 <dbl>,
## #   AcceptedCmp5 <dbl>, AcceptedCmp1 <dbl>, AcceptedCmp2 <dbl>, Complain <dbl>,
## #   Z_CostContact <dbl>, Z_Revenue <dbl>, Response <dbl>

Selección sugerida

vars <- c("Income", "MntWines", "MntFruits", "MntMeatProducts",
          "MntFishProducts", "MntSweetProducts", "MntGoldProds")

# Creación dataframe limpio (sin NA)
df_clean <- Customer_Personality %>% 
  dplyr::select(all_of(vars)) %>% 
  drop_na()

# Estandarizando
df_scaled <- scale(df_clean)
p <- ncol(df_scaled)   # grados de libertad (número de variables)
head(df_scaled, n = 3)
##          Income   MntWines  MntFruits MntMeatProducts MntFishProducts
## [1,]  0.2340099  0.9780050  1.5490798       1.6898454        2.454014
## [2,] -0.2345065 -0.8718271 -0.6371840      -0.7178241       -0.650891
## [3,]  0.7693040  0.3584298  0.5690305      -0.1783278        1.339901
##      MntSweetProducts MntGoldProds
## [1,]        1.4844919   0.84983876
## [2,]       -0.6337371  -0.73270190
## [3,]       -0.1467879  -0.03792796

K-Means clustering

fviz_nbclust(df_scaled, kmeans, method = "wss") +
  geom_vline(xintercept = 5, linetype = 2) +
  labs(subtitle = "Método del codo")

# Compute k-means with k = 5
set.seed(123)
km.res <- kmeans(df_scaled, 5, nstart = 25)
print(km.res)
## K-means clustering with 5 clusters of sizes 450, 283, 256, 1064, 163
## 
## Cluster means:
##       Income   MntWines  MntFruits MntMeatProducts MntFishProducts
## 1  0.3495149  0.4215007 -0.1744109      -0.1527252     -0.15232037
## 2  0.8564471  0.5846308  1.8117405       1.0653512      1.73493565
## 3  1.1317282  1.3742487  0.4755803       1.6359933      0.64607741
## 4 -0.6979310 -0.7571264 -0.5423108      -0.6336588     -0.56092631
## 5  0.3265028  0.6052087  0.1290336       0.1388380      0.05513592
##   MntSweetProducts MntGoldProds
## 1     -0.147437203  -0.09535402
## 2      1.826818913   0.91407875
## 3      0.493188860   0.06173471
## 4     -0.541907859  -0.56201939
## 5     -0.001898143   2.24791149
## 
## Clustering vector:
##    [1] 2 4 1 4 1 1 1 4 4 4 4 2 4 4 3 4 4 5 4 4 3 1 1 1 4 4 4 3 4 4 4 4 3 4 1 4 4
##   [38] 1 2 4 4 4 2 4 4 3 1 3 4 2 5 2 2 4 1 3 1 5 1 2 4 4 3 5 3 3 2 1 4 4 3 2 4 1
##   [75] 4 4 4 4 1 4 4 4 2 4 4 4 4 1 4 5 1 4 4 2 3 3 4 4 2 4 2 3 3 1 1 1 4 2 2 4 4
##  [112] 1 4 4 4 5 5 2 4 1 1 1 5 4 3 4 4 4 4 3 1 3 1 5 1 4 4 4 4 1 1 1 4 1 1 4 4 4
##  [149] 3 4 3 4 1 3 4 1 4 2 4 4 4 4 4 4 3 2 4 4 5 4 4 5 4 4 4 4 5 3 4 4 2 4 4 4 4
##  [186] 1 3 2 4 1 2 3 2 4 4 4 4 4 5 4 3 4 1 2 1 4 3 4 1 4 3 1 4 1 4 5 1 3 4 4 2 4
##  [223] 4 1 4 4 1 4 4 2 2 4 2 5 4 3 3 2 2 4 4 2 4 3 4 1 4 4 4 4 1 4 4 4 4 2 4 2 4
##  [260] 3 4 4 4 4 1 2 2 3 5 4 5 4 1 4 4 2 5 2 4 4 4 2 4 4 1 4 4 1 1 4 1 4 4 4 2 4
##  [297] 3 1 4 4 4 3 4 4 4 1 4 1 4 4 3 1 5 4 4 4 4 4 4 1 4 4 5 2 4 3 2 3 4 1 1 4 2
##  [334] 4 2 4 4 1 2 3 3 1 4 4 2 1 1 2 1 4 4 1 5 3 4 2 1 4 4 4 5 4 4 4 4 5 4 4 4 4
##  [371] 4 4 4 1 5 4 1 2 4 2 4 1 3 4 4 4 4 4 2 4 5 1 4 4 1 4 1 4 2 1 1 5 3 4 3 2 1
##  [408] 4 4 4 3 3 4 2 1 4 2 3 5 2 5 4 4 1 1 4 4 4 4 4 4 4 4 4 2 4 1 1 1 4 1 1 4 2
##  [445] 4 4 2 1 2 4 2 4 3 3 4 1 1 2 4 1 4 4 5 4 1 1 5 4 4 4 4 1 2 1 1 4 4 3 4 3 5
##  [482] 1 1 4 3 1 1 4 4 4 5 4 5 2 2 4 2 4 2 4 2 4 3 4 4 1 3 4 5 4 3 4 4 3 1 2 1 1
##  [519] 3 1 1 4 4 4 2 1 4 4 4 1 3 1 4 3 4 4 4 4 4 1 4 2 4 5 2 4 3 4 2 1 2 4 4 1 4
##  [556] 4 4 1 4 4 1 4 1 4 4 4 4 4 1 4 4 4 4 5 1 1 4 4 2 2 4 1 4 4 4 4 4 4 1 3 1 4
##  [593] 4 4 4 4 3 4 4 4 4 1 4 4 1 4 4 1 4 1 4 5 4 2 3 4 4 3 1 2 4 2 4 5 1 3 3 5 3
##  [630] 1 5 3 4 2 4 1 5 3 4 3 4 4 1 4 4 2 4 1 4 2 4 4 4 4 4 4 4 3 1 2 2 1 4 1 1 4
##  [667] 1 5 2 1 4 3 1 2 3 3 3 1 5 4 4 4 4 4 4 1 3 1 1 5 3 4 2 4 1 5 4 4 1 4 1 4 2
##  [704] 2 4 5 4 1 5 4 2 4 4 3 2 1 5 4 1 5 4 3 3 2 1 4 2 1 4 4 4 3 5 4 2 4 1 3 1 2
##  [741] 3 2 2 1 5 4 4 4 1 2 4 5 4 3 2 4 1 1 5 5 4 4 4 4 3 4 2 2 4 4 4 4 4 4 5 5 4
##  [778] 2 1 4 4 4 4 1 5 2 4 1 4 4 2 3 1 4 1 5 2 4 4 2 1 2 1 4 1 1 4 3 4 1 4 3 2 3
##  [815] 4 3 4 4 5 1 4 4 2 1 5 4 5 4 4 4 4 3 3 5 1 4 4 1 1 2 4 4 2 4 1 4 1 4 4 4 1
##  [852] 1 1 4 4 5 4 3 1 4 4 5 2 1 4 3 4 4 4 4 4 2 2 4 4 1 3 4 1 5 4 1 5 5 2 4 4 3
##  [889] 4 3 1 4 5 3 4 4 4 3 3 5 4 3 2 1 3 1 3 4 5 4 4 2 5 2 2 2 3 3 4 1 4 5 4 2 3
##  [926] 5 1 2 5 2 3 4 1 5 1 4 1 4 4 4 4 4 4 5 1 4 1 2 1 4 4 4 5 3 4 4 1 2 4 4 1 2
##  [963] 3 3 1 4 5 4 4 4 3 2 1 3 3 3 4 3 4 1 2 4 4 3 4 1 4 1 3 5 4 4 1 1 5 4 4 2 4
## [1000] 4 4 4 1 2 4 4 4 4 4 5 4 4 2 4 4 4 3 2 2 3 4 2 4 4 4 4 5 5 4 4 5 4 4 4 2 5
## [1037] 1 2 4 3 4 4 1 4 4 3 2 1 5 1 4 1 4 2 5 4 1 4 2 1 4 5 2 3 4 1 4 2 4 3 4 3 5
## [1074] 4 1 4 2 3 4 1 4 4 1 1 3 4 1 2 1 4 4 4 3 4 4 1 1 3 2 4 3 4 5 4 5 4 1 1 4 1
## [1111] 4 4 4 3 4 4 3 1 4 4 3 3 4 4 3 4 4 1 4 4 4 5 4 4 1 1 4 1 2 4 3 4 4 1 2 3 2
## [1148] 4 1 1 3 4 1 4 4 2 3 4 4 3 1 4 4 4 1 4 2 1 4 1 4 4 4 4 1 4 4 2 1 4 4 4 5 4
## [1185] 1 1 2 4 2 4 4 3 1 3 4 4 4 4 2 1 3 1 4 1 4 3 4 4 4 2 4 4 1 1 4 1 4 4 4 4 4
## [1222] 4 1 4 3 4 4 4 4 2 1 4 4 4 4 4 1 3 1 3 2 5 1 5 2 4 2 4 3 3 4 4 2 5 4 4 3 1
## [1259] 1 4 1 4 1 4 4 5 4 2 2 4 1 5 4 1 4 2 2 4 4 4 4 4 4 4 1 2 4 1 3 4 4 2 1 1 3
## [1296] 1 5 1 3 4 2 1 4 1 4 4 4 3 1 2 5 4 5 4 4 5 2 4 1 2 2 3 1 2 4 4 4 4 1 1 4 4
## [1333] 4 4 1 1 3 3 2 4 1 3 2 4 1 2 4 1 4 1 1 1 2 4 4 4 1 4 4 4 1 1 4 1 4 4 4 4 4
## [1370] 3 4 4 2 1 4 4 4 4 1 4 4 5 5 1 1 4 4 1 4 4 1 1 4 1 3 4 2 4 5 4 4 4 4 4 5 5
## [1407] 4 4 4 4 4 4 2 4 4 2 4 1 4 1 4 4 4 4 4 4 3 2 1 2 1 5 1 4 2 3 4 1 3 4 4 3 1
## [1444] 1 1 4 4 4 5 1 5 4 3 4 4 4 3 5 4 3 4 4 1 2 1 4 4 2 1 3 1 3 4 1 4 2 1 4 2 4
## [1481] 1 3 3 5 4 4 1 1 1 1 2 2 1 2 4 2 2 4 1 1 4 4 4 3 2 4 4 4 1 2 4 2 4 1 4 1 4
## [1518] 4 4 4 3 1 3 4 1 2 4 1 4 4 4 1 4 4 1 2 5 3 4 4 4 4 5 4 1 4 2 4 4 1 1 1 1 3
## [1555] 4 2 4 4 4 4 3 4 1 4 3 3 4 1 4 4 1 4 3 4 2 4 4 4 1 4 4 2 4 1 2 1 4 4 4 3 1
## [1592] 1 1 3 4 2 4 4 2 4 4 1 5 4 4 2 5 4 4 2 2 4 4 2 4 4 4 1 1 1 2 4 4 4 5 1 4 2
## [1629] 4 1 1 2 4 4 3 4 3 4 4 4 1 5 3 1 4 1 4 4 4 1 4 3 3 4 2 3 5 2 4 4 4 4 4 2 4
## [1666] 4 4 4 4 3 1 2 2 1 3 4 4 4 1 4 1 4 2 5 4 4 1 4 4 1 4 2 4 3 3 4 3 4 5 3 4 4
## [1703] 5 4 3 2 3 4 4 4 4 1 2 4 4 4 2 2 3 1 3 4 4 4 4 4 5 1 2 4 5 5 3 1 1 4 1 4 4
## [1740] 4 4 4 2 2 4 1 1 4 3 4 2 4 4 4 4 1 2 4 4 4 4 4 1 4 4 3 1 4 4 1 4 2 3 4 4 3
## [1777] 4 4 4 1 4 1 2 5 3 4 4 4 1 5 4 3 3 4 5 1 2 2 4 1 2 1 4 1 4 4 5 2 4 1 2 3 4
## [1814] 4 4 1 4 4 4 2 4 5 5 4 3 4 3 1 1 4 4 1 4 3 4 3 3 3 1 4 4 3 5 1 4 1 2 3 1 4
## [1851] 4 4 2 4 2 4 1 4 4 5 2 1 3 2 4 4 5 4 1 4 3 2 4 2 2 4 1 2 4 4 3 2 1 4 4 1 4
## [1888] 4 2 1 4 4 4 2 2 2 3 5 5 4 4 4 4 4 2 3 3 2 4 1 3 2 1 4 1 4 4 2 4 1 1 4 4 5
## [1925] 4 4 2 4 3 2 3 4 4 4 1 3 3 1 3 4 1 3 4 2 5 4 4 4 2 5 3 2 3 1 4 4 1 4 5 2 4
## [1962] 4 4 4 4 2 4 1 4 4 5 4 1 3 4 3 3 4 1 1 1 4 1 4 4 4 4 4 4 2 1 1 1 3 4 3 2 3
## [1999] 4 4 4 4 4 4 4 4 1 5 4 4 4 1 4 1 5 4 5 5 1 2 1 4 2 5 2 4 4 5 4 4 3 2 3 4 1
## [2036] 1 4 4 4 3 5 5 4 5 4 3 2 4 3 4 4 1 2 4 1 2 1 4 4 4 1 3 1 3 3 4 4 4 4 1 2 1
## [2073] 4 2 4 5 1 4 1 4 1 4 4 4 5 4 3 1 5 4 4 4 1 4 1 5 4 4 4 4 5 4 3 5 3 1 4 4 3
## [2110] 1 4 2 1 4 4 4 4 4 4 4 4 1 3 4 4 1 4 4 2 4 4 4 4 4 4 1 1 5 1 1 2 4 4 2 3 2
## [2147] 4 1 5 2 5 1 2 2 1 5 4 4 1 4 4 4 2 1 3 2 4 3 4 4 2 5 4 4 1 5 4 4 1 1 2 4 4
## [2184] 2 4 4 4 1 3 4 3 4 4 4 2 4 4 1 3 4 4 1 1 1 1 4 4 1 4 3 4 5 1 1 1 4
## 
## Within cluster sum of squares by cluster:
## [1] 1026.6199 2171.8591 1951.2843  476.0468  625.3122
##  (between_SS / total_SS =  59.7 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Versión limpia del dataset original con los clústers

Customer_Personality_clean <- Customer_Personality %>% 
  dplyr::select(all_of(vars)) %>% 
  drop_na() %>%
  mutate(cluster = km.res$cluster)

# Ver resultado
head(Customer_Personality_clean)
## # A tibble: 6 × 8
##   Income MntWines MntFruits MntMeatProducts MntFishProducts MntSweetProducts
##    <dbl>    <dbl>     <dbl>           <dbl>           <dbl>            <dbl>
## 1  58138      635        88             546             172               88
## 2  46344       11         1               6               2                1
## 3  71613      426        49             127             111               21
## 4  26646       11         4              20              10                3
## 5  58293      173        43             118              46               27
## 6  62513      520        42              98               0               42
## # ℹ 2 more variables: MntGoldProds <dbl>, cluster <int>

Análisis de Clusters

aggregate(Customer_Personality_clean[, vars], by = list(cluster = Customer_Personality_clean$cluster), mean)
##   cluster   Income  MntWines MntFruits MntMeatProducts MntFishProducts
## 1       1 61045.62 447.27556 19.415556       132.74222       29.297778
## 2       2 73806.66 502.30389 98.452297       405.93640      132.628975
## 3       3 80736.33 768.66406 45.281250       533.92188       73.011719
## 4       4 34678.18  49.69173  4.775376        24.87688        6.925752
## 5       5 60466.33 509.24540 31.490798       198.13497       40.656442
##   MntSweetProducts MntGoldProds
## 1        20.973333     39.02444
## 2       102.060071     91.32862
## 3        47.285156     47.16406
## 4         4.771617     14.84398
## 5        26.950920    160.44172
fviz_cluster(km.res, data = df_scaled,
             palette = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07", "#FF6B6B"),
             ellipse.type = "euclid",
             star.plot = TRUE, 
             repel = TRUE,
             ggtheme = theme_minimal())

# Cluster number for each observation
head(km.res$cluster, 10)
##  [1] 2 4 1 4 1 1 1 4 4 4
# Cluster size
km.res$size
## [1]  450  283  256 1064  163
# Cluster means
km.res$centers
##       Income   MntWines  MntFruits MntMeatProducts MntFishProducts
## 1  0.3495149  0.4215007 -0.1744109      -0.1527252     -0.15232037
## 2  0.8564471  0.5846308  1.8117405       1.0653512      1.73493565
## 3  1.1317282  1.3742487  0.4755803       1.6359933      0.64607741
## 4 -0.6979310 -0.7571264 -0.5423108      -0.6336588     -0.56092631
## 5  0.3265028  0.6052087  0.1290336       0.1388380      0.05513592
##   MntSweetProducts MntGoldProds
## 1     -0.147437203  -0.09535402
## 2      1.826818913   0.91407875
## 3      0.493188860   0.06173471
## 4     -0.541907859  -0.56201939
## 5     -0.001898143   2.24791149

Referencias

Practical guide to cluster analysis in r: Unsupervised machine learning (multivariate analysis). STHDA