Jugando con las dimensiones: desde Clustering, PCA, t-SNE.... ¡hasta Carl Sagan!

👉 Actualización! 7/4/20 La nueva versión de este post con mejoras y comentarios sobre UMAP, acá: https://escueladedatosvivos.ai/blog/204650/jugando-con-las-dimensiones-clustering-pca-tsne-carl-sagan

Jugando con las dimensiones

¡Hola! Este post es un experimento que combina el resultado de t-SNE con dos técnicas de clustering bien conocidas: k-means y hierarchical. Esta será la sección práctica, en R.

Pero también, este post explorará el punto de intersección de conceptos como reducción de dimensiones, análisis de clustering, preparación de datos, PCA, HDBSCAN, k-NN, SOM, deep learning....y Carl Sagan!

PCA y t-SNE

Para aquellos que no conocen la técnica t-SNE (sitio oficial), es una técnica de proyección -o reducción de dimensiones- similar en algunos aspectos al Análisis de Componentes Principales (PCA), utilizado para visualizar, por ejemplo, N variables en 2.

Cuando la salida de t-SNE es deficiente, Laurens van der Maaten (autor de t-SNE) dice:

Como prueba de sanidad, intente ejecutar PCA en sus datos para reducirlos a dos dimensiones. Si esto también da malos resultados, entonces tal vez no hay una estructura buena en sus datos en primer lugar. Si PCA funciona bien pero t-SNE no lo hace, estoy bastante seguro de que usted hizo algo mal.

En mi experiencia, hacer PCA con docenas de variables con:

  • Algunos valores extremos
  • Distribuciones sesgadas
  • Varias variables dummy o one-hot (0 ó 1),

No conduce a buenas visualizaciones.

Miren este ejemplo comparando los dos métodos:

Fuente: Clusterización en 2 dimensiones usando tsne

Tiene sentido, ¿no?


Surfeando en dimensiones superiores 🏄

Dado que uno de los resultados t-SNE es una matriz de dos dimensiones, donde cada punto representa un caso de entrada, podemos aplicar un clustering y luego agrupar los casos de acuerdo a su distancia en este mapa de 2 dimensiones. Al igual que un mapa geográfico con la cartografía de 3 dimensiones (nuestro mundo), en dos (papel).

El t-SNE agrupa casos similares, manejando muy bien las no linearidades de los datos. Después de usar el algoritmo en varios conjuntos de datos, creo que en algunos casos crea algo parecido a formas circulares como islas, donde estos casos son similares.

Sin embargo, no vi este efecto en la demostración interactiva del equipo de Google Brain: How to Use t-SNE Effectively. Tal vez debido a la naturaleza de los datos de entrada, 2 variables como entrada.


Los datos del rollo suizo (swiss roll)

t-SNE de acuerdo a su FAQ no funciona muy bien con los datos de juguete swiss roll. Sin embargo, es un ejemplo impresionante de cómo una superficie tridimensional (o manifold) con forma concreta de espiral se despliega como el papel gracias a una técnica de reducción de dimensiones.

La imagen ha sido tomada de este paper, donde usaron la técnica de "manifold sculpting".


Ahora la práctica en R!

t-SNE ayuda a hacer que el cluster sea más preciso porque convierte los datos en un espacio de 2 dimensiones donde los puntos están en forma circular (lo que a su vez resulta agradable para el k-means, y es uno de sus puntos débiles a la hora de crear segmentos). Más sobre esto: K-means clustering is not a free lunch).

Tal como si fuera una preparación de datos para aplicar los modelos de clustering.


library(caret)
library(Rtsne)

######################################################################
## The WHOLE post is in: https://github.com/pablo14/post_cluster_tsne
######################################################################

## Download data from: https://github.com/pablo14/post_cluster_tsne/blob/master/data_1.txt (url path inside the gitrepo.)
data_tsne=read.delim("data_1.txt", header = T, stringsAsFactors = F, sep = "\t")

## Rtsne function may take some minutes to complete...
set.seed(9)
tsne_model_1 = Rtsne(as.matrix(data_tsne), check_duplicates=FALSE, pca=TRUE, perplexity=30, theta=0.5, dims=2)

## getting the two dimension matrix
d_tsne_1 = as.data.frame(tsne_model_1$Y)

Diferentes ejecuciones de Rtsne conducen a diferentes resultados. Por lo tanto, lo más probable es que no se vea exactamente el mismo modelo que el que se presenta aquí.

Según la documentación oficial, la "perplejidad" (perplexity) está relacionada con la importancia de los vecinos:

  • Es comparable con el número de vecinos más cercanos k que se emplea en muchos aprendedores de manifold".
  • Los valores típicos para el rango de perplejidad van entre 5 y 50"

El objeto tsne_model_1$Y contiene las coordenadas X-Y (variables V1 y V2), para cada caso de entrada.


Graficando los resultados de t-SNE:

## plotting the results without clustering
ggplot(d_tsne_1, aes(x=V1, y=V2)) +
  geom_point(size=0.25) +
  guides(colour=guide_legend(override.aes=list(size=6))) +
  xlab("") + ylab("") +
  ggtitle("t-SNE") +
  theme_light(base_size=20) +
  theme(axis.text.x=element_blank(),
        axis.text.y=element_blank()) +
  scale_colour_brewer(palette = "Set2")

Y están las famosas "islas" 🏝️. En este punto, podemos hacer un poco de clustering mirándolo.... Pero probemos k-Means y clustering jerárquico en su lugar 😄. La página de preguntas frecuentes de t-SNE sugiere disminuir el parámetro de perplejidad para evitar esto, sin embargo no encontré ningún problema con este resultado.


Creando los modelos de clústeres

La siguiente pieza de código creará los modelos de clúster k-means y jerárquico. Para entonces asignar el número de cluster (1, 2 ó 3) al que pertenece cada caso de entrada.

## keeping original data
d_tsne_1_original=d_tsne_1

## Creating k-means clustering model, and assigning the result to the data used to create the tsne
fit_cluster_kmeans=kmeans(scale(d_tsne_1), 3)
d_tsne_1_original$cl_kmeans = factor(fit_cluster_kmeans$cluster)

## Creating hierarchical cluster model, and assigning the result to the data used to create the tsne
fit_cluster_hierarchical=hclust(dist(scale(d_tsne_1)))

## setting 3 clusters as output
d_tsne_1_original$cl_hierarchical = factor(cutree(fit_cluster_hierarchical, k=3))

Graficando los modelos de clústeres en la salida de t-SNE

Ahora es el momento de graficar el resultado de cada modelo de clúster, basado en el mapa t-SNE.

plot_cluster=function(data, var_cluster, palette)
{
  ggplot(data, aes_string(x="V1", y="V2", color=var_cluster)) +
  geom_point(size=0.25) +
  guides(colour=guide_legend(override.aes=list(size=6))) +
  xlab("") + ylab("") +
  ggtitle("") +
  theme_light(base_size=20) +
  theme(axis.text.x=element_blank(),
        axis.text.y=element_blank(),
        legend.direction = "horizontal", 
        legend.position = "bottom",
        legend.box = "horizontal") + 
    scale_colour_brewer(palette = palette) 
}


plot_k=plot_cluster(d_tsne_1_original, "cl_kmeans", "Accent")
plot_h=plot_cluster(d_tsne_1_original, "cl_hierarchical", "Set1")

## and finally: putting the plots side by side with gridExtra lib...
library(gridExtra)
grid.arrange(plot_k, plot_h,  ncol=2)

Análisis visual

En este caso, y basado sólo en el análisis visual, lo jerárquico parece tener más sentido común que el k-means. Miren la siguiente imagen:

Nota: las líneas punteadas que separan los clusters fueron dibujadas a mano.


En k-means, la distancia en los puntos de la esquina inferior izquierda están bastante cerca en comparación con la distancia de otros puntos dentro del mismo cluster. Pero pertenecen a diferentes grupos. Ilustrándolo:

Así que tenemos: la flecha roja es más corta que la azul....

Nota: Diferentes ejecuciones pueden llevar a diferentes agrupaciones, si no ve este efecto en esa parte del mapa, búsquelo en otra.

Este efecto no ocurre en el clustering jerárquico. Los conglomerados con este modelo parecen más uniformes. Pero, ¿qué te parece?


Sesgando el análisis (haciendo trampa)

No es justo para k-means que se compare así. El último análisis está basado en la idea de clustering por densidad. Esta técnica es realmente genial para superar las trampas de los métodos más simples.

El algoritmo HDBSCAN basa su proceso en densidades.

Encuentra la esencia de cada uno mirando esta foto:

Seguramente entendieron la diferencia entre ellos...

La última imagen viene de: Comparing Python Clustering Algorithms. Si, Python, pero es lo mismo para R. El paquete es largeVis. (Note: Install it by doing: install_github("elbamos/largeVis", ref = "release/0.2").


Deep learning and t-SNE

Citando a Luke Metz desde un gran post (Visualizing with t-SNE):

En los últimos tiempos se ha producido un gran revuelo en torno al término " deep learning ". En la mayoría de las aplicaciones, estos modelos "profundos" pueden reducirse a la composición de funciones simples que se integran de un espacio dimensional alto a otro. A primera vista, estos espacios pueden parecer demasiado grandes para pensar o visualizar, pero técnicas como t-SNE nos permiten empezar a entender lo que está ocurriendo dentro de la caja negra. Ahora, en lugar de tratar estos modelos como cajas negras, podemos empezar a visualizarlos y entenderlos.

Un comentario profundo 👏.

Pensamientos finales 🚀

Más allá de este post, t-SNE ha demostrado ser una herramienta de propósito general para reducir la dimensionalidad. Puede ser usado para explorar las relaciones dentro de los datos construyendo clusters, o para analizar casos de anomalías , mediante la inspección de los puntos aislados en el mapa.

Jugar con las dimensiones es un concepto clave en la ciencia de datos y en machine leraning. El parámetro de perplejidad es realmente similar al k en el algoritmo del vecino más cercano (k-NN). ¿Mapear datos en 2 dimensiones y luego hacer clustering? Hmmm eso no es nuevo amigo: Self-Organising Maps for Customer Segmentation.

Cuando seleccionamos las mejores variables para construir un modelo, estamos reduciendo la dimensión de los datos. Cuando construimos un modelo, estamos creando una función que describe las relaciones en los datos.... y así sucesivamente.....

¿Conocías los conceptos generales sobre k-NN y PCA? Bueno, este es un paso más, sólo hay que conectar los cables en el cerebro y ya está. El aprendizaje de conceptos generales nos da la oportunidad de hacer este tipo de asociaciones entre todas estas técnicas. Más allá de la comparación de lenguajes de programación, el poder -en mi opinión- es tener el foco en cómo se comportan los datos, y cómo estas técnicas están y pueden ser conectadas.


Explora la imaginación con este video de Carl Sagan: Tierra Plana y la 4ª Dimensión. Un cuento sobre la interacción de objetos 3D en un plano 2D....



📌 Continua aprendiendo sobre machine learning!

📗 Libro Vivo de Ciencia de Datos (open-source) Completamente disponible en línea!