Capitulo 8

Comparación de dendogramas

“Después de explicar cómo calcular el clustering jerárquico (Capítulo 7), describimos aquí cómo comparar dos dendrogramas utilizando el paquete dendeztend de R. El paquete dendertend ofrece varias funciones para comparar dendrogramas. Aquí nos centraremos en dos funciones: tanglegram():comparación visual de dos dendrogramas y cor.dendlist(): una matriz de correlación entre dendrogramas.

8.1 Preparación de datos

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

df <- scale(USArrests) 
# Para hacer legibles los gráficos generados en las siguientes secciones, trabajaremos con un pequeño subconjunto aleatorio del conjunto de datos. Por lo tanto, utilizaremos la función sample() para seleccionar aleatoriamente 10 observaciones de las 50 observaciones contenidas en el conjunto de datos:

# Subset containing 10 rows
set.seed(123)
ss <- sample(1:50, 10)
df <- df[ss,] 

8.2 Comparacón de dendrogramas

Comenzamos creando una lista de dos dendrogramas calculando el clustering jerárquico (HC) utilizando dos métodos de enlace diferentes (“average” y “ward.D2”). A continuación, transformamos los resultados en dendrogramas y creamos una lista para contener los dos dendrogramas.

library(dendextend)
## 
## ---------------------
## Welcome to dendextend version 1.17.1
## Type citation('dendextend') for how to cite the package.
## 
## Type browseVignettes(package = 'dendextend') for the package vignette.
## The github page is: https://github.com/talgalili/dendextend/
## 
## Suggestions and bug-reports can be submitted at: https://github.com/talgalili/dendextend/issues
## You may ask questions at stackoverflow, use the r and dendextend tags: 
##   https://stackoverflow.com/questions/tagged/dendextend
## 
##  To suppress this message use:  suppressPackageStartupMessages(library(dendextend))
## ---------------------
## 
## Attaching package: 'dendextend'
## The following object is masked from 'package:stats':
## 
##     cutree
# Compute distance matriz
res.dist <- dist(df, method = "euclidean")
# Compute 2 hierarchical clusterings
hc1 <- hclust(res.dist, method = "average")
hc2 <- hclust(res.dist, method = "ward.D2")
#Create two dendrograms
dend1 <- as.dendrogram (hc1)
dend2 <- as.dendrogram (hc2)
# Create a list to hold dendrograms
dend_list <- dendlist(dend1, dend2) 

8.2.1 Comparación visual de dos dendrogramas

Para comparar visualmente dos dendrogramas, utilizaremos la función tanglegram() [paquete dendextend], que dibuja 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 puede medirse utilizando la función entanglement(). El enredo es una medida entre 1 (enredo completo) y 0 (sin enredo). Un coeficiente de enredo más bajo corresponde a una mejor alineación.

#Dibujar un tanglegram
tanglegram(dend1, dend2) 

# Customizar grafica
tanglegram(dend1, dend2,
           highlight_distinct_edges = FALSE, # Turn-off dashed lines 
           common_subtrees_color_lines = FALSE, # Turn-off line colors
           common_subtrees_color_branches = TRUE, # Color common branches
           main = paste("entanglement =", round(entanglement(dend_list), 2))
) 

8.2.2 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, siendo los valores cercanos a 0 indicativos de que los dos árboles no son estadísticamente similares.

#Cophenetic correlation matriz

cor.dendlist(dend_list, method = "cophenetic") 
##           [,1]      [,2]
## [1,] 1.0000000 0.9925544
## [2,] 0.9925544 1.0000000
#Baker correlation matriz
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 puede calcularse de la siguiente manera:

#Cophenetic correlation coefficient
cor_cophenetic(dend1, dend2) 
## [1] 0.9925544
# Baker correlation coefficient
cor_bakers_gamma (dend1, dend2) 
## [1] 0.9895528

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

#Create multiple dendrograms by chaining
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
# Compute correlation matriz
dend_list <- dendlist("Complete" = dend1, "Single" = dend2,
                      "Average" = dend3, "Centroid" = dend4)
cors <- cor.dendlist(dend_list)
# Print correlation matriz
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
# Visualize the correlation matriz using corrplot package
library(corrplot)
## corrplot 0.92 loaded
corrplot(cors, "pie", "lower") 

Cápitulo 9

Visulizar dendrogramas

Como se describió en capítulos anteriores, un dendrograma es una representación basada en árboles de datos creada utilizando métodos de clustering jerárquico (Capítulo 7). En este artículo, proporcionamos código en R para visualizar y personalizar dendrogramas. Además, mostramos cómo guardar y hacer zoom en un dendrograma grande.

Empezamos calculando el clustering jerárquico utilizando el conjunto de datos USArrests:

#Load data
data(USArrests)
# Compute distances and hierarchical clustering
dd <- dist(scale(USArrests), method = "euclidean")
hc <- hclust(dd, method = "ward.D2") 

Para visualizar el dendrograma, utilizaremos las siguientes funciones y paquetes de R:

fviz_dend() del paquete factoextra para crear fácilmente un dendrograma basado en ggplot2 y visualmente atractivo. El paquete dendertend para manipular dendrogramas. Antes de continuar, instala el paquete necesario de la siguiente manera:

install.packages(c("factoextra", "dendextend")) 
## Installing packages into '/cloud/lib/x86_64-pc-linux-gnu-library/4.4'
## (as 'lib' is unspecified)

9.1 Visualizar dendrogramas

Usaremos la función fviz_dend() [en el paquete factoextra de R] para crear fácilmente un dendrograma hermoso utilizando tanto el gráfico base de R como ggplot2. También proporciona una opción para dibujar dendrogramas circulares y árboles tipo filogenético.

Para crear un dendrograma básico, escribe esto:

library(factoextra)
## Loading required package: ggplot2
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
fviz_dend(hc, cex = 0.5) 
## Warning: The `<scale>` argument of `guides()` cannot be `FALSE`. Use "none" instead as
## of ggplot2 3.3.4.
## ℹ The deprecated feature was likely used in the factoextra package.
##   Please report the issue at <https://github.com/kassambara/factoextra/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Puedes utilizar los argumentos main, sub, xlab e ylab para cambiar los títulos del gráfico de la siguiente manera:

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

Para dibujar un dendrograma horizontal, escribe esto:

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

También es posible cortar el árbol en una altura dada para dividir los datos en múltiples grupos, como se describe en el capítulo anterior: Clustering jerárquico (Capítulo 7). En este caso, es posible colorear las ramas por grupos y agregar un rectángulo alrededor de cada grupo. Por ejemplo:

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, # colorear las etiquetas por grupos
          rect = TRUE, # agregar rectángulo alrededor de los grupos
          rect_border = "black", # asignar un solo color para los bordes
          rect_fill = TRUE)

Para cambiar el tema del gráfico, usa el argumento ggtheme, cuyos valores permitidos incluyen los temas oficiales de ggplot2 [ theme_gray(), theme_bw(), theme_minimal(), theme_classic(), theme_void() ] u otros temas definidos por el usuario en ggplot2

fviz_dend(hc, k = 4, # Cut in four groups
          cex = 0.5, # label size
          k_colors = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
          color_labels_by_k = TRUE, # color labels by groups
          ggtheme = theme_gray() # Change theme
) 

Los valores permitidos para k_color incluyen paletas de colores de RColorBrewer Package (por ejemplo, “RdBu”, “Blues”, “Dark2”, “Set2”) y paletas de revistas científicas del paquete R ggsci (por ejemplo, “npg”, “aaas”, “j”, “uchicago”, “simpsons” y “rickandmorty”).

En el código R a continuación, cambiaremos los colores de los grupos usando “jco” una paleta de colores:

fviz_dend(hc, cex = 0.5, K = 4, #Cut in four groups
          k_colors = "jco")

Si deseas dibujar un dendrograma horizontal con rectángulos alrededor de los clústeres, utiliza esto:

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

Además, puedes dibujar un dendrograma circular utilizando la opción type = “circular”.

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

Para dibujar un árbol tipo filogenético, utiliza type = “phylogenic” y repel = TRUE (para evitar la superposición de etiquetas). Esta funcionalidad requiere el paquete R igraph. Asegúrate de tenerlo instalado antes de escribir el siguiente código en R.

require("igraph")
## Loading required package: igraph
## 
## Attaching package: 'igraph'
## The following objects are masked from 'package:stats':
## 
##     decompose, spectrum
## The following object is masked from 'package:base':
## 
##     union
fviz_dend(hc, kK = 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 obtener más información sobre estos diseños, consulta la documentación del paquete R igraph. Intentemos con phylo.layout = “layout.gem”:

require("igraph")
fviz_dend(hc, k = 4, # Cut in four groups
          k_colors = "jco",
          type = "phylogenic", repel = TRUE,
          phylo_layout = "layout.gem") 

Caso de dendrograma con conjuntos de datos grandes

Si calculas el clustering jerárquico en un conjunto de datos grande, es posible que desees hacer zoom en el dendrograma o solo graficar un subconjunto del mismo. Alternativamente, también podrías graficar el dendrograma en una página grande en un PDF, que se puede hacer zoom sin pérdida de resolución.

9.2.1 Hacer zoom en el dendrograma

Si deseas hacer zoom en los primeros clústeres, es posible usar la opción xlim y ylim para limitar el área de trazado. Por ejemplo, escribe el siguiente código:

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

9.2.2

Para trazar un subárbol, seguiremos el procedimiento a continuación:

Crea el dendrograma completo usando fviz_dend() y guarda el resultado en un objeto, por ejemplo, llamado dend_plot.

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

Visualiza los subárboles usando fviz_dend(). El código R es el siguiente.

Corta el dendrograma y visualiza la versión truncada

# Create a plot of the whole dendrogram,
# and extract the dendrogram data
dend_plot <- fviz_dend(hc, k = 4, # Cut in four groups
          cex = 0.5, # label size
          k_colors = "jco"
)
dend_data <- attr(dend_plot, "dendrogram") # Extract dendrogram data
# Cut the dendrogram at height h = 10
dend_cuts <- cut(dend_data, h = 10)
#Visualize the truncated version containing
# two branches
fviz_dend(dend_cuts$upper) 
## Warning in min(-diff(our_dend_heights)): no non-missing arguments to min;
## returning Inf

Trazar subárboles de dendrogramas:

# Plot the whole dendrogram
print (dend_plot) 

# Plot subtree 1
fviz_dend(dend_cuts$lower[[1]], main = "Subtree 1")

# Plot subtree 2
fviz_dend(dend_cuts$lower[[2]], main = "Subtree 2")

Tambien puedes hacer arboles circulares

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

####9.2.3 Guardar el dendrograma en una página grande de PDF

Si tienes un dendrograma grande, puedes guardarlo en una página grande de PDF, lo que te permite hacer zoom sin pérdida de resolución.

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

9.3 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, utilizaremos el operador de encadenamiento (%>%) para simplificar nuestro código. El operador de encadenamiento convierte x %>% f(y) en f(x, y), por lo que puedes usarlo para reescribir múltiples operaciones de modo que puedan leerse de izquierda a derecha y de arriba a abajo. Por ejemplo, los resultados de los dos códigos R a continuación son equivalentes.

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)
dend <- USArrests[1:5,] %>% #data
scale %>% # Scale the data
dist %>% # calculate a distance matriz,
hclust (method = "ward.D2") %>% # Hierarchical clustering
as.dendrogram # Turn the object into a dendrogram.
plot (dend)

Las funciones para personalizar dendrogramas: La función set() [en el paquete dendextend] se puede utilizar para cambiar los parámetros de un dendrograma.

library(dendextend)
#1. Create a customized dendrogram
mycols <- c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07")
dend <- as.dendrogram(hc) %>%
  set("branches_lwd", 1) %>% # Branches line width
  set("branches_k_color", mycols, k = 4) %>% # Color branches by groups
  set("labels_colors", mycols, k = 4) %>% # Color labels by groups
  set("labels_cex", 0.5) # Change label size

# 2. Create plot
fviz_dend(dend) 

Resumen

Describimos funciones y paquetes para visualizar y personalizar dendrogramas, incluyendo:

fviz_dend() [en el paquete factoextra de R], que proporciona soluciones convenientes para trazar fácilmente un dendrograma hermoso. Se puede utilizar para crear dendrogramas rectangulares y circulares, así como un árbol filogenético.

y el paquete dendextend, que proporciona métodos flexibles para personalizar dendrogramas.

Además, describimos cómo trazar un subconjunto de dendrogramas grandes.