Portada

UNIVERSIDAD DE EL SALVADOR

FACULTAD DE CIENCIAS ECONÓMICAS

ESCUELA DE ECONOMÍA

CICLO II-2021

Asignatura:

Métodos para el Análisis Ecocómico.

Facilitador:

Carlos Ademir Pérez Alas.

Contenido:

Laboratorio 2.

Grupo Teórico:

03.

Integrantes:

Hernández Cartagena, Karla Mireya. HC18035.

Mejía Ramos, Carlos Arnoldo. MR18006.

Meléndez Morales, Kennya Elizabeth. MM16049.

Novoa Rubio, Fernando Enrique. NR18001.

Ciudad Universitaria, viernes 19 de noviembre de 2021.

Numeral 1

Explique en que consiste el análisis de conglomerados.

El análisis de conglomerados o también conocido como análisis de clúster es una técnica estadística multivariante que sirve para clasificar distintas observaciones (variables) en grupos (clúster), es importante recalcar que los grupos deben ser homogéneos esto quiere decir que las observaciones pertenecientes a un mismo grupo tienen que compartir características, pero entre un grupo y otro existirá la máxima heterogeneidad. (Aldas Manzano and Uriel Jimenez 2017)

Para hacer uso de esta técnica el individuo tendrá una cantidad “x” de observaciones y variables, luego se debe establecer la “distancia” que es una medida de similitud entre las observaciones, a partir de esto se irán agrupando las observaciones que compartan mayor similitud entre ellas, siendo necesario la toma de decisión del tipo de análisis de clúster a emplear, por último una descripción de los grupos formados además de realizar comparaciones entre ellos. (Cabarcos Fernández 2015)

Al observar gráficamente el análisis clúster, puede distinguirse que habrá una menor distancia entre los observaciones que se encuentran dentro de los clústeres, a diferencia de que cada conglomerado se verá distanciado uno del otro, esto se evidencia siempre y cuando se realice la clasificación de manera adecuada. (De la Fuente Fernández 2011)

Numeral 2

Elabore un cuadro comparativo, que incluya los siguientes elementos:

library(tidyverse)
library(dplyr)
library(knitr)
library(kableExtra)
timeline_tab <- tibble(
  `Análisis de Clúster` = c(
    "**Jerárquico:**  
    Son métodos que entregan una jerarquía de divisiones del conjunto de elementos en conglomerados.  
    En este tipo de análisis no se requiere determinar el número de clústeres de manera previa, estos métodos se dividen en aglomerativo y divisivo."
  ),
  `Técnicas Disponibles` = c(
    "• Método de vinculación Simple.  
    • Método de vinculación Completo.  
    • Método del promedio entre grupos.  
    • Método Ward.  
    • Método centroide."
  ),
`Ventajas` = c(
  "• En la técnica de clustering divisivo solo hay que elegir la distacia, a diferencia del clustering aglomerativo en el cual hay que elegir un tipo de distancia y un método de vinculación.  
  • Con el análisis de Clúster jerárquico tenemos la ventaja de poder visualizar los resultados de manera gráfica por medio de un dendrograma."
),
`Desventajas` = c(
  "• Realizar el clúster jerárquico en conjunto de datos grande es problemático debido a la representación e interpretación del dendrograma.  
  • Debido a que el análisis clúster implica la elección entre diferentes medidas y procedimientos, con frecuencia es difícil juzgar la veracidad de los resultados.  
  • En última instancia la validez de los clúster se juzga mediante una interpretación cualitativa que puede ser subjetiva."
)
) %>%
  add_row(
    `Análisis de Clúster` = c(
      "**No Jerárquico:**  
      El análisis de clúster no jerárquico o de particiones se compone por métodos de agrupación que se utilizan para clasificar observaciones, que están dentro de un conjunto de datos, en varios grupos en función de su similitud.  
      Los algoritmos utilizados requieren que el analista especifique el número de conglomerados que se van a generar."
    ),
    `Técnicas Disponibles` = c(
    "• K-Means.  
    • K-Medoids.  
    • CLARA."),
`Ventajas` = c(
  "• Destaca por su sencillez y velocidad de su algoritmo (K-Means clustering).  
  • K-Medoids es un método de clustering más robusto que K-Means, por lo es más adecuado cuando el set de datos contiene datos atípicos o ruido.  
  • CLARA es un método que combina la idea de K-medoids con el remuestreo para que pueda aplicarse a grandes volúmenes de datos."
),
`Desventajas` = c(
  "• Requiere que se indique de antemano el número de clústeres que se van a crear.  
  • Presenta problemas de robustez frente a los datos atípicos (K-Means).  
  • Es posible obtener soluciones diferentes cada vez que se realiza una reorganización de los datos.  
  • Para sets de datos grandes necesita muchos recursos computacionales (K-Medoids)."
)
  )

timeline_tab %>%
  kable(caption = "**Tabla 1:** Resumen del Análisis Clúster") %>% 
  kable_styling("hover") %>% 
  row_spec(0, bold = T, align = "c") %>%
  column_spec(c(1), width = "7cm", border_right = T, border_left = T) %>%
  column_spec(c(2), width = "6cm", border_right = T) %>%
  column_spec(c(3), width = "9cm", border_right = T) %>%
  column_spec(c(4), width = "8cm", border_right = T) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>% 
  footnote(general = "Elaboración propia con base en:",
           number = c("[@feclus]", "[@libroIngles]"), general_title = "Fuente:")
Tabla 1: Resumen del Análisis Clúster
Análisis de Clúster Técnicas Disponibles Ventajas Desventajas
Jerárquico:
Son métodos que entregan una jerarquía de divisiones del conjunto de elementos en conglomerados.
En este tipo de análisis no se requiere determinar el número de clústeres de manera previa, estos métodos se dividen en aglomerativo y divisivo.
• Método de vinculación Simple.
• Método de vinculación Completo.
• Método del promedio entre grupos.
• Método Ward.
• Método centroide.
• En la técnica de clustering divisivo solo hay que elegir la distacia, a diferencia del clustering aglomerativo en el cual hay que elegir un tipo de distancia y un método de vinculación.
• Con el análisis de Clúster jerárquico tenemos la ventaja de poder visualizar los resultados de manera gráfica por medio de un dendrograma.
• Realizar el clúster jerárquico en conjunto de datos grande es problemático debido a la representación e interpretación del dendrograma.
• Debido a que el análisis clúster implica la elección entre diferentes medidas y procedimientos, con frecuencia es difícil juzgar la veracidad de los resultados.
• En última instancia la validez de los clúster se juzga mediante una interpretación cualitativa que puede ser subjetiva.
No Jerárquico:
El análisis de clúster no jerárquico o de particiones se compone por métodos de agrupación que se utilizan para clasificar observaciones, que están dentro de un conjunto de datos, en varios grupos en función de su similitud.
Los algoritmos utilizados requieren que el analista especifique el número de conglomerados que se van a generar.
• K-Means.
• K-Medoids.
• CLARA.
• Destaca por su sencillez y velocidad de su algoritmo (K-Means clustering).
• K-Medoids es un método de clustering más robusto que K-Means, por lo es más adecuado cuando el set de datos contiene datos atípicos o ruido.
• CLARA es un método que combina la idea de K-medoids con el remuestreo para que pueda aplicarse a grandes volúmenes de datos.
• Requiere que se indique de antemano el número de clústeres que se van a crear.
• Presenta problemas de robustez frente a los datos atípicos (K-Means).
• Es posible obtener soluciones diferentes cada vez que se realiza una reorganización de los datos.
• Para sets de datos grandes necesita muchos recursos computacionales (K-Medoids).
Fuente:
Elaboración propia con base en:
1 (Amat 2017)
2 (Kassambara 2017)

Numeral 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.

Generalidades para la aplicación de técnicas de análisis de clúster

Para realizar un análisis de clusters en R, generalmente, los datos deben prepararse de la siguiente manera:

1. Las filas son observaciones (individuos) y las columnas son variables

2. Cualquier valor que falte en los datos debe eliminarse utilizando la función na.omit

df<- na.omit(df)

Función na.omit: elimina todos los casos incompletos de un objeto de datos (típicamente de un marco de datos, matriz o vector)

La función na.omit solo requiere el nombre de la base de datos o dataframe que se está usando. En este caso df es el nombre de la base de datos (Kassambara 2017).

3. Los datos deben estar estandarizados para que las variables sean comparables. Hay que recordar que la estandarización consiste en transformar las variables de tal manera que tengan media cero y desviación estándar uno, para estandarizar nuestra data usamos la función Scale.

Sintaxis:

scale (x, center= TRUE, scale= TRUE)

Función Scale: es una función genérica cuyo método predeterminado centra y / o escala las columnas de una matriz numérica.

Argumentos:

x: una matriz numérica (como un objeto).

Center: ya sea un valor lógico o un vector numérico de longitud igual al número de columnas de x, donde ‘numérico similar’ significa que as.numeric(.)se aplicará con éxito si is.numeric(.)no es verdadero.

Scale: un valor lógico o un vector numérico de longitud igual al número de columnas de x.

Si se usa la funcion scale(x, scale = FALSE), solo restará la media pero no dividirá por la desviación estándar, para el análisis de clúster, debemos establecer scale= TRUE, aunque la función scale con la configuración predeterminada calculará la media y la desviación estándar de todo el vector, luego “escalará” cada elemento por esos valores restando la media y dividiendo por la desviación estándar. (RDocumentation, n.d.b)

Antes de dar paso a la explicación de las técnicas de análisis de clúster, es importante entender algunos elementos como lo son las medidas de distancia y la matriz de distancia.

Medidas de distancia

Todos los métodos de clustering tienen una cosa en común, para poder llevar a cabo las agrupaciones necesitan definir y cuantificar la similitud entre las observaciones. El término distancia se emplea dentro del contexto del clustering como cuantificación de la similitud o diferencia entre observaciones. En el método de análisis de clúster se puede emplear cualquier tipo de distancia, es el investigador el que decide que tipo usar, a continuación se muestran algunas de las más usadas. (Amat 2017)

• Distancia euclídeana

La distancia euclidiana entre dos puntos p y q se define como la longitud del segmento que une ambos puntos. En coordenadas cartesianas, la distancia euclidiana se calcula empleando el teorema de Pitágoras. Por ejemplo, en un espacio de dos dimensiones en el que cada punto está definido por las coordenadas (x,y), la distancia euclidiana entre p y q viene dada por la ecuación:

\[ d_{ec}(p,q)=\sqrt{\displaystyle\sum_{i=1}^n (p_{i}-q_{i})^2} \]

Una forma de dar mayor peso a aquellas observaciones que está más alejadas es emplear la distancia e euclidiana al cuadrado. En el caso del clustering, donde se busca agrupar observaciones que minimicen la distancia, esto se traduce en una mayor influencia de aquellas observaciones que están más distantes.

Distancia euclideana.

La imagen muestra el perfil de dos observaciones definidas por 10 variables (espacio con 10 dimensiones). La distancia euclídeana entre las dos observaciones equivale a la raíz cuadrada de la suma de las longitudes de los segmentos rojos que unen cada par de puntos. Tiene en cuenta por lo tanto el desplazamiento individual de cada una de las variables. (Amat 2017)

• Distancia de Manhattan

La distancia de Manhattan, define la distancia entre dos puntos p y q como el sumatorio de las diferencias absolutas entre cada dimensión. Esta medida se ve menos afectada por outliers (es más robusta) que la distancia euclídea debido a que no eleva al cuadrado las diferencias.

\[ d_{man}(p,q)=\sqrt{\displaystyle\sum_{i=1}^n |(p_{i}-q_{i})|} \]

Comparacion entre la distancia euclideana y la distancia de manhattan.

La imagen muestra una comparación entre la distancia euclídeana (segmento azul) y la distancia de manhattan (segmento rojo y verde) en un espacio bidimensional. Existen múltiples caminos para unir dos puntos con el mismo valor de distancia de manhattan, ya que su valor es igual al desplazamiento total en cada una de las dimensiones. (Amat 2017)

Calculo de la matriz de distancia en R

Sintaxis:

dist.eucl <- dist (df.scaled, method = "euclidean" )

En donde dist.eucl, es el nombre del objeto en el cual se almacenará la matriz de distancia.

Función dist: Es una función de R que nos sirve para calcular y visualizar matrices de distancia.

Argumentos:

Los argumentos que necesita la función dist, es el nombre de la data estandarizada, y el método que se usará para medir la distancia, tenga en cuenta que los valores permitidos para el método de opción incluyen: “euclidean,” “maximum,” “manhattan,” “canberra,” “binary,” “minkowski” (Kassambara 2017).

Ejemplo de una matriz de distancia.

En la matriz de distancia, cada valor representa la distancia entre objetos. Los valores en la diagonal de la matriz representan la distancia entre los objetos y ellos mismos (que son cero).

Se observa en la matriz de distancias cuales son los objetos más similares, en este ejemplo son el A y B que tienen la distancia menor (1). (Granada 2015)

Distancias basadas en correlación:

La correlación es una medida de distancia muy útil cuando la definición de similitud se hace en términos de patrón o forma y no de desplazamiento o magnitud. Si se emplea como medida de similitud 1 menos el valor de la correlación, ambas observaciones se consideran idénticas (su distancia es 0).

\[ d_{cor}(p,q)=1−correlacion(p,q) \]

Donde la correlación puede ser de distintos tipos (Pearson, Spearman, Kendall, eisen.)

Comparación entre entre 3 observaciones.

En la imagen se muestra el perfil de 3 observaciones. Acorde a la distancia euclídeana, las observaciones b y c son las más similares, mientras que acorde a la correlación de Pearson, las observaciones más similares son a y b. (Amat 2017)

El análisis de correlación de Pearson es el método más utilizado. También se conoce como correlación paramétrica que depende de la distribución de los datos. La correlación de Pearson es bastante sensible a los valores atípicos.

Las correlaciones de Kendall y Spearman no son paramétricas y se utilizan para realizar análisis de correlación basados en rangos.

La elección de las medidas de distancia es muy importante, ya que tiene una fuerte influencia en los resultados de agrupamiento. Para el software de agrupamiento más común, la medida de distancia predeterminada es la distancia euclidiana.

Dependiendo del tipo de datos y las preguntas del investigador, otras diferencias Se pueden preferir medidas, por ejemplo, la distancia basada en correlación se usa a menudo en análisis de datos de expresión génica (Kassambara 2017).

Calcular de la matriz de distancias basadas en correlación en R

library("factoextra")
dist.cor <- get_dist(df.scaled, method = "pearson")

En donde dist.cor, es el nombre del objeto en el cual se almacenará la matriz de distancia.

Los argumentos que necesita la función get_dist, es el nombre de la data estandarizada, y el método que se usará para medir la distancia. , tenga en cuenta que los valores permitidos para el método de opción incluyen: “Pearson,” “Spearman” o “Kendall.”

Al ejecutar dicha codigo se obtiene una matriz semejante a la del ejemplo anterior, donde cada valor representa la distancia entre objetosy los valores en la diagonal de la matriz representan la distancia entre los objetos y ellos mismos (que son cero) (Kassambara 2017).

Calcular distancias para datos mixtos

La función daisy() [paquete de clúster] proporciona una solución (métrica de Gower) para calcular la matriz de distancia, en la situación en la que los datos no contienen columnas numéricas.

library(cluster)
dd <- daisy(df)

Argumentos:

En donde dd, es el nombre del objeto en el cual se almacenará la matriz de distancia.

De forma simplificada el único argumento que utiliza la función Daisy, es el nombre de la data, la cual no contienen columnas numéricas.

De igual forma al ejecutar dicho codigo se obtiene una matriz semejante a la del ejemplo anterior, la cual se interpreta de la misma forma (Kassambara 2017).

Visualización de matrices de distancia

Una solución simple para visualizar las matrices de distancia es usar la función fviz_dist ()[paquete factoextra]

library(factoextra) 
fviz_dist (dist.eucl)

En donde dist.eucl, es el nombre del objeto en el cual se almacenó anteriormente la matriz de distancia (Kassambara 2017).

Uso de fviz_dist, con todos sus argumentos

fviz_dist(
dist.obj,
order = TRUE,
show_labels = TRUE,
lab_size = NULL,
gradient = list(low = "red", mid = "white", high = "blue")
)

Argumentos:

dist.obj: un objeto de clase “dist” generado por la función dist () o get_dist ().

Order: valor lógico. Si es VERDADERO, se muestra la imagen de disimilitud ordenada (ODI).

show_labels: valor lógico. Si es VERDADERO, se muestran las etiquetas.

lab_size: el tamaño de las etiquetas.

gradient: una lista que contiene tres elementos que especifican los colores para los valores bajo, medio y alto en la imagen de disimilitud ordenada. (RDocumentation, n.d.a)

Visualización gráfica de una matriz de distancia

La visualización grafica de una matriz de distancia nos permite oberservar con ligereza y a grandes rasgos, entre que objetos hay menor o mayor distancia, en este ejemplo podemos observar que las distancias mas bajas entre los objetos , estan coloreadas con tono azul y las mas altas, con un tono rojo.

Técnicas de análisis de clúster

Técnicas no jerárquicas:

La agrupación de clústeres basada en particiones son métodos de agrupación que se utilizan para clasificar observaciones, dentro de un conjunto de datos, en varios grupos en función de su similitud. Los algoritmos requieren analista para especificar el número de conglomerados que se generarán. Este apartado describe la agrupación en clústeres de particiones de uso común (Kassambara 2017).

K-medias

Es el método no supervisado más utilizado algoritmo de aprendizaje automático para particionar un conjunto de datos dado en un conjunto de k grupos, donde k representa el número de grupos predefinidos por el analista antes de ejecutar del algoritmo. K-medias, encuentra los K mejores clusters, entendiendo como mejor clúster aquel cuya varianza interna, (sea lo más pequeña posible). Se trata por lo tanto de un problema de optimización, en el que se reparten las observaciones en K clusters de forma que la suma de las varianzas internas de todos ellos sea lo menor posible (Kassambara 2017).

El algoritmo de k medias es el siguiente:

  1. Especificar el número K de clusters que se quieren crear.
  2. Seleccionar de forma aleatoria k observaciones del set de datos como centroides iniciales.
  3. Asignar cada una de las observaciones al centroide más cercano.
  4. Para cada uno de los K clusters recalcular su centroide.
  5. Repetir los pasos 3 y 4 hasta que las asignaciones no cambien o se alcance el número máximo de iteraciones establecido.

Este algoritmo garantiza que, en cada paso, se reduzca la intra-varianza total de los clusters hasta alcanzar un óptimo local.

Resutado de la aplicación del algoritmo de k medias

Paquetes y funciones de R requeridos, para k medias.

La función R estándar para la agrupación en clústeres de k-medias es kmeans () [paquete stats], su sintaxis es:

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

x: matriz numérica, marco de datos numéricos o un vector numérico.

Centers: los valores posibles son el número de grupos (k) o un conjunto de grupos iniciales (distintos) centros de clúster. Si es un número, un conjunto aleatorio de filas (distintas) en x se elige como los centros iniciales.

iter.max: el número máximo de iteraciones permitidas. El valor predeterminado es 10.

nstart: el número de particiones iniciales aleatorias cuando los centros son un número. A menudo se recomienda probar nstart> 1 (Kassambara 2017).

La función kmeans () devuelve una lista de componentes, que incluyen:

cluster: un vector de números enteros (de 1: k) que indica el clúster al que cada se asigna el punto

centers: una matriz de centros de conglomerados (medias de conglomerados)

totss: La suma total de cuadrados (TSS), es decir, q ( x i ≠ ¯ x ) 2 . TSS mide el total varianza en los datos.

withinss: Vector de suma de cuadrados dentro del conglomerado, un componente por conglomerado

tot.withinss: suma total de cuadrados dentro del conglomerado, es decir, suma (sin inserciones

betweenss: La suma entre-clúster de cuadrados, es decir totss ≠ tot.withinss

size: el número de observaciones en cada grupo .

Se puede acceder a cada uno de estos componentes utilizando el nombre del objeto creado con la función kmeans, seguido de un signo de dólar ($) y el nombre del componente que se desea extraer o visualizar (Kassambara 2017).

Estimación del número óptimo de clúster k-medias

La agrupación en clústeres de k-means requiere que los usuarios especifiquen el número de clústeres que se generarán, una pregunta fundamental es: cómo elegir el número correcto de clústeres.

La función R fviz_nbclust () [en el paquete factoextra ] proporciona una solución conveniente para estimar el número óptimo de clusters, determina y visualiza el número óptimo de conglomerados usando diferentes métodos: dentro de los clusters , sumas de cuadrados, silueta promedio y estadísticas de brechas (Kassambara 2017).

Uso de la función fviz_nbclust ()
fviz_nbclust(
 x,
 FUNcluster = NULL,
method = c("silhouette", "wss", "gap_stat"),
 diss = NULL,
k.max = 10,
nboot = 100,
verbose = interactive(),
barfill = "steelblue",
barcolor = "steelblue",
linecolor = "steelblue",
print.summary = TRUE
)

x: matriz numérica o marco de datos. En la función fviz_nbclust (), x puede ser el resultado de la función NbClust ().

FUNcluster: una función de partición que acepta como primer argumento una matriz (de datos) como x, segundo argumento, digamos k, k> = 2, el número de clúster deseados, y devuelve una lista con un componente llamado clúster, que contiene el agrupamiento de observaciones. Los valores permitidos incluyen: kmeans, clúster :: pam, clúster :: clara, clúster :: fanny, hcut, etc. Este argument

method: el método que se utilizará para estimar el número óptimo de conglomerados. Los valores posibles son “silueta” (para el ancho medio de la silueta), “wss” (para el total dentro de la suma del cuadrado) y “gap_stat” (para las estadísticas de espacios).o no es necesario cuando x es una salida de la función NbClust::NbClust().

diss: objeto dist producido por dist (), es decir: , diss = dist(x, method = “euclidean”)Se utiliza para calcular el ancho de silueta promedio de los conglomerados, la suma interna de los conglomerados cuadrados y jerárquicos. Si es NULL, dist (x) se calcula con el método predeterminado = “euclidiana”

k.max: el número máximo de clústeres a considerar debe ser al menos dos.

nboot: entero, número de muestras de Monte Carlo (“bootstrap”). Se utiliza solo para determinar el número de conglomerados mediante la estadística de brechas.

verbose: valor lógico. Si es TRUE, se imprime el resultado del progreso. barfill, barcolor: color de relleno y color de contorno para barras

linecolor: color para líneas

print.summary: valor lógico. Si es verdadero, el número óptimo de clústeres se imprime en fviz_nbclust (). (RDocumentation, n.d.c)

Visualización del numero óptimo de clusters

La función R fviz_nbclust, genera un gráfico en el cual la ubicación de una curva (codo) el gráfico se considera generalmente como un indicador del número apropiado de clusters (Kassambara 2017).

Visualización de clusters de k-medias

Es una buena idea trazar los resultados del clúster, se pueden utilizar para evaluar la elección del número de clusters, así como la comparación de dos análisis de clusters diferentes.

La función fviz_cluster () [paquete factoextra] se puede utilizar para visualizar fácilmente k-medias clusters. Toma resultados de k-medias y los datos originales como argumentos. En la gráfica resultante, las observaciones se representan mediante puntos, utilizando componentes principales si el número de variables es mayor que 2. También es posible dibujar una elipse de concentración alrededor de cada grupo (Kassambara 2017).

Uso de la función fviz_cluster ()
fviz_cluster(
object,
data = NULL,
choose.vars = NULL,
stand = TRUE,
axes = c(1, 2),
geom = c("point", "text"),
 repel = FALSE,
 show.clust.cent = TRUE,
ellipse = TRUE,
ellipse.type = "convex",
llipse.level = 0.95,
ellipse.alpha = 0.2,
shape = NULL,
pointsize = 1.5,
labelsize = 12,
main = "Cluster plot",
xlab = NULL,
ylab = NULL,
outlier.color = "black",
outlier.shape = 19
outlier.pointsize = pointsize,
outlier.labelsize = labelsize,
ggtheme = theme_grey(),
)

object: un objeto de clase “partición” creado por las funciones pam (), clara () o fanny () en el paquete cluster; “kmeans” [en el paquete de estadísticas]; “dbscan” [en paquete fpc]; “Mclust” [en mclust]; “hkmeans,” “eclust” [in factoextra]. Los valores posibles también son cualquier objeto de lista con datos y componentes de clúster (por ejemplo: objeto = lista (datos = mydata, cluster = myclust)). data: los datos que se han utilizado para la agrupación. Solo es necesario cuando el objeto es una clase de kmeans o dbscan.

choose.vars: un vector de caracteres que contiene variables a considerar para el trazado.

stand: valor lógico; si es VERDADERO, los datos se estandarizan antes del análisis de componentes principales.

axes: un vector numérico de longitud 2 que especifica las dimensiones que se trazarán.

geom: un texto que especifica la geometría que se utilizará para el gráfico. Los valores permitidos son la combinación de c (“punto,” “texto”). Utilice “punto” (para mostrar solo puntos); “texto” para mostrar solo etiquetas; c (“punto,” “texto”) para mostrar ambos tipos.

repel: un booleano, ya sea para usar ggrepel para evitar sobretrazar las etiquetas de texto o no.

show.clust.cent: lógico; si es VERDADERO, muestra los centros del clúster

ellipse: valor lógico; si es VERDADERO, dibuja un contorno alrededor de los puntos de cada grupo

ellipse.type: Carácter que especifica el tipo de trama. Los valores posibles son ‘convexo,’ ‘confianza’ o tipos admitidos al stat_ellipseincluir uno de c (“t,” “norma,” “euclid”).

ellipse.level: el tamaño de la elipse de concentración en probabilidad normal. Aprobado por ggplot2::stat_ellipseel nivel. Ignorado en ‘convexo.’ El valor predeterminado es 0,95.

ellipse.alpha: Alfa para el marco que especifica el nivel de transparencia del color de relleno. Use alpha = 0 para ningún color de relleno.

shape: la forma de los puntos.

pointsize: el tamaño de los puntos

labelsize: tamaño de fuente para las etiquetas

main: título principal de la trama.

xlab, ylab: vector de caracteres que especifica las etiquetas de los ejes xey, respectivamente. Utilice xlab = FALSE y ylab = FALSE para ocultar xlab y ylab, respectivamente.

outlier.pointsize, outlier.color, outlier.shape, outlier.labelsize: argumentos para personalizar valores atípicos, que solo se pueden detectar en clústeres DBSCAN.

ggtheme: función, nombre del tema ggplot2. El valor predeterminado es theme_pubr (). Los valores permitidos incluyen temas oficiales de ggplot2: theme_gray (), theme_bw (), theme_minimal (), theme_classic (), theme_void (). (RDocumentation, n.d.d)

Cálculo de la agrupación en clústeres de k-medias.

Como el algoritmo de agrupamiento de k-medias comienza con k centroides seleccionados al azar, siempre es se recomienda usar la función set.seed () para establecer una semilla para el azar de R.

El siguiente código R realiza la agrupación de k-medias con k = 4:

library(stats)
set.seed ()
km.res <- kmeans(df, 4, nstart = 25)
print(km.res)

En donde km. res, es el nombre del objeto donde se almacenaran los resultados, y la función kmeans, puede usarse de manera simplificada, indicando el nombre de la data estandarizada y el número de clusters elegidos por el analista.

Como el resultado final del resultado de la agrupación de k-medias es sensible a las asignaciones iniciales aleatorias, especificamos nstart = 25. Esto significa que R probará 25 asignaciones iniciales aleatorias diferentes y luego seleccionará los mejores resultados correspondientes al que tenga la variación más baja dentro de la agrupación. El valor predeterminado de nstart en R es uno. Sin embargo, se recomienda encarecidamente calcular la agrupación en clústeres de k medias con un valor alto de nstart, como 25 o 50, para tener un resultado más estable.

Al hacer uso del comando print sobre el objeto generado con la funcion kmeans, se muestra, el numero de clusters generados y el tamaño de cada uno, además se muestra el clúster al cual pertenecen cada uno de los objetos u individuos (Kassambara 2017).

K-Medoides

El término medoide se refiere a un objeto dentro de un grupo para el cual la diferencia o disimilitud promedio entre él y todos los demás miembros del grupo es mínima, corresponde al punto más céntrico del grupo).

K-Medoides es un método de clustering muy similar a K-medias en cuanto a que ambos agrupan las observaciones en K clusters, donde K es un valor preestablecido por el analista. La diferencia es que, en K-Medoides, cada clúster está representado por una observación presente en el clúster (medoide), mientras que en K-medias, cada clúster está representado por su centroide, que se corresponde con el promedio de todas las observaciones del clúster pero con ninguna en particular.

Una definición más exacta del término Medoides: elemento dentro de un clúster cuya distancia (diferencia) promedio entre él y todos los demás elementos del mismo clúster es lo menor posible. Se corresponde con el elemento más central del clúster y por lo tanto puede considerarse como el más representativo. El hecho de utilizar Medoides en lugar de centroides hace de K-Medoides un método más robusto que K-means, viéndose menos afectado por outliers o ruido. A modo de idea intuitiva puede considerarse como la analogía entre media y mediana. (Amat 2017)

El algoritmo más empleado para aplicar K-Medoides se conoce como PAM (Partición alrededor de Medoides) y sigue los siguientes pasos:

  1. Seleccionar K observaciones aleatorias como medoides iniciales. También es posible identificarlas de forma específica.
  2. Calcular la matriz de distancia entre todas las observaciones si esta no se ha calculado anteriormente.
  3. Asignar cada observación a su medoide más cercano.
  4. Para cada uno de los clusters creados, comprobar si seleccionando otra observación como medoide se consigue reducir la distancia promedio del clúster, si esto ocurre, seleccionar la observación que consigue una mayor reducción como nuevo medoide.
  5. Si al menos un medoide ha cambiado en el paso 4, volver al paso 3, de lo contrario, se termina el proceso

A diferencia del algoritmo K-medias, en el que se minimiza la suma total de cuadrados intra-cluster (suma de las distancias al cuadrado de cada observación respecto a su centroide), el algoritmo PAM minimiza la suma de las diferencias de cada observación respecto a su medoide.

Por lo general, el método de K-medoides se utiliza cuando se conoce o se sospecha de la presencia de outliers. Si esto ocurre, es recomendable utilizar como medida de similitud la distancia de Manhattan, ya que es menos sensible a outliers que la euclídeana. (Amat 2017)

Paquetes y funciones de R requeridos para K-Medoides (PAM)

La función pam () [ paquete clúster ] y pamk () [ paquete fpc ] se pueden utilizar para calcular PAM La función pamk () no requiere que el usuario decida el número de clústeres K.

En los siguientes ejemplos, describiremos solo la función pam (), que simplificó el formato es:

pam(x, k, metric = "euclidean", stand = FALSE)

• x: los valores posibles incluyen: - Matriz de datos numéricos o marco de datos numéricos: cada fila corresponde a un observación, y cada columna corresponde a una variable. - Matriz de disimilitud: en este caso x es típicamente la salida de daisy () o dist ()

• k: el número de clústeres

• métric: la métrica de distancia que se utilizará. Las opciones disponibles son “euclidiana” y “Manhattan.”

• stand: valor lógico; si es verdadero, las variables (columnas) en x están estandarizadas antes calculando las diferencias. Se ignora cuando x es una matriz de disimilitudes. Para crear un hermoso gráfico de los clusters generados con la función pam (), utilizará el paquete factoextra.

La función pam () devuelve un objeto de clase pam cuyos componentes incluyen:

medoides: objetos que representan grupos

agrupación: un vector que contiene el número de agrupación de cada objeto.

Se puede acceder a cada uno de estos componentes utilizando el nombre del objeto creado con la función “pam,” seguido de un signo de dólar ($) y el nombre del componente que se desea extraer o visualizar (Kassambara 2017).

Estimación del número óptimo de clúster PAM

Para estimar el número óptimo de clústeres, usaremos el método de silueta promedio.

La idea es calcular el algoritmo PAM utilizando diferentes valores de los clusters k. A continuación, se dibuja la silueta de los clusters promedio de acuerdo con el número de clusters. La silueta promedio mide la calidad de un agrupamiento. Un ancho de silueta medio alto indica una buena agrupación. El número óptimo de clusters k es el que maximiza la silueta promedio en un rango de valores posibles para k

La función fviz_nbclust () [paquete factoextra] proporciona una solución conveniente para estimar el número óptimo de clústeres, dicha función se ha explicado con detalle anteriormente.

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

Para este caso a la función fviz_nbclust, se le ha pasado como argumento, la data estandarizada, se ha especificado la técnica a utilizar la cual es “pam” y el método para calculo óptimo de clusters que en este caso es el de silueta promedio (Kassambara 2017).

Visualización de clústeres PAM

Para visualizar los resultados de la partición, usaremos la función fviz_cluster () [factoextra paquete] , la cual ya se explicó anteriormente con detalles.

En este caso la función fviz_cluster (), dibuja un diagrama de dispersión de puntos de datos coloreados por números de grupo. Si los datos contienen más de 2 variables, el algoritmo de análisis de componentes principales (PCA) se utiliza para reducir la dimensionalidad de los datos. En este caso, los dos primeros principales se utilizan para trazar los datos. (Kassambara 2017)

Cálculo de la agrupación en clústeres PAM

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

pam.res <- pam (df, 2 )

En donde pam. res, es el nombre del objeto donde se almacenaran los resultados, y la función pam, puede usarse de manera simplificada, indicando el nombre de la data estandarizada y el número de clusters elegidos por el analista. (Kassambara 2017)

CLARA

En lugar de intentar encontrar los medoides empleando todos los datos a la vez, CLARA selecciona una muestra aleatoria de un tamaño determinado y le aplica el algoritmo de PAM (K-medoides) para encontrar los clusters óptimos acorde a esa muestra. Utilizando esos medoides se agrupan las observaciones de todo el set de datos. La calidad de los medoides resultantes se cuantifica con la suma total de las distancias entre cada observación del set de datos y su correspondiente medoide (suma total de distancias intra-clusters). CLARA repite este proceso un número predeterminado de veces con el objetivo de reducir el bias de muestreo. Por último, se seleccionan como clusters finales los obtenidos con aquellos medoides que han conseguido menor suma total de distancias. A continuación, se describen los pasos del algoritmo CLARA

Una de las limitaciones del método K-medoides-clustering (PAM) es que su algoritmo requiere mucha memoria RAM, lo que impide que se pueda aplicar cuando el set de datos contiene varios miles de observaciones. CLARA (Clustering Large Applications) es un método que combina la idea de K-medoides con el resampling para que pueda aplicarse a grandes volúmenes de datos. (Amat 2017)
El algoritmo CLARA es el siguiente:

  1. Se divide aleatoriamente el set de datos en n partes de igual tamaño, donde n es un valor que determina el analista.
  2. Para cada una de las n partes: 2.1 Aplicar el algoritmo PAM e identificar cuáles son los k medoids. 2.2 Utilizando los medoides del paso anterior agrupar todas las observaciones del set de datos. 2.3 Calcular la suma total de las distancias entre cada observación del set de datos y su correspondiente medoide (suma total de distancias intra-clusters).
  3. Seleccionar como clustering final aquel que ha conseguido menor suma total de distancias intra-clusters en el paso 2.3.

Funciones y paquetes R requeridos para CLARA

La función clara () [paquete de clúster] se puede utilizar para calcular CLARA . El formato simplificado es el siguiente:

clara(x, k, metric = "euclidean", stand = FALSE, 
samples = 5, pamLike = FALSE)

x : una matriz de datos numéricos o un marco de datos, cada fila corresponde a una observación, y cada columna corresponde a una variable. Se permiten valores perdidos (NA). • k : el número de conglomerados.

metric : la métrica de distancia que se utilizará. Las opciones disponibles son “euclidiana” y “Manhattan.” Las distancias euclidianas son la raíz de la suma de cuadrados de las diferencias, y Las distancias de Manhattan son la suma de las diferencias absolutas. Leer más sobre distancia medidas (Capítulo 3). Tenga en cuenta que la distancia de Manhattan es menos sensible a los valores atípicos.

stand: valor lógico; si es verdadero, las variables (columnas) en x están estandarizadas antes calculando las diferencias. Tenga en cuenta que se recomienda estandarizar variables antes de la agrupación.

samples: número de muestras que se extraerán del conjunto de datos. El valor predeterminado es 5 pero se recomienda un valor mucho mayor.

pamLike: lógico que indica si el mismo algoritmo en la función pam () debe ser usado. Esto debería ser siempre cierto.

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

medoids: objetos que representan grupos.

clustering: un vector que contiene el número de agrupación de cada objeto

sample: número de muestras que se extraerán del conjunto de datos. El valor predeterminado es 5, pero se recomienda un valor mucho mayor.

Se puede acceder a cada uno de estos componentes utilizando el nombre del objeto creado con la función clara, seguido de un signo de dólar ($) y el nombre del componente que se desea extraer o visualizar. (Kassambara 2017)

Estimación del número óptimo de clusters CLARA.

Para estimar el número óptimo de clústeres, es posible utilizar el método de silueta promedio como se describe en la técnica k-medoides (PAM).

La función fviz_nbclust () [ paquete factoextra ] proporciona una solución para facilitar este paso.

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

Para este caso a la función fviz_nbclust, se le ha pasado como argumento, la data estandarizada, se ha especificado la técnica a utilizar la cual es “clara” y el método para calculo óptimo de clusters que en este caso es el de silueta promedio. (Kassambara 2017)

Visualización de clusters CLARA

Para visualizar los resultados de la partición, usaremos la función fviz_cluster () [factoextrapaquete], la cual ya se explicó con detalle anteriormente.

La función fviz_cluster (), dibuja un diagrama de dispersión de puntos de datos coloreados por números de grupo. (Kassambara 2017)

Calcular CLARA en R

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

clara.res <- clara (df, 2, samples = 50 , pamLike = TRUE )
print (clara.res)

En donde clara.res, es el nombre del objeto donde se almacenaran los resultados, y la función clara, puede usarse de manera simplificada, indicando el nombre de la data estandarizada y el número de clusters elegidos por el analista y el número de muestras que se extraerán del conjunto de datos. (Kassambara 2017)

Técnicas jerárquicas

El agrupamiento jerárquico es una alternativa enfoque nativo para la creación de particiones en clústeres, para agrupar objetos basados en su similitud. A diferencia de la agrupación en clústeres de particiones, la agrupación jerárquica no requieren pre-especificar el número de clusters que se producirán. La agrupación jerárquica se puede subdividir en dos tipos:

• Agrupación aglomerativa en la que, cada observación se considera inicialmente como un racimo propio (hoja). Luego, los clústeres más similares se fusionan sucesivamente hasta que haya un solo gran clúster (raíz).

• Agrupación divisiva, es una operación inversa de la agrupación aglomerativa, comienza con la raíz, en que todos los objetos están incluidos en un grupo. Entonces el más heterogéneo Los conglomerados se dividen sucesivamente hasta que todas las observaciones se encuentran en su propio conglomerado.

El resultado de la agrupación jerárquica es una representación basada en árboles de los objetos, que también se conoce como dendrograma. (Kassambara 2017)

Algoritmo agrupación aglomerativa

La agrupación aglomerativa funciona de forma “de abajo hacia arriba.” Es decir, cada objeto se considera inicialmente como un grupo de un solo elemento (hoja). En cada paso del algoritmo, los dos grupos que son más similares se combinan en un nuevo grupo más grande (nodos). Este procedimiento se repite hasta que todos los puntos son miembros de un solo gran clúster (raíz). (Kassambara 2017)

La estructura resultante de un agrupamiento jerárquico aglomerativo se obtiene mediante un algoritmo sencillo:

  1. El proceso se inicia considerando cada una de las observaciones como un cluster individual, formando así la base del dendrograma (hojas).

  2. Se inicia un proceso iterativo hasta que todas las observaciones pertenecen a un único clúster:

2.1 Se calcula la distancia entre cada posible par de los n clusters. El investigador debe determinar el tipo de medida emplea para cuantificar la similitud entre observaciones o grupos (distancia y linkage).

2.2 Los dos clusters más similares se fusionan, de forma que quedan n-1 clusters.

  1. Determinar dónde cortar la estructura de árbol generada (dendrograma).

Algoritmo agrupación aglomerativa

La imagen muestra cómo se van sucediendo las agrupaciones a medida que avanzan las primeras iteraciones del algoritmo. (Amat 2017)

Pasos para la agrupación jerárquica aglomerativa en R

Seguiremos los pasos a continuación para realizar agrupaciones jerárquicas aglomerativas usando R software:

  1. Preparación de los datos
  2. Calcular información de (des) similitud entre cada par de objetos en los datos colocar.
  3. Uso de la función de vinculación para agrupar objetos en un árbol de clúster jerárquico, según la información de distancia generada en el paso 1. Objetos / grupos que están cerca proximidad se vinculan entre sí mediante la función de vinculación.
  4. Determinar dónde cortar el árbol jerárquico en grupos. Esto crea una partición de los datos. (Kassambara 2017)

Estructura y preparación de datos

Los datos deben ser una matriz numérica con:

  1. Filas que representan observaciones (individuos);
  2. Columnas que representan variables.
  3. Tenga en cuenta que, en general, se recomienda estandarizar las variables en el conjunto de datos antes realizar análisis posteriores. (Kassambara 2017)

Medidas de similitud

Para decidir qué objetos o grupos deben combinarse o dividirse, necesitamos métodos para medir la similitud entre objetos. Hay muchos métodos para calcular la información de similitud, incluidas las distancias euclidianas y de Manhattan.

En el software R, puede usar la función dist () para calcular la distancia entre cada par de objetos en un conjunto de datos. Los resultados de este cálculo se conocen como matriz de distancia o disimilitud. Por defecto, la función dist () calcula la distancia euclidiana entre objetos; sin embargo, es posible indicar otras métricas mediante el argumento “method.” (Kassambara 2017)

Función dist ()

Esta función calcula y devuelve la matriz de distancia calculada utilizando la medida de distancia especificada para calcular las distancias entre las filas de una matriz de datos.

Sintaxis:

dist(x, method = "euclidean", diag = FALSE, upper = FALSE, p = 2)

x: una matriz numérica, marco de datos u “dist”objeto.

method: la medida de distancia que se utilizará. Este puede ser “euclidean,” “maximum,” “manhattan,” “canberra,” “binary” or “minkowski.”

diag: valor lógico que indica si se debe imprimir la diagonal de la matriz de distancias print.dist.

upper: valor lógico que indica si el triángulo superior de la matriz de distancias debe imprimirse por print.dist.

p: el poder de la distancia de Minkowski.

(https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/dist?)

Métodos de vinculación

La función de vinculación toma la información de distancia, devuelta por la función dist (), y agrupa pares de objetos en grupos según su similitud. A continuación, estos grupos recién formados se vinculan entre sí para crear grupos más grandes. Este proceso se repite hasta que todos los objetos del conjunto de datos original están vinculados en un árbol jerárquico.

Por ejemplo, dada una matriz de distancia “res.dist” generada por la función dist (), la función base de R hclust () se puede utilizar para crear el árbol jerárquico.

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

En donde res.hc es el nombre del objeto donde se almaneceran los resultados

d: una estructura de disimilitud producida por la función dist ().

method: El método de aglomeración (vinculación) que se utilizará para calcular la distancia entre conglomerados. Los valores permitidos son: “ward.D,” “ward.D2,” “single,” “complete,” “average,” “mcquitty,” “median” o “centroid.”

Al ejecutar el comando print sobre el objeto generado con la función hclust, se muestra información básica,como lo es el tipo de metodo de vinculación que se está usando,la medida de distancia utilizada y el numero de objetos.

Sobre todo el objeto generado con la función hclust, servirá para generar un dendrograma, el cual es un diagrama de árbol que muestra los grupos que se forman al crear conglomerados de observaciones en cada paso y sus niveles de similitud. (Kassambara 2017)

Para que el proceso de agrupamiento pueda llevarse a cabo tal como indica el algoritmo anterior, es necesario definir cómo se cuantifica la similitud entre dos clusters. Es decir, se tiene que extender el concepto de distancia entre pares de observaciones para que sea aplicable a pares de grupos, cada uno formado por varias observaciones. A este proceso se le conoce como vinculación. A continuación, se describen los 5 tipos de vinculación más empleados y sus definiciones.

Vinculación máxima o completa: Se calcula la distancia entre todos los posibles pares formados por una observación del clúster A y una del clúster B. La mayor de todas ellas se selecciona como la distancia entre los dos clusters. Se trata de la medida más conservadora (maximal intercluster dissimilarity).

Vínculo mínimo o único: Se calcula la distancia entre todos los posibles pares formados por una observación del clúster A y una del clúster B. La menor de todas ellas se selecciona como la distancia entre los dos clusters. Se trata de la medida menos conservadora (minimal intercluster dissimilarity).".

Vinculación media o promedia: Se calcula la distancia entre todos los posibles pares formados por una observación del clúster A y una del clúster B. El valor promedio de todas ellas se selecciona como la distancia entre los dos clusters (mean intercluster dissimilarity).

Enlace centroide: Se calcula el centroide de cada uno de los clusters y se selecciona la distancia entre ellos como la distancia entre los dos clusters.

Método de varianza mínima de Ward: se trata de un método general. La selección del par de clusters que se combinan en cada paso del agrupamiento jerárquico aglomerativo, se basa en el valor óptimo de una función objetivo, pudiendo ser esta última cualquier función definida por el analista. El conocido método Ward es un caso particular en el que el objetivo es minimizar la suma total de varianza intra-cluster. En cada paso, se identifican aquellos dos clusters cuya fusión conlleva menor incremento de la varianza total intra-cluster. (Amat 2017)

La implementación en R de este método ha sido causa de confusiones. Si se emplea la función hclust() se tiene que especificar method = “ward.D2,” mientras que en la función agnes() es method = “ward”

Los métodos de vinculación completa, promedio y Ward suelen ser los preferidos por los analistas debido a que generan dendrogramas más compensados. Sin embargo, no se puede determinar que uno sea mejor que otro, ya que depende del caso de estudio en cuestión. (Kassambara 2017)

Algoritmo agrupación divisivo.

El algoritmo más conocido de agrupamiento jerárquico divisivo es DIANA (DIvisive ANAlysis Clustering). Este algoritmo se inicia con un único clúster que contiene todas las observaciones, a continuación, se van sucediendo divisiones hasta que cada observación forma un clúster independiente. En cada iteración, se selecciona el clúster con mayor diámetro, entendiendo por diámetro de un clúster la mayor de las diferencias entre dos de sus observaciones. Una vez seleccionado el clúster, se identifica la observación más dispar, que es aquella con mayor distancia promedio respecto al resto de observaciones que forman el clúster, esta observación inicia el nuevo clúster. Se reasignan las observaciones en función de si están más próximas al nuevo clúster o al resto de la partición, dividiendo así el clúster seleccionado en dos nuevos clusters.

  1. Todas las n observaciones forman un único clúster.
  2. Repetir hasta que hayan n clusters: 2.1 Calcular para cada clúster la mayor de las distancias entre pares de observaciones (diámetro del clúster). 2.2 Seleccionar el clúster con mayor diámetro. 2.3 Calcular la distancia media de cada observación respecto a las demás. 2.4 La observación más distante inicia un nuevo clúster 2.5 Se reasignan las observaciones restantes al nuevo clúster o al viejo dependiendo de cuál está más próximo.

A diferencia del clustering aglomerativo, en el que hay que elegir un tipo de distancia y un método de vinculación, en el clustering divisivo solo hay que elegir la distancia, no hay vinculación En el siguiente apartado se realizará el uso de todas las técnicas mencionadas hasta ahora, será interesante pues observar sobre todo gráficamente, la diferencia de los resultados entre cada técnica. (Amat 2017)

Dendrogramas.

Los dendrogramas corresponden a la representación gráfica del árbol jerárquico generado por la función hclust (), muestran los grupos que se forman al crear conglomerados de observaciones en cada paso y sus niveles de similitud. El nivel de similitud se mide en el eje vertical (alternativamente se puede mostrar el nivel de distancia) y las diferentes observaciones se especifican en el eje horizontal. (Minitab, n.d.)

Interpretación de un dendrograma.

Utilice el dendrograma para ver cómo se forman los conglomerados en cada paso y para evaluar los niveles de similitud (o distancia) de los conglomerados que se forman.

Para ver los niveles de similitud (o de distancia), coloque el puntero del ratón sobre una línea horizontal del dendrograma. El patrón de cómo los valores de similitud o de distancia cambian de un paso a otro puede ayudar a elegir la agrupación final para los datos. El paso donde los valores cambian de manera abrupta podría identificar un punto adecuado para definir la agrupación final.

La decisión acerca de la agrupación final también se conoce como cortar el dendrograma. Cortar el dendrograma es similar a trazar una línea a lo largo del dendrograma para especificar la agrupación final. También se pueden comparar diferentes agrupaciones finales en los dendrogramas para determinar cuál de ellas tiene más sentido para los datos

Dendrograma vinvulación completa, distancia euclideana

En la base del dendrograma, cada observación forma una terminación individual conocida como hoja o leaf del árbol. A medida que se asciende por la estructura, pares de hojas se fusionan formando las primeras ramas. Estas uniones (nodos) se corresponden con los pares de observaciones más similares. También ocurre que ramas se fusionan con otras ramas o con hojas. Cuanto más temprana (más próxima a la base del dendrograma) ocurre una fusión, mayor es la similitud. Esto significa que, para cualquier par de observaciones, se puede identificar el punto del árbol en el que las ramas que contienen dichas observaciones se fusionan. La altura a la que esto ocurre (eje vertical) indica cómo de similares o diferentes son las dos observaciones, cuanto mayor sea la altura de la fusión, menos similares serán los objetos. Esta altura se conoce como la distancia cofenética entre los dos objetos

Se observa que el primer conglomerado (extremo izquierdo) se compone de siete observaciones (las observaciones de filas 1, 3, 6, 9, 10, 11 y 15 de la hoja de trabajo). El segundo conglomerado, inmediatamente a la derecha, se compone de 3 observaciones (las observaciones de las filas 4, 12 y 19 de la hoja de trabajo). El tercer grupo se compone de 7 observaciones (las observaciones de las filas 2, 14, 17, 20, 18, 5 y 8). El cuarto conglomerado, en el extremo derecho, se compone de 3 observaciones (las observaciones de las filas 7, 13 y 16). Si se cortara el dendrograma más arriba, entonces habría menos conglomerados finales, pero su nivel de similitud sería menor. Si se cortara el dendrograma más abajo, entonces el nivel de similitud sería mayor, pero habría más conglomerados finales.

Los dendrogramas, se deben interpretar únicamente en base al eje vertical y no por las posiciones que ocupan las observaciones en el eje horizontal, esto último es simplemente por estética. (Minitab, n.d.)

Verificar el árbol resultante.

Una vez creado el dendrograma, hay que evaluar hasta qué punto su estructura refleja las distancias originales entre observaciones.

Tenga en cuenta que las conclusiones sobre la proximidad de dos objetos solo pueden extraerse basándose en la altura donde se fusionan las ramas que contienen esos dos objetos primero. No podemos usar la proximidad de dos objetos a lo largo del eje horizontal como criterio de similitud. Para identificar subgrupos, podemos cortar el dendrograma a una cierta altura

Después de vincular los objetos de un conjunto de datos en un árbol de clúster jerárquico, es posible que desee para evaluar que las distancias (es decir, las alturas) en el árbol reflejan las distancias originales precisamente Cuanto más se acerque el valor del coeficiente de correlación a 1, con mayor precisión será el La solución de agrupamiento refleja sus datos. Se considera que los valores superiores a 0,75 son buenos. Esta medida puede emplearse como criterio de ayuda para escoger entre los distintos métodos de linkage.

La función de base R cophenetic() se puede utilizar para calcular las distancias cofenéticas para agrupación jerárquica, mediante la siguiente sintaxis:

res.coph <- cophenetic(res.hc) 

En donde res.coph es el objeto dnde se almacenaran las distancias cofenéticas entre los objetos.

La función cophenetic de manera simplificada solo requiere el objeto generado anteriormente con la función hclust.

luego de calcularl la distancia cofenética, se calcula la correlación entre la distancia cofenética y la distancia original, mediante la función cor.

cor(res.dist, res.coph)

En donde la función cor, de manera simplificada requiere la matriz generada por la función dist (distancia original) y la matriz de distancia generada por la función cophenetic, como anteriormente se mencionó es deseable una correlación con valor superior a 0.75. (Kassambara 2017)

Cortar el árbol para generar los clusters.

Además de representar en un dendrograma la similitud entre observaciones, se tiene que poder identificar el número de clusters creados y qué observaciones forman parte de cada uno. Si se realiza un corte horizontal a una determinada altura del dendrograma, el número de ramas que sobrepasan (en sentido ascendente) dicho corte se corresponde con el número de clusters.

Dendrograma vinvulación completa, distancia euclideana, K= 2 y K= 4, (data:mtcars)

La imagen muestra que si se realiza el corte a la altura de 6 se obtienen dos clusters, mientras que si se hace a la de 4.5 se obtienen 4 clusters. (Amat 2017)

La función cutree() se puede utilizar para cortar un árbol, generado por la función hclust (), en varios grupos, de la siguiente forma.

# Cortar el árbol en 4 grupos 
grp <- cutree(res.hc, k = 4)

# Número de miembros en cada cluster  
table(grp)

# Obtenga los nombres de los miembros del clúster  1
rownames(df)[grp == 1]

En donde grp es el nombre del objeto donde se almacenarán los nombres de cada elemento o individuo, junto al número de clúster perteneciente, res.hc es el árbol generado por la función hclust y K=4, es el número de grupos (clusters).

utilizando la funcion table() sobre el objeto generado con la función cutree, se muestra el numero de miembros o individuos, pertenecientes a cada clúster.

se puede mostrar los nombres de los miembros o individuos de un grupo o clusters en específico utilizando la función rownames() sobre el objeto generado con la función cutree, se muestra el numero de miembros o individuos, pertenecientes a cada clúster, dicha función requiere, el nombre de la data estandarizada, seguido y entre corchetes del nombre del objeto donde se generados por la función cutree, indicando el número de clúster del cual se desea saber los nombre de los mimbros dentro de el.

El resultado de los cortes se puede visualizar fácilmente usando la función fviz_dend() [in factoextra] de la siguiente forma:

fviz_dend(res.hc, k = 4, 
cex = 0.5,
k_colors = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
color_labels_by_k = TRUE, 
rect = TRUE 
)

En donde de manera simplificada la función fviz_dend(), requiere como argumentos,el árbol generado por la función hclust, el tamaño de las etiquetas, los colores de las etiquetas para cada grupo y se indica que cada clúster quede encerrado por un rectángulo con el argumento rect= TRUE)

Corte de dendrograma, data:mtcars

De esta manera se puede visualizar facilmente los elementos o individuos por los que está formado cada clúster y se puede diferenciar cada clúster.

También podemos visualizar el resultado en un diagrama de dispersión. Las observaciones están representadas por puntos en la gráfica, utilizando el método de componentes principales, Usando la función fviz_cluster() [in factoextra ], de la siguiente forma:

fviz_cluster(list(data = df, cluster = grp),
 palette = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
 ellipse.type = "convex", 
 repel = TRUE, # Avoid label overplotting (slow) 
show.clust.cent = TRUE, ggtheme = theme_minimal())

En donde la función fviz_cluster(), de manera simplificada necesita como argumento, una lista, con el nombre de la data estandarizada y el objeto generado por la función cutree, ellipse.type mediante el argumento palette, se seleccionan los colores de preferencia para cada clúster, con el agrgumento ellipse.type, se selecciona la forma geométrica con la se desea que se visualizen los clusters, con el argumento repel se evita la superposición de etiquetas de los elemntos que conforma un clúster ,se indica mediante el argumento how.clust.cent, si se desea que se muestren los centro de cada clúster o no y se es escoge el tema de preferencia. (Kassambara 2017)

Agrupación jerárquica + proyección PCA,K= 4, data:mtcars

Paquete Cluster R

El de paquetes cluster(), facilita la realización de análisis de clústeres en R. Proporciona la función agnes () y diana () para calcular la agrupación aglomerativa y divisiva, respectivamente. Estas funciones realizan todos los pasos necesarios automaticamnete. No es necesario ejecutar la función scale (), dist () y hclust () por separado. (Kassambara 2017)

Agrupamiento aglomerativo

res.agnes <- agnes(df, 
stand = TRUE,
metric = "euclidean", # metric for distance matrix
method = "ward" # Linkage method
)

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

En donde res.agnes es el objeto generado por la función agnes(), la cual requiere como argumento el nombre de la data que se usará, mediante argumento stand= TRUE, la data queda estandariazada, con el argumento metric, se elige un media de distancia y con el argumento method, se especifica el metodo de vinculación.

por medio de la fviz_dend() se puede visualizar el dendrograma, dicha función como se ha mencionado anteriormente de manera simple, requiere como argumento el objeto generado con la función agnes, el tamaño de las etiquetas y el número de clusters. (Kassambara 2017)

Dendrograma, agrupamiento aglomerativo ,K= 4, data:mtcars

Agrupamiento divisivo

res.diana <- diana(df, # data matrix
stand = TRUE, # standardize the data
metric = "euclidean" # metric for distance matrix
)

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

Note que el agrupamiento divisivo requiere la misma estructura de código, con la unica diferencia que no se especifíca un metodo de vinculación. (Kassambara 2017)

Dendrograma, agrupamiento divisivo ,K= 4, data:mtcars

Comparación de dendrogramas

El paquete dendextend proporciona varias funciones para comparar dendrogramas. Aquí, nos centraremos en dos funciones:

tanglegram(): para la comparación visual de dos dendrogramas • y cor.dendlist() para calcular una matriz de correlación entre dendrogramas.

library(dendextend)

# Calcular matriz de distancias
res.dist <- dist (df, method = "euclidean" )

# Calcular 2 agrupaciones jerárquicas
hc1 <- hclust (res.dist, method = "average" )
hc2 <- hclust (res.dist, method = "ward.D2" )

# Crea dos dendrogramas
dend1 <- as.dendrogram(hc1)
dend2 <- as.dendrogram(hc2)

# Crea una lista para contener dendrogramas
dend_list <- dendlist (dend1, dend2)

# Comparación visual de los dendrogramas
tanglegram(dend1, dend2)

Se comienza definiendo una matriz de distancia, mediante la funcion dist, la cual requiere como argumento la data estandarizada y la especificación de una medida de distancia, posteriormente mediante la función hclus se crean dos agrupaciones jerarquicas utilizando un método de vinculacón distinto en cada una, luego se transformann los resultados como dendrogramas, con la función as.dendrogram, por ultimo se crea una lista mediante la función denlist la cual contendrá, las dos agrupaciones generadas anteriormente.

Comparación visual de los dendrogramas, método promedio y ward, data:mtcars

Tenga en cuenta que los nodos “únicos,” con una combinación de elementos que no están presentes en el otro árbol, están resaltados con líneas discontinuas.

Matriz de correlación entre una lista de dendrogramas

La función cor.dendlist(), se utiliza para calcular la correlación " Baker " o " Cophenetic "matriz entre una lista de árboles, de la siguiente forma:

# Matriz de correlación cofenética
cor.dendlist(dend_list, method = "cophenetic")

#Matriz de correlación de Baker
cor.dendlist(dend_list, method = "baker")

La correlación entre dos árboles también se puede calcular de la siguiente manera:

# Matriz de correlación cofenética
cor_cophenetic(dend1, dend2)

#Matriz de correlación de Baker
cor_bakers_gamma(dend1, dend2)

la función cor.dendlist, requiere como argumento, la lista que contiene los dendrogramas y el metodo que se desea usar, “cophenetic” o “baker,” como resultado se mostrá una matriz la cual contiene en la diagonal principal la correlación entre el mismo árbol y en los demas elementos de la matriz se muestra la corrlación entre los distintos arboles.

la función cor_cophenetic y cor_bakers_gamma, calculan la correlacion cofenética y de Baker, respectivamente, unicamente requieren como argumento los dendrogramas que se desean comparar.

El valor de la correlación puede oscilar entre -1 y 1. si el valor es 0 que significa que los dos árboles no son estadísticamente similares.

También es posible comparar simultáneamente varios dendrogramas. Un operador de encadenamiento %>% se usa para ejecutar múltiples funciones al mismo tiempo, de la siguiente forma:

# 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 correlación
dend_list <- dendlist("Complete" = dend1, "Single" = dend2,
"Average" = dend3, "Centroid" = dend4)
cors <- cor.dendlist(dend_list)

# Imprimir matriz de correlación
round(cors, 2)

Usando el operador pipe (%>%) se puede utilizar de forma multiple las funciones ya mencionadas anteriormente, creando diferentes dendrogrmas, con un metodo de vinculación distinto para cada uno, para realizar una comparación. Mediante la función dendlist, se crea una lista que contiene los distintos dendrogrogramas, dicha lista se utiliza como argumento en la función cor y se obtiene una matriz en donde la diagonal principal muestra la correlación entre el mismo arbol, elaborado con el mismo método de vinculación y en los demas elementos de la matriz se muestra la corrlación entre los distintos arboles, elabrados cada uno con un método de vinculación distinto. (Kassambara 2017)

Matriz de correlación , data:mtcars

Mediante la funcíon corrplot se puede visualizar la matriz de correlación de la siguiente forma:

# Visualizar la matriz de correlación
library(corrplot)
corrplot(cors, "pie", "lower")

La funcion corrplot, requiere unicamente como argmento la matriz de correlación generada con la función cor.

Gráfico de la matriz de correlación, data:mtcars

Visualización de dendrogramas

Como se describió anteriormente, un dendrograma es una representación basada en árbol de datos creados usando métodos de agrupamiento jerárquico. En este apartado, se proprociona el código R para visualizar y personalizar dendrogramas. Además, se muestra cómo guardar y hacer zoom en un dendrograma grande.

Para visualizar un dendrograma, puede usarse la función fviz_dend, la cual ya utilizamos anteriormente, para manipular dendrogramas se hace uso del paquete dendextend.

Puede usar los argumentos main, sub, xlab, ylab, de esta manera podemos añadir un titulo al dendrograma y a los ejes. (Kassambara 2017)

fviz_dend(res.hc, cex = 0.5,
main = "Dendrograma",
xlab = "Objectos", ylab = "Distancia", sub = "")

Dendrograma, data:mtcars

Se puede visuaizar un dendrograma horizontal, de la siguiente forma.

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

Dendrograma horizontal, data:mtcars

Se puede colorear las ramas por grupos y agregar un rectángulo alrededor de cada grupo, de la siguiente forma:

fviz_dend(res.hc, k = 4, # Cortar en cuatro grupos
cex = 0.5, # label size # tamaño de etiqueta
k_colors = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
color_labels_by_k = TRUE,  # etiquetas de color por grupos
rect = TRUE, # Agregar rectángulo alrededor de los grupos
rect_border = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
rect_fill = TRUE)

Dendrograma, K= 4, data:mtcars

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

Los valores permitidos para k_color incluyen paletas de cerveza del paquete RColorBrewer (p. Ej. “RdBu,” “Blues,” “Dark2,” “Set2,” . . ; ) y paletas de revistas científicas de ggsci R paquete (por ejemplo: “npg,” “aaas,” “lancet,” “jco,” “ucscgb,” “uchicago,” “simpsons” y “Rickandmorty”)

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

Dendrograma con tema diferente, K= 4, data:mtcars

Además, puede trazar un dendrograma circular usando la opción type = “circular,” de la siguiente forma:

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

Arbol circular, K= 4, data:mtcars

Para trazar un árbol filogénico, se usa type = “phylogenic” y repel = TRUE (para evitar superposición de etiquetas). Esta funcionalidad requiere el paquete R igraph.

require("igraph")
 fviz_dend(res.hc, k = 4, k_colors = "jco", 
type = "phylogenic", repel = TRUE)

Arbol filogénico, K= 4, data:mtcars

Si se desea hacer zoom en los primeros grupos, es posible usar la opción xlim e ylim para limitar el área de trazado. Por ejemplo, se escribe el código a continuación:

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

Zoom de un dendrograma, K= 4, data:mtcars

Para trazar un subárbol, seguiremos el siguiente procedimiento:

  1. Cree el dendrograma completo usando fviz_dend () y guarde el resultado en un objeto, llamado dend_plot por ejemplo

  2. Utilice la función base R cut.dendrogram () para cortar el dendrograma, en un determinado altura (h), en múltiples subárboles. Esto devuelve una lista con componentes$ upper y $lower , la primera es una versión truncada del árbol original, también de clase dendrograma, este último una lista con las ramas obtenidas al cortar el árbol, cada una de las cuales es un dendrograma.

  3. Visualice subárboles usando fviz_dend ().

El código R es el siguiente. cortar el dendrograma y visualizar la versión truncada. (Kassambara 2017):

# Cree un gráfico de todo el dendrograma y extraiga los datos del dendrograma
dend_plot <- fviz_dend (res.hc, k = 4, # Cortar en cuatro grupos
cex = 0.5, # tamaño de etiqueta
k_colors = "jco"
)
dend_data <- attr (dend_plot, "dendrogram") # Extraer datos de dendrograma
# Cortar el dendrograma a la altura h = 10
dend_cuts <- cut (dend_data, h = 10)
# Visualice la versión truncada que contiene tres ramas
fviz_dend (dend_cuts$upper)

dendrograma versión truncada, K= 4, data:mtcars

se puede visuzalizar el dendrograma completo de la siguiente forma:

# Trazar el dendrograma completo
prin (dend_plot) 

Dendrograma completo, K= 4, data:mtcars

Para dibujar los subarboles, se puede hacer siguiente forma (Kassambara 2017):

# Dibujar subarbol 1
fviz_dend(dend_cuts$lower[[1]], main = "sub-árbol 1")
# Dibujar sub arbol 2
fviz_dend(dend_cuts$lower[[2]], main = "Sub-árbol 2")

Sub-arboles 1 y 2 K= 4, data:mtcars

También puede trazar árboles circulares de la siguiente manera (Kassambara 2017):

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

Dendrograma circular, data:mtcars

Si se tiene un dendrograma grande, puede guardarse en una página PDF grande, que se puede ampliar sin perder resolución, de la siguiente forma (Kassambara 2017):

pdf("dendrogram.pdf", width=30, height=15) # Abrir un PDF
p <- fviz_dend(res.hc, k = 4, cex = 1, k_colors = "jco" ) # Hacer gráfico
print(p)
dev.off() # Cerrar el PDF

Manipulación de dendrogramas usando dendextend

El paquete dendextend proporciona funciones para cambiar fácilmente la apariencia de un dendrograma y para comparar dendrogramas. En esta sección usaremos el operador de encadenamiento (%>%) para simplificar nuestro código.

El operador de encadenamiento (%>%) se usa para reescribir múltiples operaciones de modo que se puedan leer de izquierda a derecha, de arriba a abajo. Por ejemplo, los resultados de los dos códigos R siguientes son equivalentes

El código R para crear un dendrograma usando un operador de encadenamiento es:

library(dendextend)
dend <- mtcars[1:5,] %>% # data
scale %>% # estandarizar data
dist %>% # calculate a distance matrix,
hclust(method = "ward.D2") %>% # Agrupación jerárquica
as.dendrogram # Convierte el objeto en un dendrograma.
plot(dend)

Funciones para personalizar dendrogramas: la función set () [en el paquete dendextend] se puede utilizar para cambiar los parámetros de un dendrograma.El formato es:

set(object, what, value

1.object : un objeto dendrograma

  1. what : un carácter que indica cuál es la propiedad del árbol que debe ser configurar o actualizar

  2. value : un vector con el valor a establecer en el árbol (el tipo de valor depende sobre “what”).

Ejemplo (Kassambara 2017):

library(dendextend)
# 1. Create a customized dendrogram
mycols <- c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07")
dend <- as.dendrogram(res.hc) %>%
set("branches_lwd", 1) %>% # Ancho de línea 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.Crear dendrograma
fviz_dend(dend)

Numeral 4

Del texto: Kassambara, A. (2017). Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning (Multivariate Analysis) (1st ed.) Desarrolle los ejemplos presentados en los capítulos: 4, 5, 6, 7, 8, 9.

Capítulo 4: K-Means Clustering

Datos

library(kableExtra)
# Cargando el set de Datos
data("USArrests")
# Estandarizando los Datos
df <- scale(USArrests)
# Muestra de las primeras 3 filas de Datos"
head(df, n = 3) %>%
  kable(caption = "**Tabla 2:** Muestra de la Data.",
        align = "c",
        digits = 2) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 2: Muestra de la Data.
Murder Assault UrbanPop Rape
Alabama 1.24 0.78 -0.52 0.00
Alaska 0.51 1.11 -1.21 2.48
Arizona 0.07 1.48 1.00 1.04
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.

Estimacion del Número Optimo de Clústeres

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

El gráfico anterior representa la varianza dentro de los clusters. Disminuye a medida que aumenta k, pero puede verse una curva (o “codo”) en k = 4. Esta curva indica que los clusters adicionales clusters adicionales más allá del cuarto tienen poco valor.. En la siguiente sección, clasificaremos las observaciones en 4 clusters.

Computación de Clústeres de k-medias

# Calculando k-medias con k = 4
set.seed(123)
km.res <- kmeans(df, 4, nstart = 25)
# Imprimiendo los Resultados
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"

Como el resultado final del clustering de k-means es sensible a las asignaciones iniciales aleatorias aleatorio, especificamos nstart = 25. Esto significa que R probará 25 asignaciones iniciales aleatorias diferentes y luego seleccionará el mejor resultado correspondiente a la que tenga la menor variación dentro del clúster. El valor por defecto de nstart como 25 o 50, para tener un resultado más estable.

Es posible calcular la media de cada una de las variables por clusters utilizando los datos originales:

aggregate(USArrests, by = list(cluster = km.res$cluster), mean) %>% 
  kable(caption = "**Tabla 3:** Media de las  variables por clúster",
        align = "c",
        digits = 2) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 3: Media de las variables por clúster
cluster Murder Assault UrbanPop Rape
1 13.94 243.62 53.75 21.41
2 3.60 78.54 52.08 12.18
3 5.66 138.88 73.88 18.78
4 10.82 257.38 76.00 33.19
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.

Para añadir las clasificaciones de puntos a los datos originales, se debe realizar lo siguiente:

dd <- cbind(USArrests, cluster = km.res$cluster)
head(dd) %>%
  kable(caption = "**Tabla 4:** Clasificación de puntos a los Datos Originales",
        align = "c",
        digits = 2) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning  en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 4: Clasificación de puntos a los Datos Originales
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
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.

Accediendo a los resultados de la función k-means ()

# Número de conglomerado para cada una de las observaciones
# Este vector de enteros (de 1:k) que indica el clúster al que se asigna cada punto se asigna
  head(km.res$cluster, 4) %>%
  kable(caption = "**Tabla 5:** Clúster asignado por Objeto",
        align = "c",
        digits = 2) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 5: Clúster asignado por Objeto
x
Alabama 1
Alaska 4
Arizona 4
Arkansas 1
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.
# Número de observaciones en cada clúster 
km.res$size
## [1]  8 13 16 13
# Medias de Cluster
km.res$centers %>%
  kable(caption = "**Tabla 6:** Media de los Grupos",
        align = "c",
        digits = 2, row.names = T) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 6: Media de los Grupos
Murder Assault UrbanPop Rape
1 1.41 0.87 -0.81 0.02
2 -0.96 -1.11 -0.93 -0.97
3 -0.49 -0.38 0.58 -0.26
4 0.70 1.04 0.72 1.28
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.

Visualizing k-means clusters
Si tenemos un conjunto de datos multidimensional, una solución es realizar Análisis de Componentes Principales (ACP) y trazar los puntos de datos según las primeras coordenadas de los dos componentes principales, como se puede ver a continuación

fviz_cluster(
  km.res,
  data = df,
  palette = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
  ellipse.type = "euclid",
  # Concentración de la Elipse
  star.plot = TRUE,
  # Agregar segmentos de centroides a los elementos
  repel = TRUE,
  # Etiqueta vacía anular en exceso (slow)
  ggtheme = theme_minimal()
)

Capítulo 5: K-Medoids

Estimación del número optimo de Clusteres

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

Como podemos obserbar en el gráfico, el número de conglomerados sugerido es 2. Porr lo tanto clasificaremos las observaciones en 2 clusters (grupos)

Cálculo de Clústeres PAM

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"

“Clustering Vector” Muestra el clúster o grupo que se asignara cada uno Clúster 1 o 2.
Para incluir las clasificaciones de puntos a los datos originales, realice lo siguiente:

dd <- cbind(USArrests, cluster = pam.res$cluster)
head(dd, n = 3) %>%
  kable(caption = "**Tabla 7:**Asignación de Clúster",
        align = "c",
        digits = 2, row.names = F) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 7:Asignación de Clúster
Murder Assault UrbanPop Rape cluster
13.2 236 58 21.2 1
10.0 263 48 44.5 1
8.1 294 80 31.0 1
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.

Accesando a los Resultados de la función PAM

# Clúster de Medoides: Nuevo México, Nebraska
# al usar  .medoids  Objetos que representan agrupaciones
pam.res$medoids %>%
  kable(
    caption = "**Tabla 8:** Medoides Nuevo México y Nebraska",
    align = "c",
    digits = 2,
    row.names = T
  ) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 8: Medoides Nuevo México y Nebraska
Murder Assault UrbanPop Rape
New Mexico 0.83 1.37 0.31 1.16
Nebraska -0.80 -0.83 -0.24 -0.51
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.
# Reproduce un vector con el Número de Grupos (Clúster) para cada objeto
head(pam.res$clustering)  %>%
  kable(caption = "**Tabla 9:** Número de Clúster Asignado",
        align = "c",
        digits = 2) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 9: Número de Clúster Asignado
x
Alabama 1
Alaska 1
Arizona 1
Arkansas 2
California 1
Colorado 1
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.

Visualizacion de los Clústeres PAM

fviz_cluster(
  pam.res,
  # Color de las Elipses
  palette = c("#00AFBB", "#FC4E07"),
  # Concentración de la Ellipse  
  ellipse.type = "t",
  # Evitar el exceso de etiqueta (slow)
  repel = T,
  ggtheme = theme_classic()
)

## Capítulo 6: CLARA - Clustering Large Applications
### Computing CLARA in R
#### Preparación y Formato de Datos
Aquí, generaremos el uso de un conjunto de datos aleatorios. Para que el resultado sea reproducible, empezamos utilizando la función set.seed() en este caso estableceremos una semilla de 1234

set.seed(1234)
# Generando 500 objetos, divididos dentro de 2 Clústeres.
df <- rbind(cbind(rnorm(200, 0, 8), rnorm(200, 0, 8)),
            cbind(rnorm(300, 50, 8), rnorm(300, 50, 8)))
# Nombrando Filas y columnas
colnames(df) <- c("x", "y")
rownames(df) <- paste0("S", 1:nrow(df))
# Vista preliminar de los Datos
head(df, nrow = 6) %>%
  kable(caption = "**Tabla 10:** Muestra de conjunto de datos aleatorios cun una semilla de 1234",
        align = "c",
        digits = 2) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base  en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 10: Muestra de conjunto de datos aleatorios cun una semilla de 1234
x y
S1 -9.66 3.88
S2 2.22 5.57
S3 8.68 1.48
S4 -18.77 5.61
S5 3.43 2.49
S6 4.05 6.08
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.

Paquetes y funciones Requeridos de R

#clara(x, k, metric = "euclidean", stand = FALSE,
#samples = 5, pamLike = FALSE)

Estimación del Número Optimo de Clústeres

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

En el gráfico anterior podemos obsevar el número de conglomerados sugerido es 2. Por lo tanto utilizaremos un K = 2.

Calculando CLARA

Calcularemos el Algoritmo PAM con K = 2 que es el número óptimo de Clúster.

# Calculando CLARA
clara.res <- clara(df, 2, samples = 50, pamLike = TRUE)
# Imprimiendo 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"

Para incluir clasificaciones de puntos a los datos originales

dd <- cbind(df, cluster = clara.res$cluster)
head(dd, n = 4) %>%
  kable(caption = "**Tabla 11:** Clasificaciones de Puntos a los Datos Originales",
        align = "c",
        digits = 2) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 11: Clasificaciones de Puntos a los Datos Originales
x y cluster
S1 -9.66 3.88 1
S2 2.22 5.57 1
S3 8.68 1.48 1
S4 -18.77 5.61 1
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.
# Al emplear $medoid muestra los elementos que representa 
clara.res$medoid %>%
  kable(caption = "**Tabla 12:** Elementos Representados",
        align = "c",
        digits = 4) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 12: Elementos Representados
x y
S121 -1.5311 1.1451
S455 48.3573 50.2335
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.
# Al  emplear $clustering devuelve  un vector que contiene el número de clúster de cada objeto
head(clara.res$clustering, 4) %>%
  kable(caption = "**Tabla 13:** Número de clúster por cada Objeto",
        align = "c",
        digits = 2) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 13: Número de clúster por cada Objeto
x
S1 1
S2 1
S3 1
S4 1
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.

Visualización de Clústeres CLARA

fviz_cluster(
  clara.res,
  ## Color de las Elipses
  palette = c("#00AFBB", "#FC4E07"),
  # Concentración de la Elipse
  ellipse.type = "t",
  geom = "point",
  pointsize = 1,
  ggtheme = theme_classic()
)

En el gráfico anterior vemos los resultados de la division o separación mostrando la dispersión por clúster.

Capítulo 7: Agglomerative Clustering

Estructura y preparación de los datos

# Cargando los Datos
data("USArrests")
# Estandarizando los Datos
df <- scale(USArrests)
# Mostrando las primeras 6 filas
head(df, nrow = 6) %>%
  kable(caption = "**Tabla 14:** Muestra de los Datos",
        align = "c",
        digits = 4) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 14: Muestra de los Datos
Murder Assault UrbanPop Rape
Alabama 1.2426 0.7828 -0.5209 -0.0034
Alaska 0.5079 1.1068 -1.2118 2.4842
Arizona 0.0716 1.4788 0.9990 1.0429
Arkansas 0.2323 0.2309 -1.0736 -0.1849
California 0.2783 1.2628 1.7589 2.0678
Colorado 0.0257 0.3989 0.8608 1.8650
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.

En este caso, se utilizaron los conjuntos de datos USArrests de la base R.

Medidas de similitud (semejanza)

# Calculando la Matriz de Disimilitud
# df = Datos Estandarizados
res.dist <- dist(df, method = "euclidean")
as.matrix(res.dist)[1:6, 1:6]  %>%
  kable(caption = "**Tabla 15:** Matriz de Semejanza",
        align = "c",
        digits = 2) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 15: Matriz de Semejanza
Alabama Alaska Arizona Arkansas California Colorado
Alabama 0.00 2.70 2.29 1.29 3.26 2.65
Alaska 2.70 0.00 2.70 2.83 3.01 2.33
Arizona 2.29 2.70 0.00 2.72 1.31 1.37
Arkansas 1.29 2.83 2.72 0.00 3.76 2.83
California 3.26 3.01 1.31 3.76 0.00 1.29
Colorado 2.65 2.33 1.37 2.83 1.29 0.00
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.

En la tabla anterior se muestran las 6 primeras filas y columnas de la matriz de distancia, para ver fácilmente la información de la distancia entre objetos, reformateamos los resultados de la función dist() en una matriz utilizando la función as.matrix(). En esta matriz, el valor en la celda formada por la fila i, la columna j, representa la distancia entre el objeto i y el objeto j en el conjunto de datos original.

Enlace

# Para crear el árbol jerárquico.
res.hc <- hclust(d = res.dist, method = "ward.D2")

Dendrograma

# cex: Tamaño de las Etiquetas
library("factoextra")
fviz_dend(res.hc, cex = 0.5)

En el dendrograma mostrado arriba, cada hoja corresponde a un objeto. A medida que avanzamos a medida que ascendemos en el árbol, los objetos que son similares entre sí se combinan en ramas, que se fusionan a su vez a una altura superior. La altura en el eje vertical, indica la (des)similitud/distancia entre dos objetos/grupos. Cuanto mayor sea la altura de la fusión, menos similares serán los objetos son. Esta altura se conoce como la distancia cofenética entre los dos objetos.

Verificar el árbol del clúster

# Calcular la Distancia Cofínica
res.coph <- cophenetic(res.hc)
# Correlación entre la distancia cofenética y la distancia original
cor(res.dist, res.coph)
## [1] 0.6975266
res.hc2 <- hclust(res.dist, method = "average")
cor(res.dist, cophenetic(res.hc2))
## [1] 0.7180382

El coeficiente de correlación que se muestra evidencia que el uso de un método de enlace diferente crea un árbol que representa las distancias originales de una forma ligeramente mejor.

Dividir el dendrograma en diferentes grupos

# Dividir el árbol en 4 grupos
grp <- cutree(res.hc, k = 4)
head(grp, n = 4)  %>%
  kable(caption = "**Tabla 16:** Arbol  dividido",
        align = "c",
        digits = 2) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 16: Arbol dividido
x
Alabama 1
Alaska 2
Arizona 2
Arkansas 3
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.
# Número de componentes en cada grupo (clúster)
table(grp)  %>%
  kable(caption = "**Tabla 17:** Componentes por Grupo o Clúster",
        align = "c",
        digits = 2) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 17: Componentes por Grupo o Clúster
grp Freq
1 7
2 12
3 19
4 12
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.
# Obtener los nombres de los miembros del grupo (clúster) 1
rownames(df)[grp == 1]  %>%
  kable(caption = "**Tabla 18:** Nombre de los miembros  del Grupo 1",
        align = "c",
        digits = 2) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 18: Nombre de los miembros del Grupo 1
x
Alabama
Georgia
Louisiana
Mississippi
North Carolina
South Carolina
Tennessee
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.

Como puede observarse en las tablas anteriores es posible cortar el árbol jerárquico a una altura determinada para dividir sus datos en clusters con la función base de R cutree(), se puede ver un vector que contiene el número de clúster de cada observación.

# Dividir en 4 grupos y colorear por grupos
fviz_dend(
  res.hc,
  # Número de Grupos = 4
  k = 4,
  # Tamaño de las Etiquetas
  cex = 0.5,
  # Color de las  Etiquetas por Grupos
  k_colors = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
  color_labels_by_k = TRUE,
  # Agregar Rectangulos alrededor de los Grupos
  rect = TRUE
)

En el dendrograma anterior se observa el resultado de los cortes, haciendo uso de la función fviz_dend().

fviz_cluster(
  list(data = df, cluster = grp),
  palette = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
  ellipse.type = "convex",
  # Concentración de la Elipse
  repel = TRUE,
  # Evitar el Exceso de Etiquetas (slow)
  show.clust.cent = FALSE,
  ggtheme = theme_minimal()
)

El gráfico de dispersión que puede obtenerse con la función fviz_cluster(), las observaciones se representan mediante puntos en el gráfico, utilizando componentes componentes principales. Se dibuja un marco alrededor de cada clúster.

##Paquete Cluster de R

library("cluster")
# Anidamiento Aglomerado (Agrupación Jerárquica)
res.agnes <- agnes(
  # Matriz de Datos
  x = USArrests,
  # Estandarizacion de los Datos
  stand = TRUE,
  # Métrica para la Matriz de Distancia
  metric = "euclidean",
  # Método de vinculación
  method = "ward"
)
# Análisis de Agrupación Divisivo
res.diana <- diana(x = USArrests,
                   stand = TRUE,
                   metric = "euclidean")
fviz_dend(res.agnes, cex = 0.6, k = 4) # no se muestra ej el libro

La salida anterior se obtiene de los cálculos de las funciones agnes() y diana() para calcular la agrupación aglomerativa y divisiva respectivamente. Estas funciones realizan todos los pasos necesarios, el dendrograma se obtiene con la función fviz_dend().

Capítulo 8: Comparación de dendrogramas.

Preparación de los Datos

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

Uso de la función sample() para seleccionar aleatoriamente 10 observaciones entre las 50 contenidas en el conjunto de datos.

Comparación de dendrogramas

library(dendextend)
# Calcular la matriz de distancia
res.dist <- dist(df, method = "euclidean")
# Calcular 2 agrupaciones jerárquicas
hc1 <- hclust(res.dist, method = "average")
hc2 <- hclust(res.dist, method = "ward.D2")
# Crear dos dendrogramas
dend1 <- as.dendrogram (hc1)
dend2 <- as.dendrogram (hc2)
# Crear una Lista para mantener los Dendrogramas
dend_list <- dendlist(dend1, dend2)

Comenzamos creando una lista de dos dendrogramas mediante el cálculo de la agrupación jerárquica utilizando dos métodos de vinculación diferentes (“average” y “ward.D.2”), con los resultados se crean dendrogramas, se crea una lista para contener ambos dendrogramas.

Comparación Visual de dos Dendrogramas

tanglegram(dend1, dend2)

tanglegram(
  dend1,
  dend2,
  # Líneas discontinuas de Apagado
  highlight_distinct_edges = FALSE,
  # Color de las Líneas de Apagado
  common_subtrees_color_lines = FALSE,
  # Color de las Ramas Comunes
  common_subtrees_color_branches = TRUE,
  main = paste("entanglement =", 
               round(entanglement(dend_list), 2)
  )
)

Matriz de Correlación entre una lista de Dendrogramas

# Matriz de Correlación Cofenética
cor.dendlist(dend_list, method = "cophenetic")
##           [,1]      [,2]
## [1,] 1.0000000 0.9925544
## [2,] 0.9925544 1.0000000
# Matriz de correlación de Baker
cor.dendlist(dend_list, method = "baker")
##           [,1]      [,2]
## [1,] 1.0000000 0.9895528
## [2,] 0.9895528 1.0000000
# Coeficiente de Correlación Cofenética, con este valor se puede obtener la correlación entre dos árboles.
cor_cophenetic(dend1, dend2)
## [1] 0.9925544
# Coeficiente de correlación de Baker
cor_bakers_gamma(dend1, dend2)
## [1] 0.9895528

Los valores cercanos a 0 significan que los dos árboles no son estadísticamente similares.

# Crear múltiples dendrogramas Encadenados
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 la matriz de correlación
dend_list <- dendlist(
  "Complete" = dend1,
  "Single" = dend2,
  "Average" = dend3,
  "Centroid" = dend4
)
cors <- cor.dendlist(dend_list)
# Imprimir Matriz de Correlación
round(cors, 2) %>%
  kable(
    caption = "**Tabla 19:**  Matriz de Correlación",
    align = "c",
    digits = 2,
    row.names = F
  ) %>%
  kable_classic(html_font = "Times New Roman",
                font_size = 14) %>%
  row_spec(0, bold = T) %>%
  footnote(general_title = "**Fuente**:",
           general = "Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.")
Tabla 19: Matriz de Correlación
Complete Single Average Centroid
1.00 0.46 0.45 0.30
0.46 1.00 0.23 0.17
0.45 0.23 1.00 0.31
0.30 0.17 0.31 1.00
Fuente:
Elaboración propia con base en Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning.

La tabla anterior realiza una comparación simultáneamente de varios dendrogramas. Un operador de encadenamiento %>% se utiliza para ejecutar varias funciones al mismo tiempo.

# Visualización la matriz de correlación utilizando el paquete corrplot
library(corrplot)
corrplot(cors, "pie", "lower")

## Capítulo 9: Visualización de Dendrogramas

# Calcular las distancias y la agrupación jerárquica
dd <- dist(scale(USArrests), method = "euclidean")
hc <- hclust(dd, method = "ward.D2")
# Para crear un dendrograma básico:
library(factoextra)
fviz_dend(hc, cex = 0.5)

#Puede utilizar los argumentos main, sub, xlab, ylab para cambiar los títulos de los gráficos como se muestra:
fviz_dend(hc, cex = 0.5, main = "Dendrogram - ward.D2", xlab = "Objects", ylab = "Distance", sub = "")

Se ha creado un dendrograma básico.

#Para dibujar un dendrograma horizontal, escriba esto:
fviz_dend(hc, cex = 0.5, horiz = TRUE)

Se obtuvo un dendrograma con orientación horizontal.

# Para colorear y añadir cuadro:
fviz_dend(hc, k = 4, # Cortar en cuatro grupos
cex = 0.5, # Tamaño de la etiqueta
k_colors = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
color_labels_by_k = TRUE, # etiquetas de color por grupos
rect = TRUE, # Añadir un rectángulo alrededor de los grupos
rect_border = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
rect_fill = TRUE)

Como puede obsevarse en la figuara anterior es posible colorear las ramas por grupos y añadir un rectángulo alrededor de cada grupo.

# Para cambiar el tema del gráfico.
fviz_dend(hc, k = 4, # Dividir en cuatro grupos
cex = 0.5, # tamaño de la etiqueta
k_colors = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
color_labels_by_k = TRUE, # etiquetas de color por grupos
ggtheme = theme_gray() # Cambiar tema
)

# cambio de los colores de los grupos usando "jco" (journal of clinical oncology).
fviz_dend(hc, cex = 0.5, k = 4, # Dividir en cuatro grupos
k_colors = "jco")

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

Se obtuvo un dendrograma horizontal con un rectángulo alrededor de los clusters.

# Dendrograma circular utilizando la opción tipo = "circular".
fviz_dend(hc, cex = 0.5, k = 4,
k_colors = "jco", type = "circular")

# Para trazar un árbol de tipo filogénico, utilice type = "phylogenic" y repel = TRUE (para evitar etiquetas de sobretrazado). 
require("igraph")
fviz_dend(hc, k = 4, k_colors = "jco",
type = "phylogenic", repel = TRUE)

require("igraph")
# Probando phylo.layout = "layout.gem"
fviz_dend(hc, k = 4, k_colors = "jco", type = "phylogenic", repel = TRUE,
phylo_layout = "layout.gem")

Caso de dendrograma con grandes conjuntos de datos

# Para ampliar los primeros clusters.
fviz_dend(hc, xlim = c(1, 20), ylim = c(1, 8))

Aquí puede observarse como utilizar la función de ampliar los primeros clusters, es posible utilizar la opción xlim e ylim para limitar el área del gráfico.

# Trazado de un subárbol de dendrogramas.
#Crear un gráfico de todo el dendrograma, y extraer los datos del dendrograma.
dend_plot <- fviz_dend(hc, k = 4, # Dividir en cuatro grupos
cex = 0.5, # Tamaño de la etiqueta
k_colors = "jco"
)
dend_data <- attr(dend_plot, "dendrogram") # Extraer los datos del dendrograma
# Corta el dendrograma a la altura h = 10
dend_cuts <- cut(dend_data, h = 10)
# Visualizar la versión truncada que contiene
# Dos ramas
fviz_dend(dend_cuts$upper)

Corte de dendrograma y visualizar la versión recortada.Primero se realiza una versión recortada del árbol original, también de la clase dendrograma, segundo, una lista con las ramas obtenidas al cortar el árbol, cada una de ellas es un dendrograma.

# Trazar el dendrograma completo
print(dend_plot)

# Trazar el subárbol 1
fviz_dend(dend_cuts$lower[[1]], main = "Subárbol 1")

# Trazar el subárbol 2
fviz_dend(dend_cuts$lower[[2]], main = "Subárbol 2")

# Trazando árboles circulares.
fviz_dend(dend_cuts$lower[[2]], type = "circular")

# Guardar el dendrograma en una página PDF grande
pdf("dendrogram.pdf", width=30, height=15) # Abrir un PDF
p <- fviz_dend(hc, k = 4, cex = 1, k_colors = "jco" ) # Hacer el trazado
print(p)
dev.off() # Cerrar el PDF
## png 
##   2

Manipulación de dendrogramas con dendextend

# Código R estándar para crear un dendrograma.
data <- scale(USArrests)
dist.res <- dist(data)
hc <- hclust(dist.res, method = "ward.D2")
dend <- as.dendrogram(hc)
plot(dend)

library(dendextend)
#  Código R para crear un dendrograma utilizando el operador de encadenamiento.
dend <- USArrests[1:5,] %>% # data
scale %>% # Escalar los datos
dist %>% # calcular una matriz de distancia,
hclust(method = "ward.D2") %>% # Agrupación jerárquica
as.dendrogram # Convierte el objeto en un dendrograma.
plot(dend)

En los dos gráficos anteriores se está haciendo uso del paquete dendextend que proporciona funciones para cambiar fácilmente la apariencia de un dendrograma y para comparar dendrogramas, ambos son equivalentes.

library(dendextend)
# 1. Crear un dendrograma personalizado
mycols <- c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07")
dend <- as.dendrogram(hc) %>%
set("branches_lwd", 1) %>% # Ramas de ancho de línea
set("branches_k_color", mycols, k = 4) %>% # Colorea las ramas por grupos
set("labels_colors", mycols, k = 4) %>%  # Etiquetas de colores por grupos
set("labels_cex", 0.5) # Cambiar el tamaño de la etiqueta
# 2. Crear gráfica
fviz_dend(dend)

Haciendo uso de las funciones para personalizar los dendrogramas: La función set() puede utilizarse para cambiar los parámetros de un dendrograma.

Referencias

Aldas Manzano, Joaquin, and Ezequiel Uriel Jimenez. 2017. Análisis Multivariante Aplicado Con r. Ediciones Paraninfo, SA.
Amat, J. 2017. “Clustering y Heatmaps: Aprendizaje No Supervisado.” Recuperado de Https://Rpubs. Com/Joaquin_AR/310338. https://www.cienciadedatos.net/documentos/37_clustering_y_heatmaps.
Cabarcos Fernández, Miriam. 2015. “Análisis Cluster. Una Aplicación Al Estudio de ı́Ndices de Bienestar a Través de Los Paı́ses.” https://ruc.udc.es/dspace/bitstream/handle/2183/16378/CabarcosFernandez_Miriam_TFG_2015.pdf?sequence=4.
De la Fuente Fernández, S. 2011. “Análisis Conglomerados Santiago de La Fuente Fernández.” Madrid. https://www.fuenterrebollo.com/Economicas/ECONOMETRIA/SEGMENTACION/CONGLOMERADOS/conglomerados.pdf.
Granada, Universidad de. 2015. “Método de análisis Multivariante: Análisis Clúster.” http://wpd.ugr.es/~bioestad/guia-spss/practica-8/.
Kassambara, Alboukadel. 2017. Practical Guide to Cluster Analysis in r: Unsupervised Machine Learning. Vol. 1. Sthda. https://xsliulab.github.io/Workshop/week10/r-cluster-book.pdf.
Minitab. n.d. “Dendrograma.” https://support.minitab.com/es-mx/minitab/18/help-and-how-to/modeling-statistics/multivariate/how-to/cluster-observations/interpret-the-results/all-statistics-and-graphs/dendrogram/.
RDocumentation. n.d.a. “Dist: Enhanced Distance Matrix Computation and Visualization.” https://www.rdocumentation.org/packages/factoextra/versions/1.0.7/topics/dist.
———. n.d.b. “Scale: Scaling and Centering of Matrix-Like Objects.” https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/scale.
———. n.d.c. https://www.rdocumentation.org/packages/factoextra/versions/1.0.7/topics/fviz_nbclust.
———. n.d.d. https://www.rdocumentation.org/packages/factoextra/versions/1.0.7/topics/fviz_cluster.