Portada

Universidad de El Salvador

Facultad de Ciencias Económicas

Escuela de Economía

Métodos para el Análisis Económico



Grupo teórico 03


Laboratorio 2:

“Análisis de Clúster (Conglomerados)”


Docente:

Carlos Ademir Pérez Alas


Integrantes:

Claros Ruiz, Jacqueline Vanessa

Flores Meléndez, Jennifer Saraí

Herrera Rumaldo, Erick Alexander

Menéndez Cerón, Hazel Zuriel

Rivas Flores, Karina Marcela


Ciudad universitaria, San Salvador, 25 de noviembre de 2022.




1. Análisis de conglomerados

También conocido como análisis de clúster es una técnica estadística multivariante que tiene la finalidad de agrupar elementos o variables de acuerdo a ciertas características que tienen en común, tratando de lograr la máxima homogeneidad en los elementos u observaciones dentro de ellos y la mayor diferencia o heterogeneidad entre los grupos.


El análisis de conglomerados nos va a permitir contestar a preguntas tales como:

  • ¿Es posible identificar cuáles son las empresas en las que sería más deseable invertir?
  • ¿Es posible identificar grupos de clientes a los que les pueda interesar un nuevo producto que una empresa va a lanzar al mercado?

  • Las etapas del Análisis de Conglomerados son las siguientes:

  • Elección de variables
  • Elección de la media de asociación
  • Elección de la técnica clúster
  • Validación de los resultados

  • 2. Resumen del Análisis de Clúster

    Resumen del Análisis Clúster
    Análisis de Clúster Técnicas Disponibles Ventajas Desventajas

    Jerárquico:
    Es un enfoque para agrupar objetos en función de su similitud. El clustering jerárquico no requiere que se especifique previamente el número de clusters que se van a producir. En los métodos jerárquicos, si un objeto es asignado a un determinado grupo no tiene posibilidad de ser reasignado a otro.

    El clustering jerárquico puede subdividirse en dos tipos:

    • La mayoría pertenecen a la categoría de la agrupación aglomerativa, es decir se parte fusionando los objetos más similares para formar pequeños conglomerados y progresivamente estos conglomerados se unen con otros objetos o conglomerados cada vez menos parecidos hasta terminar con los más diferentes juntándose en un solo grupo.

    • El clustering de división, inverso al clustering aglomerativo, en los que se parte de todos los objetos en un solo conglomerado para luego irlos dividiendo. Los métodos jerárquicos forman una estructura en forma de árbol árbol de clasificación o dendograma en el curso del análisis.

    • Maximum or complete linkage (Método del vecino más lejano o enlace completo).

    •Minimum or single linkage. (Método del vecino más próximo o Enlace simple).

    • Centroid linkage (Método del Centroide).

    • Método de Ward o Varianza mínima (Ward’s minimum variance method).

    • No exigen una definición previa del número de conglomerados.

    • El clustering jerárquico es fácil de implementar.

    • Permite obtener distintos tipos de resultados gráficos y numéricos que facilitan la interpretación de los resultados.

    • Pueden aplicarse sobre los casos y sobre las variables.

    • No hay manera de recuperarse de las decisiones incorrectas (no pueden deshacerse los pasos anteriores producidos).

    • La complejidad del tiempo para el clustering puede dar lugar a tiempos de cálculo muy largos.

    • Precisan una gran cantidad de cálculos, que en ocasiones limita la posibilidad de aplicación con muestras muy grandes.

    • Una mala partición no puede modificarse.

    No Jerárquico:

    Son métodos de agrupación utilizados para clasificar las observaciones, dentro de un conjunto de datos, en múltiples grupos basados en su similitud Los algoritmos requieren que el analista especifique el número de clústeres que se generarán. Están diseñados para la clasificación de individuos (no de variables) en K grupos. El procedimiento es elegir una partición de los individuos en K grupos e intercambiar los miembros de los clúster para tener una partición mejor.

    • K-means clustering.

    • K-medoids clustering o PAM (Partitioning Around Medoids.

    • El algoritmo CLARA (Clustering Large Applications)

    • Es menos afectado por la presencia de valores atípicos y por la presencia de variables irrelevantes, pudiendo ser aplicado a bases de datos grandes debido a que demanda menos trabajo de cómputo. Si hay muchas variables y los tamaños de muestra son mayores a 500 se recomienda este método.

    • Proporcionan los valores de los centroides de los grupos, lo que facilita la interpretación.

    • Ofrecen resultados adicionales que permiten seleccionar las variables para la interpretación de los conglomerados.

    • Exigen definir previamente el número de clusters.

    • Si se ordena nuevamente la data es muy posible que se obtengan salidas diferentes cada vez que la data se reordene.

    • Los resultados finales son sensibles a la selección aleatoria de clusters.

    • Una mala decisión inicial sobre el número y composición de los grupos ocasiona una errónea clasificación.
    Fuente: Elaboración propia con base en Kassambara, A. (2017). Practical Guide to Cluster Analysis in R: Unsupervised Machine Learning (Multivariate Analysis) y De la Fuente Fernández, S. (2011). Análisis de Conglomerados
    Elaboración propia con base en:
    1 (Kassambara, 2017)


    3. Técnicas disponibles para realizar el análisis de clúster

    3.1. Clustering jerárquico

    Los métodos jerárquicos o agrupamientos jerárquicos van generando grupos en cada una de las fases del proceso buscando el número de clúster para hacer una agrupación óptima. El agrupamiento jerárquico es capaz de fijar por si solos el número de clústers, por ello se pueden utilizar de forma exploratoria y posteriormente aplicar un análisis no jerárquico con el número de clúster ya fijado. (Calvo, 2018)

    Las estrategias para conseguir este objetivo se dividen en:

    • Clustering aglomerativo, aquí se considera inicialmente a cada observación como un clúster (hoja). Posteriormente, todos los clúster similares se juntan sucesivamente hasta que se crea un solo cruster grande (raíz).
    • Clustering disociativo, es lo contrario al aglomerativo, este comienza desde la raíz, donde todos los objetos están en un solo clúster. Posteriormente, los clusters más generales se van dividiendo hasta que todas las observaciones vuelven a su propio clúster.


    3.1.1. Clustering aglomerativo

    El algoritmo comienza tratando cada objeto como un clúster único. Luego, los clusters similares se fusionan sucesivamente hasta que todos los clusters se han fusionado en un gran clúster que contiene todos los objetos.

    Estas son algunas de las estrategias que pueden ser empleadas a la hora de unir los clusters en las diversas etapas o niveles de un procedimiento jerárquico. Ninguno de estos procedimientos proporciona una solución óptima para todos los problemas que se pueden plantear, ya que es posible llegar a distintos resultados según el método elegido. (Granada, 2017)

    • Vinculación máxima o completa: la distancia entre dos clusters se define como el valor máximo de todas las distancias por pares entre los elementos del clúster 1 y los elementos del clúster 2. Tiende a producir clusters más compactos.
    • Vinculación mínima o simple: la distancia entre dos clusters se define como el valor mínimo de todas las distancias por pares entre los elementos del clúster 1 y los elementos del clúster 2. Tiende a producir clusters largos y “sueltos”.
    • Vinculación media o promedio: la distancia entre dos clusters se define como la distancia media entre los elementos del clúster 1 y los elementos del clúster 2.
    • Vinculación del centro: la distancia entre dos conglomerados se define como la distancia entre el centroide del conglomerado 1 (un vector medio de longitud \(p\) variables) y el centroide del conglomerado 2.
    • Método de varianza mínima de Ward: minimiza la varianza total dentro del clúster. En cada paso, el par de clusters con la mínima distancia entre clusters se fusionan.


    3.1.1.1. Funciones:

    dist(): Distance Matrix Computation

    Para realizar un análisis de clúster jerárquico en R, el primer paso es calcular la matriz de distancia entre pares de distancia por pares utilizando la función dist().

    Esta función (del paquete “stats”) calcula y devuelve una matriz de distancia utilizando la medida de distancia especificada para calcular las distancias entre las filas de una matriz de datos. (RDocumentation, 2022c)

    Uso:

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

    Argumentos:

    • x: matriz numérica, un dataframe o un objeto “dist”.
    • method: medida de distancia a utilizar. Debe ser una de las siguientes: “euclidean”, “maximum”, “manhattan”, “canberra”, “binary” or “minkowski”. Se puede dar cualquier subcadena no ambigua.
    • diag: valor lógico que indica si la diagonal de la matriz de distancias debe ser impresa por print.dist.
    • upper: valor lógico que indica si el triángulo superior de la matriz de distancia debe ser impreso por print.dist.
    • p: potencia de la distancia de Minkowski.
    • m: objeto con la información de la distancia que debe convertirse en un objeto “dist”. Para el método por defecto, un objeto “dist”, o una matriz (de distancias) o un objeto que pueda ser coaccionado a tal matriz usando as.matrix(). (Solo se utiliza el triángulo inferior de la matriz, el resto se ignora).
    • digits, justify: para dar formato dentro de print().
    • right,…: otros argumentos, pasados a otros métodos.


    hclust(): Hierarchical Clustering

    El resultado anterior de la función “dist()” se utiliza por la función hclust() para producir el árbol jerárquico.

    hclust() es una función (del paquete “stats”) que genera un análisis jerárquico de conglomerados sobre un conjunto de disimilitudes y métodos para analizarlo. (RDocumentation, 2022f)

    Uso:

    hclust(d, method = "complete", members = NULL)

    Argumentos:

    • d: estructura de disimilitud como la producida por “dist”.
    • method: método de aglomeración a utilizar. Debe ser (una abreviatura inequívoca de) uno de los siguientes: “ward.D”, “ward.D2”, “single”, “complete”, “average” (= UPGMA), “mcquitty” (= WPGMA), “median” (= WPGMC) or “centroid” (= UPGMC).
    • members: NULL o un vector con un tamaño de longitud \(d\).
    • x: objeto del tipo producido por hclust.
    • hang: fracción de la altura del gráfico en la que las etiquetas deben aparecer por debajo del resto del gráfico. Si el valor es negativo hará que las etiquetas aparezcan por debajo de \(0\).
    • check: lógica que indica si se debe comprobar la validez del objeto \(x\). Esta comprobación no es necesaria cuando se sabe que \(x\) es válido, como cuando es el resultado directo de hclust(). El valor predeterminado es check=TRUE, ya que las entradas no válidas pueden hacer que R se bloquee debido a una violación de la memoria en el código interno de trazado de C.
    • labels: vector de caracteres de etiquetas para las hojas del árbol. Por defecto se utilizan los nombres o números de fila de los datos originales. Si labels=FALSE no se traza ninguna etiqueta.
    • axes, frame.plot, ann: indicadores lógicos como en plot.default.
    • main, sub, xlab, ylab: cadenas de caracteres para el título. sub y xlab tienen un valor por defecto no NULL cuando hay una llamada a \(tree\$call\).
    • Otros argumentos gráficos. Por ejemplo, cex controla el tamaño de las etiquetas (si se trazan) de la misma manera que el texto.


    Por último, se puede utilizar la función fviz_dend() (en el paquete factoextra) para obtener fácilmente un dendrograma. (RDocumentation, 2022e)

    fviz_dend(
      x,
      k = NULL,
      h = NULL,
      k_colors = NULL,
      palette = NULL,
      show_labels = TRUE,
      color_labels_by_k = TRUE,
      label_cols = NULL,
      labels_track_height = NULL,
      repel = FALSE,
      lwd = 0.7,
      type = c("rectangle", "circular", "phylogenic"),
      phylo_layout = "layout.auto",
      rect = FALSE,
      rect_border = "gray",
      rect_lty = 2,
      rect_fill = FALSE,
      lower_rect,
      horiz = FALSE,
      cex = 0.8,
      main = "Cluster Dendrogram",
      xlab = "",
      ylab = "Height",
      sub = NULL,
      ggtheme = theme_classic(),
      ...
    )

    Argumentos:

    • x: objeto de clase dendrograma, hclust, agnes, diana, hcut, hkmeans o HCPC (FactoMineR).
    • k: número de grupos para cortar el árbol.
    • h: valor numérico. Corta el dendrograma a la altura h. (k anula h)
    • k_colors, palette: vector que contiene los colores a utilizar para los grupos. Debe contener k número de colores. Los valores permitidos incluyen también “grey” para paletas color gris; paleta de colores, ejemplo, “RdBu”, “Blues”, …; y paletas de revistas científicas por el paquete de R ggsci, ejemplo: “npg”, “aaas”, “lancet”, “jco”, “ucscgb”, “uchicago”, “simpsons” y “rickandmorty”.
    • show_labels: valor lógico. Si es TRUE, se muestran las etiquetas de las hojas. El valor por defecto es TRUE.
    • color_labels_by_k: valor lógico. Si es TRUE, las etiquetas se colorean automáticamente por grupo cuando k != NULL.
    • label_cols: vector que contiene los colores de las etiquetas.
    • labels_track_height: valor numérico positivo para ajustar el espacio de las etiquetas. Se utiliza sólo cuando el type = “rectangle”.
    • repel: valor lógico. Se utiliza repel = TRUE para evitar el sobretrazado de las etiquetas cuando type = “phylogenic”
    • lwd: valor numérico que especifica el ancho de las ramas y de las líneas del rectángulo.
    • type: tipo de gráfico. Los valores permitidos son uno de los siguientes: “rectangle”, “triangle”, “circular”, “phylogenic”.
    • phylo_layout: el diseño que se utilizará para los árboles filogénicos. El valor por defecto es “layout.auto”. Los valores permitidos son: layout.auto, layout_with_drl, layout_as_tree, layout.gem, layout.mds y layout_with_lgl.
    • rect: valor lógico que especifica si se añade un rectángulo alrededor de los grupos. Sólo se utiliza cuando k!= NULL.
    • rect_border, rect_lty: color del borde y tipo de línea para los rectángulos.
    • rect_fill: valor lógico. Si es TRUE, rellena el rectángulo.
    • lower_rect: valor de cuán baja debe ser la parte inferior del rectángulo alrededor de los clusters. Se ignora cuando rect = FALSE.
    • horiz: valor lógico. Si es TRUE, se dibuja un dendrograma horizontal.
    • cex: tamaño de las etiquetas.
    • main, xlab, ylab: títulos principales y de los ejes.
    • sub: subtítulo del gráfico. Si es NULL, se muestra el método de agrupación jerárquica utilizado. Para eliminar el subtítulo utilice sub = ““.
    • ggtheme: función, nombres de temas de ggplot2. El valor por defecto es theme_classic(). Los valores permitidos incluyen los temas oficiales de ggplot2: theme_gray(), theme_bw(), theme_minimal(), theme_classic(), theme_void(), ….
    • otros argumentos a pasar a la función plot.dendrogram()


    También es posible cortar el árbol a una altura determinada para dividir los datos en múltiples grupos (función cutree()). (RDocumentation, 2022b)

    cutree(tree, k = NULL, h = NULL)

    Argumentos:

    • tree: árbol tal y como lo produce hclust. cutree() una lista con los componentes merge, height y labels, de contenido apropiado cada uno.
    • k: escalar o vector entero con el número deseado de grupos
    • h: escalar numérico o vector con las alturas en las que debe cortarse el árbol.


    3.1.2. Clustering disociativo

    Los métodos disociativos, constituyen el proceso inverso a los aglomerativos. Comienzan con un conglomerado que engloba a todos los casos tratados y, a partir de este grupo inicial, a través de sucesivas divisiones, se van formando grupos cada vez menores. Al final del proceso se tienen tantas agrupaciones como casos han sido tratados. (Granada, 2017)

    En cuanto a la clasificación de estos métodos se puede decir que es la misma que el de los métodos aglomerativos, si bien, como es lógico, al partir de un grupo único que hay que subdividir, se seguirá la estrategia de maximizar las distancias, o minimizar las similaridades, puesto que se busca ahora los individuos menos similares para separarlos del resto del conglomerado.


    3.2. Clustering no jerárquico

    Los métodos no jerárquicos categorizan los elementos según un número de clúster dado. Necesitan que el número de particiones esté fijado a priori.

    Los clústeres no jerárquicos más utilizados son: (Kassambara, 2017)

    • K-means clustering (MacQueen, 1967), en el que, cada clúster está representado por el centro o la media de los puntos de datos que pertenecen al clúster. El método K-means es sensible a los puntos de datos anómalos y a los valores atípicos.
    • K-medoids clustering o PAM (Partitioning Around Medoids, Kaufman & Rousseeuw, 1990), en el que, cada clúster está representado por uno de los objetos del clúster. PAM es menos sensible a los valores atípicos en comparación con k-means.
    • El algoritmo CLARA (Clustering Large Applications), que es una extensión de PAM adaptada para grandes conjuntos de datos.


    3.2.1. K-Means Clustering

    El objetivo de este método (del paquete de stats) es dividir el conjunto de objetos en un número predefinido (\(k\)) de clusters. El criterio para esta subdivisión es normalmente la mínima dispersión dentro de los clusters, por ejemplo, la mínima suma de cuadrados de las distancias desde el vector medio (centroide) del clúster. Una solución directa y rigurosa a este problema requiere la comprobación de un número innecesario de subdivisiones de datos. La agrupación k-means es un método heurístico rápido que proporciona una solución razonablemente buena, aunque no es muy óptima. (Statistics Education, 2022)

    El algoritmo K-means puede realizarse con los siguientes pasos (Guide, 2022):

    1. El analista especifica el número de clusters (\(K\)) que se van a crear.
    2. Se seleccion aleatoriamente \(k\) objetos del conjunto de datos como centros de clústeres iniciales o medios.
    3. Se asigna a cada observación a su centroide más cercano, basándose en la distancia euclidiana entre el objeto y el centroide.
    4. Para cada uno de los \(k\) clusters, se actualiza el centroide del clúster calculando los nuevos valores medios de todos los puntos de datos del clúster. El centoide de un \(Kº\) clúster es un vector de longitud \(p\) que contiene las medias de todas las variables para las observaciones en el \(kº\) clúster; \(p\) es el número de variables.
    5. Luego se minimiza repetidamente el total dentro de la suma de cuadrados. Es decir, repetir los pasos 3 y 4 hasta que las asignaciones de los clusters dejen de cambiar o se alcance el número máximo de iteraciones. Por defecto, el software R utiliza \(10\) como valor del número máximo de iteraciones.
    Uso:

    Por ejemplo, para agrupar los datos en dos clusters (centers = 2). La función kmeans también tiene la opción nstart que intenta múltiples configuraciones iniciales e informa la mejor. Por ejemplo, con nstart = 25 se generarán \(25\) configuraciones iniciales. Este enfoque se recomienda a menudo. (Guide, 2022)

    kmeans(df, centers = 2, nstart = 25)

    Argumentos:

    • x: matriz numérica, marco de datos numérico o vector numérico.
    • centers: número que se ha establecido como \(K\) clústeres iniciales.
    • iter.max: número máximo de iteraciones permitido. El valor por defecto es \(10\).
    • nstart: número de particiones iniciales aleatorias cuando los centros son un número. Se suele recomendar nstart > 1.

    Resultados que se obtienen:

    • cluster: vector de enteros (de 1:k) que indica el clúster al que se asigna cada punto.
    • centers: matriz de centros de clúster.
    • totss: suma total de cuadrados.
    • withinss: vector de la suma de cuadrados dentro del clúster, un componente por clúster.
    • tot.withinss: suma total de cuadrados dentro del clúster, es decir, sum(withinss).
    • betweenss: suma de cuadrados entre grupos, es decir, totss-tot.withinss.
    • size: número de puntos en cada clúster.


    Se podrá usar la función fviz_nbclust (paquete factoextra) para determinar y visualizar el número óptimo de conglomerados utilizando diferentes métodos: sumas de cuadrados dentro del conglomerado, silhouette y gap statistics. (RDocumentation, 2022d)

    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,
      ...
    )

    Argumentos:

    • x: matriz numérica o dataframe.
    • FUNcluster: función de partición que acepta como primer argumento una matriz (de datos) como \(x\) y como segundo argumento el número de clusters deseado.
    • method: método que se utilizará para estimar el número óptimo de clusters. Los valores posibles son “silhouette” (para la anchura media de la silueta), “wss” (para el total dentro de la suma de cuadrados) y “gap_stat” (para la estadística de huecos).
    • diss: objeto dist producido por dist(), es decir: diss = dist(x, method = “euclidean”). Se utiliza para calcular la anchura media de la silueta de los conglomerados, la suma interna del cuadrado y la agrupación jerárquica. Si es NULL, dist(x) se calcula con el método por defecto = “euclidiano”
    • k.max: número máximo de clusters a considerar, debe ser al menos dos.
    • nboot: número de muestras de Monte Carlo (“bootstrap”). Se utiliza sólo para determinar el número de conglomerados utilizando el estadístico gap.
    • verbose: valor lógico. Si es TRUE, se imprime el resultado del progreso.
    • barfill, barcolor: color de relleno y color de contorno para las barras.
    • linecolor: color para las líneas.
    • print.summary: valor lógico. Si es TRUE, el número óptimo de clusters se imprime en fviz_nbclust().
    • otros argumentos para FUNcluster()


    También, después de calcular el clustering de k-means, se puede utilizar la función de fviz_cluster() (paquete factoextra) para visualizar los resultados. Donde km.res son los resultados de k-means y data es el conjunto de datos originales. (Kassambara, 2017)

    fviz_cluster(km.res, data)


    3.2.2. K-Medoids (PAM)

    El algoritmo K-medoids, PAM, es una alternativa robusta a k-means para dividir un conjunto de datos en clusters de observación. (Kassambara, 2017)

    En el método k-medoids, cada clúster está representado por un objeto seleccionado dentro del clúster. Los objetos seleccionados se denominan medoides y corresponden a los puntos más céntricos dentro del clúster. El método de clustering k-medoids más común es el algoritmo PAM (en paquete cluster).

    El algoritmo PAM puede realizarse con los siguientes pasos:

    1. Seleccionar \(k\) objetos para que se conviertan en los medoides, o en caso de que se proporcionen estos objetos utilizarlos como medoides.
    2. Calcular la matriz de disimilitud si no se ha proporcionado.
    3. Asignar cada objeto a su medoide más cercano.
    4. Para cada clúster se buscará si alguno de los objetos del clúster disminuye el coeficiente de disimilitud medio; si lo hace, se selecciona la entidad que más disminuye este; si lo hace, se selecciona la entidad que más disminuye este coeficiente como el medoide para este clúster.
    5. Si al menos un medoide ha cambiado, pasar a (3), si no, terminar el algoritmo.

    Uso:

    pam(x, k, diss = inherits(x, "dist"),
        metric = c("euclidean", "manhattan"), 
        medoids = if(is.numeric(nstart)) "random",
        nstart = if(variant == "faster") 1 else NA,
        stand = FALSE, cluster.only = FALSE,
        do.swap = TRUE,
        keep.diss = !diss && !cluster.only && n < 100,
        keep.data = !diss && !cluster.only,
        variant = c("original", "o_1", "o_2", "f_3", "f_4", "f_5", "faster"),
        pamonce = FALSE, trace.lev = 0)

    Argumentos: (RDocumentation, 2022g)

    • x: matriz de datos o dataframe.
    • k: entero positivo que especifica el número de conglomerados, menor que el número de observaciones.
    • diss: indicador lógico: si es TRUE (predeterminado para objetos de disimilitud o disimilitud), entonces \(x\) se considerará como una matriz de disimilitud. Si es FALSE, entonces \(x\) se considerará como una matriz de observaciones por variables.
    • metric: cadena de caracteres que especifica la métrica que se utilizará para calcular las diferencias entre las observaciones.
    • medoids: NULL (predeterminado) o vector de length-k de índices enteros (en 1:n) que especifica medoids iniciales en lugar de usar el algoritmo de “construcción”.
    • nstart: se usa solo cuando medoids = “random”: especifica el número de “starts” aleatorios.
    • stand: si es TRUE, las medidas en x se estandarizan antes de calcular las diferencias.
    • cluster.only: si es TRUE, solo se calculará y devolverá la agrupación.
    • do.swap: indica si la fase de intercambio debe ocurrir. El valor predeterminado, TRUE, corresponde al algoritmo original.
    • keep.diss, keep.data: indica si las diferencias y/o los datos de entrada \(x\) deben mantenerse en el resultado. Configurarlos en FALSE puede dar resultados mucho más pequeños.
    • variant: cadena de caracteres que indica la variante del algoritmo PAM a utilizar.
    • trace.lev: especifica un nivel de seguimiento para imprimir diagnósticos durante la fase de creación e intercambio del algoritmo.


    El algoritmo PAM requiere que el usuario conozca los datos y que indique el número adecuado de clusters que debe producir. Esto puede estimarse mediante la función fviz_nbclust (en el paquete R factoextra), los argumentos de la función están explicados en el anterior apartado.

    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,
      ...
    )


    Después de realizar el clustering PAM, se puede utilizar la función de R fviz_cluster() (paquete factoextra) para visualizar los resultados. El formato es fviz_cluster(pam.res), donde pam.res es el resultado de PAM. (Kassambara, 2017)

    fviz_cluster(pam.res)


    3.2.3. CLARA - Clustering Large Applications

    El algoritmo CLARA (Clustering Large Applications) (en paquete de clúster) es una extensión del método de agrupamiento PAM (Partitioning Around Medoids) para grandes conjuntos de datos. Con este se obtiene una pequeña muestra. La calidad de los medoides resultantes se mide por la diferencia promedio entre cada objeto en el conjunto de datos completo y el medoide de su grupo. (Kassambara, 2017)

    El algoritmo CLARA puede realizarse con los siguientes pasos:

    1. Se divide aleatoriamente los conjuntos de datos en múltiples subconjuntos con tamaño fijo (sampsize).
    2. Se calcula el algoritmo PAM en cada subconjunto y se elije los \(k\) objetos representativos correspondientes (medoids). Luego se asigna cada observación del conjunto de datos completo al medoide más cercano.
    3. Posteriormente se calcula la media (o la suma) de las diferencias de las observaciones a su medoid más cercano. Esto se utiliza como una medida de la bondad de la agrupación.
    4. Por último se conserva el conjunto de subdatos para el que la media (o la suma) es mínima. Se lleva a cabo un análisis adicional en la partición final.

    Uso:

    clara(x, k, metric = c("euclidean", "manhattan", "jaccard"),
          stand = FALSE, cluster.only = FALSE, samples = 5,
          sampsize = min(n, 40 + 2 * k), trace = 0, medoids.x = TRUE,
          keep.data = medoids.x, rngR = FALSE, pamLike = FALSE, correct.d = TRUE)

    Argumentos: (RDocumentation, 2022a)

    • x: matriz de datos o dataframe.
    • k: número de clústeres.
    • metric: cadena de caracteres que especifica la métrica que se utilizará para calcular las diferencias entre las observaciones. Las opciones disponibles son “euclidean”, “manhattan” y “jaccard”.
    • stand: indica si las medidas en \(x\) están estandarizadas antes de calcular las diferencias.
    • cluster.only: si es TRUE, solo se calculará y devolverá la agrupación.
    • samples: número de muestras que se extraerán del conjunto de datos. El valor predeterminado, \(N = 5\), es considerado pequeño, se recomienda establecer muestras un orden de magnitud mayor.
    • sampsize: número de observaciones en cada muestra. Sampsize debe ser mayor que el número de conglomerados \((k)\) y como máximo el número de observaciones (nrow(x)).
    • trace: indica un nivel de seguimiento para la salida de diagnóstico durante el algoritmo.
    • medoids.x: indica si se deben devolver los medoids, de forma idéntica a algunas filas de los datos de entrada \(x\). Si es FALSO, keep.data también debe ser falso, y los índices medoids, es decir, los números de fila de los medoides aún se devolverán (componente i.med).
    • keep.data: indica si los datos deben mantenerse en el resultado.
    • rngR: indica lógicamente si se debe usar el generador de números aleatorios de R en lugar del primitivo integrado clara().
    • pamLike: indica si la fase de “swap” debe usar el mismo algoritmo que pam().


    Como casi todos los algoritmos de partición, requiere que el usuario especifique el número apropiado de clústeres que se producirán. Esto se puede estimar utilizando la función fviz_nbclust (en el paquete R factoextra). (Kassambara, 2017)

    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,
      ...
    )


    Después de calcular CLARA, se puede usar la función de fviz_cluster() (paquete factoextra) para visualizar los resultados. El formato es fviz_cluster(clara.res), donde clara.res son los resultados de CLARA. (Kassambara, 2017)

    fviz_cluster(clara.res)


    4. Ejemplos

    Capítulo 4

    Datos

    data("USArrests") # Cargando el conjunto de datos
    df <- scale(USArrests) # Escalando los datos
    # Ver las primeras 3 filas del encabezado de los datos
    head(df, n = 3)
    ##             Murder   Assault   UrbanPop         Rape
    ## Alabama 1.24256408 0.7828393 -0.5209066 -0.003416473
    ## Alaska  0.50786248 1.1068225 -1.2117642  2.484202941
    ## Arizona 0.07163341 1.4788032  0.9989801  1.042878388

    Estimación del número óptimo de conglomerados:

    La función de R fviz_nbclust() (Paquete FactoExtra) proporciona una solución conveniente para estimar el número óptimo de clústeres.

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

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

    Cálculo de agrupamiento de k-medias:

    # Calcula k-medias con k = 4
    set.seed(123)
    km.res <- kmeans(df, 4, nstart = 25)

    Como el resultado final del agrupamiento de k-medias es sensible al inicio aleatorio de asignaciones, especificamos \(nstart = 25\). Esto significa que R probará \(25\) diferentes asignaciones aleatorias, tareas de inicio y luego seleccionará los mejores resultados correspondientes a la que tiene la más baja dentro de la variación del conglomerado. El valor predeterminado de nstart en R es uno. Pero Se recomienda enfáticamente calcular el agrupamiento de k-means con un gran valor de nstart con \(25\) o \(50\), para tener un resultado más estable.

    # Imprimir 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"

    Es posible calcular la media de cada variable por grupos utilizando los datos originales:

    aggregate(USArrests, by=list(cluster=km.res$cluster), mean)
    ##   cluster   Murder   Assault UrbanPop     Rape
    ## 1       1 13.93750 243.62500 53.75000 21.41250
    ## 2       2  3.60000  78.53846 52.07692 12.17692
    ## 3       3  5.65625 138.87500 73.87500 18.78125
    ## 4       4 10.81538 257.38462 76.00000 33.19231
    # Si desea agregar las clasificaciones de puntos a los datos originales
    dd <- cbind(USArrests, cluster = km.res$cluster)
    head(dd)
    ##            Murder Assault UrbanPop Rape cluster
    ## Alabama      13.2     236       58 21.2       1
    ## Alaska       10.0     263       48 44.5       4
    ## Arizona       8.1     294       80 31.0       4
    ## Arkansas      8.8     190       50 19.5       1
    ## California    9.0     276       91 40.6       4
    ## Colorado      7.9     204       78 38.7       4

    Acceso a los resultados de la función kmeans():

    # Número de conglomerado para cada una de las observaciones
    km.res$cluster
    ##        Alabama         Alaska        Arizona       Arkansas     California 
    ##              1              4              4              1              4 
    ##       Colorado    Connecticut       Delaware        Florida        Georgia 
    ##              4              3              3              4              1 
    ##         Hawaii          Idaho       Illinois        Indiana           Iowa 
    ##              3              2              4              3              2 
    ##         Kansas       Kentucky      Louisiana          Maine       Maryland 
    ##              3              2              1              2              4 
    ##  Massachusetts       Michigan      Minnesota    Mississippi       Missouri 
    ##              3              4              2              1              4 
    ##        Montana       Nebraska         Nevada  New Hampshire     New Jersey 
    ##              2              2              4              2              3 
    ##     New Mexico       New York North Carolina   North Dakota           Ohio 
    ##              4              4              1              2              3 
    ##       Oklahoma         Oregon   Pennsylvania   Rhode Island South Carolina 
    ##              3              3              3              3              1 
    ##   South Dakota      Tennessee          Texas           Utah        Vermont 
    ##              2              1              4              3              2 
    ##       Virginia     Washington  West Virginia      Wisconsin        Wyoming 
    ##              3              3              2              2              3
    head(km.res$cluster, 4)
    ##  Alabama   Alaska  Arizona Arkansas 
    ##        1        4        4        1
    # Tamaño de clúster
    km.res$size
    ## [1]  8 13 16 13
    # Medias de Clúster
    km.res$centers
    ##       Murder    Assault   UrbanPop        Rape
    ## 1  1.4118898  0.8743346 -0.8145211  0.01927104
    ## 2 -0.9615407 -1.1066010 -0.9301069 -0.96676331
    ## 3 -0.4894375 -0.3826001  0.5758298 -0.26165379
    ## 4  0.6950701  1.0394414  0.7226370  1.27693964

    Visualización de grupos de k-medias:

    La función fviz_cluster() (paquete factoextra) se puede usar para visualizar fácilmente grupos de k-means. Toma los resultados de k-medias y los datos originales como argumentos. En el gráfico resultante, las observaciones están representadas por puntos, utilizando componentes principales si el número de variables es mayor que \(2\). También es posible dibujar elipses de concentración alrededor de cada grupo.

    fviz_cluster(km.res, data = df,
    palette = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
    ellipse.type = "euclid", # Elipse de concentración
    star.plot = TRUE, # Agregar segmentos de centralización a los elementos
    repel = TRUE, # Evitar que se traslapen (lento)
    ggtheme = theme_minimal()
    )



    Capítulo 5

    Cálculo de PAM en R

    Datos:

    data("USArrests") # Cargar el conjunto de datos
    df <- scale(USArrests) # Escalando los datos
    head(df, n = 3) # Ver las 3 primeras filas de los datos
    ##             Murder   Assault   UrbanPop         Rape
    ## Alabama 1.24256408 0.7828393 -0.5209066 -0.003416473
    ## Alaska  0.50786248 1.1068225 -1.2117642  2.484202941
    ## Arizona 0.07163341 1.4788032  0.9989801  1.042878388

    Estimación del número óptimo de conglomerados:

    La función R fviz_nbclust() (paquete factoextra) proporciona una solución conveniente para estimar la cantidad óptima de clústeres

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

    De la gráfica, el número sugerido de conglomerados es \(2\). En la siguiente parte, clasificaremos las observaciones en \(2\) conglomerados.

    Clúster de PAM informático:

    El siguiente código R calcula el algoritmo PAM con \(k = 2\)

    La salida impresa muestra:

    Los medoides del conglomerado: una matriz, cuyas filas son los medoides y qué columnas son variables.

    El vector de agrupamiento: Un vector de enteros (de 1:k) que indica el agrupamiento que se asigna a cada punto.

    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"
    # Si desea agregar las clasificaciones de puntos a los datos originales, use esto:
    dd <- cbind(USArrests, cluster = pam.res$cluster)
    head(dd, n = 3)
    ##         Murder Assault UrbanPop Rape cluster
    ## Alabama   13.2     236       58 21.2       1
    ## Alaska    10.0     263       48 44.5       1
    ## Arizona    8.1     294       80 31.0       1

    Acceder a los resultados de la función pam():

    # Cúmulo de medoides: Nuevo México, Nebraska
    pam.res$medoids
    ##                Murder    Assault   UrbanPop       Rape
    ## New Mexico  0.8292944  1.3708088  0.3081225  1.1603196
    ## Nebraska   -0.8008247 -0.8250772 -0.2445636 -0.5052109
    # Números de clúster
    head(pam.res$clustering)
    ##    Alabama     Alaska    Arizona   Arkansas California   Colorado 
    ##          1          1          1          2          1          1

    Visualización de clústeres PAM:

    fviz_cluster(pam.res,
    palette = c("#00AFBB", "#FC4E07"), # paleta de colores
    ellipse.type = "t", # Elipse de concentración
    repel = TRUE, # Evitar que se traslapen (lento)
    ggtheme = theme_classic()
    )



    Capítulo 6

    Cálculo de CLARA en R:

    Formato y preparación de datos:

    Aquí, generaremos un conjunto de datos aleatorios. Para que el resultado sea reproducible, comenzamos usando la función set.seed().

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

    Estimación del número óptimo de conglomerados:

    Para estimar la cantidad óptima de conglomerados en sus datos, es posible utilizar el método de silueta promedio como se describe en el capítulo de conglomerados de PAM (Capítulo 5). La función R fviz_nbclust() (paquete factoextra) proporciona una solución para facilitar este paso.

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

    De la gráfica, el número sugerido de conglomerados es \(2\). En la siguiente sección, clasificaremos las observaciones en \(2\) conglomerados.

    Cálculo de CLARA

    # Calcular CLARA
    clara.res <- clara(df, 2, samples = 50, pamLike = TRUE)

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

    • Medoids: Objetos que representan clusters clustering: un vector que contiene el número de conglomerado de cada objeto
    • sample: etiquetas o números de caso de las observaciones en la mejor muestra, es decir, a muestra utilizada por el algoritmo clara para la partición final.
    # Imprimir 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"
    # Si desea agregar las clasificaciones de puntos a los datos originales
    dd <- cbind(df, cluster = clara.res$cluster)
    head(dd, n = 4)
    ##             x        y cluster
    ## S1  -9.656526 3.881815       1
    ## S2   2.219434 5.574150       1
    ## S3   8.675529 1.484111       1
    ## S4 -18.765582 5.605868       1
    # Puede acceder a los resultados devueltos por clara() de la siguiente manera:
    # Medoides
    clara.res$medoids
    ##              x         y
    ## S121 -1.531137  1.145057
    ## S455 48.357304 50.233499
    # Agrupación
    head(clara.res$clustering, 10)
    ##  S1  S2  S3  S4  S5  S6  S7  S8  S9 S10 
    ##   1   1   1   1   1   1   1   1   1   1
    # Los medoides son S121, S455

    Visualización de clústeres CLARA:

    fviz_cluster(clara.res,
    palette = c("#00AFBB", "#FC4E07"), # Paleta de colores
    ellipse.type = "t", # Elipse de concentración
    geom = "point", pointsize = 1,
    ggtheme = theme_classic()
    )



    Capítulo 7

    Estructura y preparación de datos:

    # Cargar los datos
    data("USArrests")
    # Estandarizar los datos
    df <- scale(USArrests)
    # Mostrar la cabeza de las primeras 6 filas
    head(df, nrow = 6)
    ##                Murder   Assault   UrbanPop         Rape
    ## Alabama    1.24256408 0.7828393 -0.5209066 -0.003416473
    ## Alaska     0.50786248 1.1068225 -1.2117642  2.484202941
    ## Arizona    0.07163341 1.4788032  0.9989801  1.042878388
    ## Arkansas   0.23234938 0.2308680 -1.0735927 -0.184916602
    ## California 0.27826823 1.2628144  1.7589234  2.067820292
    ## Colorado   0.02571456 0.3988593  0.8608085  1.864967207

    Medidas de similitud:

    Tener en cuenta que la función dist() calcula la distancia entre las filas de una matriz de datos utilizando el método de medida de distancia especificado.

    Para ver fácilmente la información de distancia entre objetos, reformateamos los resultados de la función dist() en una matriz usando 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. Por ejemplo, el elemento \(1,1\) representa la distancia entre el objeto \(1\) y él mismo (que es cero). El elemento \(1,2\) representa la distancia entre el objeto \(1\) y el objeto \(2\), y así sucesivamente.

    # Calcule la matriz de disimilitud # df = los datos estandarizados
    res.dist <- dist(df, method = "euclidean")
    # El siguiente código R muestra las primeras 6 filas y columnas de la matriz de distancia:
    as.matrix(res.dist)[1:6, 1:6]
    ##             Alabama   Alaska  Arizona Arkansas California Colorado
    ## Alabama    0.000000 2.703754 2.293520 1.289810   3.263110 2.651067
    ## Alaska     2.703754 0.000000 2.700643 2.826039   3.012541 2.326519
    ## Arizona    2.293520 2.700643 0.000000 2.717758   1.310484 1.365031
    ## Arkansas   1.289810 2.826039 2.717758 0.000000   3.763641 2.831051
    ## California 3.263110 3.012541 1.310484 3.763641   0.000000 1.287619
    ## Colorado   2.651067 2.326519 1.365031 2.831051   1.287619 0.000000

    Dendograma:

    # cex: tamaño de la etiqueta
    res.hc <- hclust(d = res.dist, method = "ward.D2")

    En el dendrograma que se muestra arriba, cada hoja corresponde a un objeto. mientras nos movemos arriba del árbol, los objetos que son similares entre sí se combinan en ramas, que se funsionan a una altura mayor.

    La altura de la fusión, proporcionada en el eje vertical, indica la (des)similitud/distancia entre dos objetos/clusters. Cuanto mayor sea la altura de la fusión, menos similar será la los objetos son. Esta altura se conoce como la distancia cofenética entre los dos objetos.

    NOTA: Tener en cuenta que las conclusiones sobre la proximidad de dos objetos solo se pueden sacar en función de 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 su similitud.

    Verificar el árbol de clústeres:

    # cex: label size
    library("factoextra")
    fviz_dend(res.hc, cex = 0.5)

    #  Calcular distancia cophenetic
    res.coph <- cophenetic(res.hc)
    # Correlación entre distancia cophenetic y la distancia original
    cor(res.dist, res.coph)
    ## [1] 0.6975266

    Ejecutar la función hclust() nuevamente usando el método de vinculación promedio. A continuación, llame a cophenetic() para evaluar la solución de agrupación.

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

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

    Cortar el dendograma en diferentes grupos:

    # Cortar el árbol en 4 grupos
    grp <- cutree(res.hc, k = 4)
    head(grp, n = 4)
    ##  Alabama   Alaska  Arizona Arkansas 
    ##        1        2        2        3
    # Número de miembros en cada Clúster
    table(grp)
    ## grp
    ##  1  2  3  4 
    ##  7 12 19 12
    # Obtener los nombres de los miembros del clúster 1
    rownames(df)[grp == 1]
    ## [1] "Alabama"        "Georgia"        "Louisiana"      "Mississippi"   
    ## [5] "North Carolina" "South Carolina" "Tennessee"
    # Cortar en 4 grupos y colorear por grupos
    fviz_dend(res.hc, k = 4, # Cortar en 4 grupos
    cex = 0.5, # tamaño de etiqueta
    k_colors = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
    color_labels_by_k = TRUE, # color de etiquetas por grupo
    rect = TRUE # Agregar rectángulo alrededor de los grupos
    )

    Usando la función fviz_cluster() (de factoextra), también podemos visualizar el resultado en un diagrama de dispersión. Las observaciones están representadas por puntos en la gráfica, utilizando componentes principales. Se dibuja un marco alrededor de cada grupo.

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

    Paquete Clúster R:

    library("cluster")
    # Anidamiento aglomerativo (agrupación jerárquica)
    res.agnes <- agnes(x = USArrests, # matriz de datos
    stand = TRUE, # Estandarizar los datos
    metric = "euclidean", # métrica para el método de matriz de distancia 
    method = "ward" # Método de vinculación
    )
    # ANÁLISIS DIvisivo Clustering
    res.diana <- diana(x = USArrests, # matriz de datos
    stand = TRUE, # Estandarizar los datos
    metric = "euclidean" # métrica para el método de matriz de distancia
    )

    Después de ejecutar agnes() y diana(), puede usar la función fviz_dend() (de factoextra) para visualizar el resultado:

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



    Capítulo 8

    Preparación de datos:

    Usaremos los conjuntos de datos R base USArrests y comenzaremos estandarizando las variables usando la función scale() de la siguiente manera:

    df <- scale(USArrests)
    
    # Para que las gráficas generadas en las siguientes secciones sean legibles, trabajaremos con un pequeño subconjunto aleatorio del conjunto de datos. Por lo tanto, usaremos la función sample() para seleccionar aleatoriamente 10 observaciones entre las 50 observaciones contenidas en el conjunto de datos:
    
    # Subconjunto que contiene 10 filas
    set.seed(123)
    ss <- sample(1:50, 10)
    df <- df[ss,]

    Comparación de dendogramas:

    library(dendextend)
    # # Calcular 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 contener dendrogramas
    dend_list <- dendlist(dend1, dend2)

    Comparación visual de dos dendrogramas:

    Para comparar visualmente dos dendrogramas, usaremos la función tanglegram() (paquete dendextend), que traza los dos dendrogramas, uno al lado del otro, con sus etiquetas conectadas por líneas.

    La calidad de la alineación de los dos árboles se puede medir usando la función enredo(). El enredo es una medida entre \(1\) (enredo total) y \(0\) (sin enredo). Un coeficiente de entrelazamiento más bajo corresponde a una buena alineación.

    tanglegram(dend1, dend2)

    # Personalizar el tanglegrama usando muchas otras opciones de la siguiente manera:
    tanglegram(dend1, dend2,
    highlight_distinct_edges = FALSE, # Desactivar líneas discontinuas
    common_subtrees_color_lines = FALSE, # Desactivar colores de línea
    common_subtrees_color_branches = TRUE, # Color de ramas comunes
    main = paste("entanglement =", round(entanglement(dend_list), 2))
    )

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

    Matriz de correlación entre una lista de dendrogramas:

    La función cor.dendlist() se utiliza para calcular la matriz de correlación “Baker” o “Cophenetic” entre una lista de árboles. El valor puede oscilar entre \(-1\) y \(1\). Con valores cercanos a \(0\), significa que los dos árboles no son estadísticamente similares.

    # Matriz de correlación Cophenetic 
    cor.dendlist(dend_list, method = "cophenetic")
    ##           [,1]      [,2]
    ## [1,] 1.0000000 0.9925544
    ## [2,] 0.9925544 1.0000000
    # Matriz de correlación Baker
    cor.dendlist(dend_list, method = "baker")
    ##           [,1]      [,2]
    ## [1,] 1.0000000 0.9895528
    ## [2,] 0.9895528 1.0000000
    # La correlación entre dos árboles también se puede calcular de la siguiente manera: 
    
    # Coeficiente de correlación Cophenetic 
    cor_cophenetic(dend1, dend2)
    ## [1] 0.9925544
    # Coeficiente de correlación Baker
    cor_bakers_gamma(dend1, dend2)
    ## [1] 0.9895528

    También es posible comparar simultáneamente múltiples dendrogramas. Se utiliza un operador de encadenamiento %>% para ejecutar múltiples funciones al mismo tiempo. Es útil para simplificar el código:

    # 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 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)
    ##          Complete Single Average Centroid
    ## Complete     1.00   0.46    0.45     0.30
    ## Single       0.46   1.00    0.23     0.17
    ## Average      0.45   0.23    1.00     0.31
    ## Centroid     0.30   0.17    0.31     1.00
    # Visualiza la matriz de correlación usando el paquete corrplot
    library(corrplot)
    corrplot(cors, "pie", "lower")



    Capítulo 9

    Visualización de dendogramas:

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

    Visualización de dendograma:

    # Para crear un dendrograma básico
    library(factoextra)
    fviz_dend(hc, cex = 0.5)

    # Puede usar los argumentos main, sub, xlab, ylab para cambiar los títulos de las gráficas de la siguiente manera:
    fviz_dend(hc, cex = 0.5,
    main = "Dendrogram - ward.D2",
    xlab = "Objects", ylab = "Distance", sub = "")

    # Para dibujar un dendograma horizontal
    fviz_dend(hc, cex = 0.5, horiz = TRUE)

    También es posible cortar el árbol a una altura determinada para dividir los datos en varios grupos, como se describe en el capítulo anterior: Agrupación jerárquica (Capítulo 7). En este caso, es posible colorear las ramas por grupos y agregar un rectángulo alrededor de cada una.

    fviz_dend(hc, k = 4,cex = 0.5,color_labels_by_k = TRUE, rect = TRUE,rect_fill = TRUE)

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

    fviz_dend(hc, k = 4, # 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
    ggtheme = theme_gray() # cambiar tema
    )

    library(RColorBrewer)
    fviz_dend(hc, cex = 0.5, k = 4, # Cortar en 4 grupos
    k_colors = "jco")

    # Si desea dibujar un dendograma horizontal con un rectángulo alrededor de los grupos
    fviz_dend(hc, k = 4, cex = 0.4, horiz = TRUE, k_colors = "jco",
    rect = TRUE, rect_border = "jco", rect_fill = TRUE)

    # Además, puede trazar un dendrograma circular usando la opción type = "circular"
    fviz_dend(hc, cex = 0.5, k = 4,
    k_colors = "jco", type = "circular")

    Para trazar un árbol de tipo filogenético, use type = “phylogenic” y repel = TRUE (para evitar que las etiquetas se sobretrafiquen). Esta funcionalidad requiere el igraph del paquete R. Asegúrese de que esté instalado antes de escribir el siguiente código R

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

    El diseño predeterminado para los árboles filogenéticos es “layout.auto”. Los valores permitidos son uno de: c(“layout.auto”, “layout_with_drl”, “layout_as_tree”, “layout.gem”, “layout.mds”, “layout_with_lgl”). Para leer más sobre estos diseños, lea la documentación del paquete igraph R.

    # Probemos phylo.layout = “layout.gem”:
    require("igraph")
    fviz_dend(hc, k = 4, # Cortar en cuatro grupos
    k_colors =
    "jco", type = "phylogenic", repel = TRUE,
    phylo_layout = "layout.gem")

    Zoom en el dendrograma:

    Si desea acercar los primeros grupos, es posible usar la opción xlim e ylim para limitar el área de la trama. Por ejemplo, escriba el código a continuación:

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

    # 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, # Cortar en 4 grupos
    cex = 0.5, # tamaño de la etiqueta
    k_colors = "jco"
    )
    dend_data <- attr(dend_plot, "dendrogram") # Extraer los datos del denograma
    # Cortar el dendrograma a la altura h = 10
    dend_cuts <- cut(dend_data, h = 10)
    # Visualiza la versión truncada que contiene
    # 2 ramas
    fviz_dend(dend_cuts$upper)

    # Trazar subárboles de dendrogramas:
    # Graficar todo el dendograma
    print(dend_plot)

    # Gráficar el subárbol 1
    fviz_dend(dend_cuts$lower[[1]], main = "Subtree 1")

    # Gráficar el subárbol 2
    fviz_dend(dend_cuts$lower[[2]], main = "Subtree 2")

    # También puede trazar árboles circulares de la siguiente manera:
    fviz_dend(dend_cuts$lower[[2]], type = "circular")

    Guardar 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 la gráfica
    print(p)
    dev.off() 
    ## png 
    ##   2

    Manipulación de dendrogramas usando 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)

    # Código R para crear un dendrograma usando un operador de encadenamiento:
    library(dendextend)
    dend <- USArrests[1:5,] %>% # data
    scale %>% # Scale the data
    dist %>% # calculate a distance matrix,
    hclust(method = "ward.D2") %>% # Hierarchical clustering
    as.dendrogram # Turn the object into a dendrogram.
    plot(dend)

    library(dendextend)
    # 1. Crear un dendrograma personalizado dendrogram
    mycols <- c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07")
    dend <- as.dendrogram(hc) %>%
    set("branches_lwd", 1) %>% # Ancho de las ramas
    set("branches_k_color", mycols, k = 4) %>% # Color de los grupos de ramas
    set("labels_colors", mycols, k = 4) %>% # Color de las etiquetas por grupos
    set("labels_cex", 0.5) # Cambiar el tamaño de las etiquetas
    # # 2. Crearlo
    fviz_dend(dend)


    5. Bibliografía

    Calvo, D. (2018). Clúster jerárquicos y no jerárquicos. https://www.diegocalvo.es/cluster-jerarquicos-y-no-jerarquicos/
    Galili, T. (2015). Dendextend: An r package for visualizing, adjusting, and comparing trees of hierarchical clustering. Bioinformatics. https://doi.org/10.1093/bioinformatics/btv428
    Galili, T., & Jefferis, G. (2022). Dendextend: Extending dendrogram functionality in r. https://CRAN.R-project.org/package=dendextend
    Granada, U. de. (2017). Métodos jerárquicos de análisis cluster. https://www.ugr.es/~gallardo/pdf/cluster-3.pdf
    Guide, B. A. R. P. (2022). K-means cluster analysis. https://uc-r.github.io/kmeans_clustering
    Husson, F., Josse, J., Le, S., & Mazet, J. (2022). FactoMineR: Multivariate exploratory data analysis and data mining. http://factominer.free.fr
    Kassambara, A. (2017). Multivariate analysis i (1st ed., pp. 1–187). STHDA.
    Kassambara, A., & Mundt, F. (2020). Factoextra: Extract and visualize the results of multivariate data analyses. http://www.sthda.com/english/rpkgs/factoextra
    Lê, S., Josse, J., & Husson, F. ois. (2008). FactoMineR: A package for multivariate analysis. Journal of Statistical Software, 25(1), 1–18. https://doi.org/10.18637/jss.v025.i01
    Maechler, M., Rousseeuw, P., Struyf, A., & Hubert, M. (2022). Cluster: "Finding groups in data": Cluster analysis extended rousseeuw et al. https://svn.r-project.org/R-packages/trunk/ cluster/
    RDocumentation. (2022a). Clara: Clustering large applications. https://www.rdocumentation.org/packages/cluster/versions/2.1.4/topics/clara
    RDocumentation. (2022b). Cutree: Cut a tree into groups of data. https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/cutree
    RDocumentation. (2022c). Dist: Distance matrix computation. https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/dist
    RDocumentation. (2022d). Fviz_clust: Determining and visualizing the optimal number of clusters. https://www.rdocumentation.org/packages/factoextra/versions/1.0.7/topics/fviz_nbclust
    RDocumentation. (2022e). Fviz_dend: Enchanced visualization of dendrogram. https://www.rdocumentation.org/packages/factoextra/versions/1.0.7/topics/fviz_dend
    RDocumentation. (2022f). Hclust: Hierarchial clustering. https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/hclust
    RDocumentation. (2022g). Pam: Partitioning around medoids. https://www.rdocumentation.org/packages/cluster/versions/2.1.4/topics/pam
    Statistics Education, I. for. (2022). K-means clustering. https://www.statistics.com/glossary/k-means-clustering/
    Warnes, G. R., Bolker, B., Bonebakker, L., Gentleman, R., Huber, W., Liaw, A., Lumley, T., Maechler, M., Magnusson, A., Moeller, S., Schwartz, M., & Venables, B. (2022). Gplots: Various r programming tools for plotting data. https://github.com/talgalili/gplots