You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
493 lines
28 KiB
493 lines
28 KiB
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## **Análisis de música nigeriana extraída de Spotify**\n",
|
|
"\n",
|
|
"El clustering es un tipo de [aprendizaje no supervisado](https://wikipedia.org/wiki/Aprendizaje_no_supervisado) que asume que un conjunto de datos no está etiquetado o que sus entradas no están asociadas a salidas predefinidas. Utiliza varios algoritmos para clasificar datos no etiquetados y proporcionar agrupaciones según los patrones que detecta en los datos.\n",
|
|
"\n",
|
|
"[**Cuestionario previo a la lección**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/27/)\n",
|
|
"\n",
|
|
"### **Introducción**\n",
|
|
"\n",
|
|
"El [clustering](https://link.springer.com/referenceworkentry/10.1007%2F978-0-387-30164-8_124) es muy útil para la exploración de datos. Veamos si puede ayudar a descubrir tendencias y patrones en la forma en que las audiencias nigerianas consumen música.\n",
|
|
"\n",
|
|
"> ✅ Tómate un minuto para pensar en los usos del clustering. En la vida cotidiana, el clustering ocurre cuando tienes un montón de ropa sucia y necesitas clasificar la ropa de los miembros de tu familia 🧦👕👖🩲. En ciencia de datos, el clustering ocurre al intentar analizar las preferencias de un usuario o determinar las características de un conjunto de datos no etiquetado. El clustering, de alguna manera, ayuda a dar sentido al caos, como un cajón de calcetines.\n",
|
|
"\n",
|
|
"En un entorno profesional, el clustering puede usarse para determinar cosas como la segmentación de mercado, identificando qué grupos de edad compran qué productos, por ejemplo. Otro uso sería la detección de anomalías, tal vez para identificar fraudes en un conjunto de datos de transacciones con tarjetas de crédito. O podrías usar el clustering para identificar tumores en un lote de escaneos médicos.\n",
|
|
"\n",
|
|
"✅ Piensa un momento en cómo podrías haber encontrado clustering \"en la vida real\", en un entorno bancario, de comercio electrónico o empresarial.\n",
|
|
"\n",
|
|
"> 🎓 Curiosamente, el análisis de clústeres se originó en los campos de la Antropología y la Psicología en la década de 1930. ¿Puedes imaginar cómo podría haberse utilizado?\n",
|
|
"\n",
|
|
"Alternativamente, podrías usarlo para agrupar resultados de búsqueda, como enlaces de compras, imágenes o reseñas, por ejemplo. El clustering es útil cuando tienes un conjunto de datos grande que deseas reducir y sobre el cual deseas realizar un análisis más detallado, por lo que la técnica puede usarse para aprender sobre los datos antes de construir otros modelos.\n",
|
|
"\n",
|
|
"✅ Una vez que tus datos están organizados en clústeres, les asignas un Id de clúster, y esta técnica puede ser útil para preservar la privacidad de un conjunto de datos; en lugar de referirte a un punto de datos por información más reveladora, puedes referirte a él por su Id de clúster. ¿Puedes pensar en otras razones por las que preferirías referirte a un Id de clúster en lugar de otros elementos del clúster para identificarlo?\n",
|
|
"\n",
|
|
"### Comenzando con el clustering\n",
|
|
"\n",
|
|
"> 🎓 La forma en que creamos clústeres tiene mucho que ver con cómo agrupamos los puntos de datos. Vamos a desglosar algo de vocabulario:\n",
|
|
">\n",
|
|
"> 🎓 ['Transductivo' vs. 'inductivo'](https://wikipedia.org/wiki/Transduction_(machine_learning))\n",
|
|
">\n",
|
|
"> La inferencia transductiva se deriva de casos de entrenamiento observados que se mapean a casos de prueba específicos. La inferencia inductiva se deriva de casos de entrenamiento que se mapean a reglas generales que luego se aplican a los casos de prueba.\n",
|
|
">\n",
|
|
"> Un ejemplo: Imagina que tienes un conjunto de datos que está parcialmente etiquetado. Algunas cosas son 'discos', otras 'CDs', y otras están en blanco. Tu tarea es proporcionar etiquetas para los elementos en blanco. Si eliges un enfoque inductivo, entrenarías un modelo buscando 'discos' y 'CDs', y aplicarías esas etiquetas a tus datos no etiquetados. Este enfoque tendrá problemas para clasificar cosas que en realidad son 'cassettes'. Un enfoque transductivo, por otro lado, maneja estos datos desconocidos de manera más efectiva al agrupar elementos similares y luego aplicar una etiqueta a un grupo. En este caso, los clústeres podrían reflejar 'cosas musicales redondas' y 'cosas musicales cuadradas'.\n",
|
|
">\n",
|
|
"> 🎓 ['Geometría no plana' vs. 'plana'](https://datascience.stackexchange.com/questions/52260/terminology-flat-geometry-in-the-context-of-clustering)\n",
|
|
">\n",
|
|
"> Derivado de la terminología matemática, la geometría no plana vs. plana se refiere a la medida de distancias entre puntos mediante métodos geométricos 'planos' ([Euclidianos](https://wikipedia.org/wiki/Geometr%C3%ADa_euclidiana)) o 'no planos' (no Euclidianos).\n",
|
|
">\n",
|
|
"> 'Plana' en este contexto se refiere a la geometría Euclidiana (partes de la cual se enseñan como geometría 'plana'), y no plana se refiere a la geometría no Euclidiana. ¿Qué tiene que ver la geometría con el aprendizaje automático? Bueno, como dos campos que tienen raíces en las matemáticas, debe haber una forma común de medir distancias entre puntos en clústeres, y eso puede hacerse de manera 'plana' o 'no plana', dependiendo de la naturaleza de los datos. Las [distancias Euclidianas](https://wikipedia.org/wiki/Distancia_euclidiana) se miden como la longitud de un segmento de línea entre dos puntos. Las [distancias no Euclidianas](https://wikipedia.org/wiki/Geometr%C3%ADa_no_euclidiana) se miden a lo largo de una curva. Si tus datos, al visualizarlos, parecen no existir en un plano, podrías necesitar usar un algoritmo especializado para manejarlos.\n",
|
|
"\n",
|
|
"<p>\n",
|
|
" <img src=\"../../images/flat-nonflat.png\"\n",
|
|
" width=\"600\"/>\n",
|
|
" <figcaption>Infografía por Dasani Madipalli</figcaption>\n",
|
|
"\n",
|
|
"> 🎓 ['Distancias'](https://web.stanford.edu/class/cs345a/slides/12-clustering.pdf)\n",
|
|
">\n",
|
|
"> Los clústeres se definen por su matriz de distancias, es decir, las distancias entre puntos. Esta distancia puede medirse de varias maneras. Los clústeres Euclidianos se definen por el promedio de los valores de los puntos y contienen un 'centroide' o punto central. Las distancias se miden por la distancia a ese centroide. Las distancias no Euclidianas se refieren a 'clustroides', el punto más cercano a otros puntos. Los clustroides, a su vez, pueden definirse de varias maneras.\n",
|
|
">\n",
|
|
"> 🎓 ['Restringido'](https://wikipedia.org/wiki/Constrained_clustering)\n",
|
|
">\n",
|
|
"> El [clustering restringido](https://web.cs.ucdavis.edu/~davidson/Publications/ICDMTutorial.pdf) introduce el aprendizaje 'semi-supervisado' en este método no supervisado. Las relaciones entre puntos se marcan como 'no puede enlazar' o 'debe enlazar', de modo que se imponen algunas reglas al conjunto de datos.\n",
|
|
">\n",
|
|
"> Un ejemplo: Si un algoritmo se deja libre en un lote de datos no etiquetados o semi-etiquetados, los clústeres que produce pueden ser de baja calidad. En el ejemplo anterior, los clústeres podrían agrupar 'cosas musicales redondas', 'cosas musicales cuadradas', 'cosas triangulares' y 'galletas'. Si se le dan algunas restricciones o reglas a seguir (\"el objeto debe estar hecho de plástico\", \"el objeto debe ser capaz de producir música\"), esto puede ayudar a 'restringir' el algoritmo para tomar mejores decisiones.\n",
|
|
">\n",
|
|
"> 🎓 'Densidad'\n",
|
|
">\n",
|
|
"> Los datos que son 'ruidosos' se consideran 'densos'. Las distancias entre puntos en cada uno de sus clústeres pueden resultar, al examinarlas, más o menos densas, o 'congestionadas', y por lo tanto estos datos necesitan ser analizados con el método de clustering apropiado. [Este artículo](https://www.kdnuggets.com/2020/02/understanding-density-based-clustering.html) demuestra la diferencia entre usar el clustering K-Means y los algoritmos HDBSCAN para explorar un conjunto de datos ruidoso con densidad de clúster desigual.\n",
|
|
"\n",
|
|
"Profundiza tu comprensión de las técnicas de clustering en este [módulo de aprendizaje](https://docs.microsoft.com/learn/modules/train-evaluate-cluster-models?WT.mc_id=academic-77952-leestott)\n",
|
|
"\n",
|
|
"### **Algoritmos de clustering**\n",
|
|
"\n",
|
|
"Existen más de 100 algoritmos de clustering, y su uso depende de la naturaleza de los datos en cuestión. Hablemos de algunos de los principales:\n",
|
|
"\n",
|
|
"- **Clustering jerárquico**. Si un objeto se clasifica por su proximidad a un objeto cercano, en lugar de uno más lejano, los clústeres se forman en función de la distancia entre sus miembros. El clustering jerárquico se caracteriza por combinar repetidamente dos clústeres.\n",
|
|
"\n",
|
|
"<p>\n",
|
|
" <img src=\"../../images/hierarchical.png\"\n",
|
|
" width=\"600\"/>\n",
|
|
" <figcaption>Infografía por Dasani Madipalli</figcaption>\n",
|
|
"\n",
|
|
"- **Clustering por centroides**. Este algoritmo popular requiere elegir 'k', o el número de clústeres a formar, después de lo cual el algoritmo determina el punto central de un clúster y agrupa los datos alrededor de ese punto. El [clustering K-means](https://wikipedia.org/wiki/K-means_clustering) es una versión popular de clustering por centroides que separa un conjunto de datos en K grupos predefinidos. El centro se determina por la media más cercana, de ahí el nombre. La distancia cuadrada desde el clúster se minimiza.\n",
|
|
"\n",
|
|
"<p>\n",
|
|
" <img src=\"../../images/centroid.png\"\n",
|
|
" width=\"600\"/>\n",
|
|
" <figcaption>Infografía por Dasani Madipalli</figcaption>\n",
|
|
"\n",
|
|
"- **Clustering basado en distribución**. Basado en modelos estadísticos, el clustering basado en distribución se centra en determinar la probabilidad de que un punto de datos pertenezca a un clúster y asignarlo en consecuencia. Los métodos de mezcla gaussiana pertenecen a este tipo.\n",
|
|
"\n",
|
|
"- **Clustering basado en densidad**. Los puntos de datos se asignan a clústeres en función de su densidad, o su agrupación entre sí. Los puntos de datos alejados del grupo se consideran valores atípicos o ruido. DBSCAN, Mean-shift y OPTICS pertenecen a este tipo de clustering.\n",
|
|
"\n",
|
|
"- **Clustering basado en cuadrícula**. Para conjuntos de datos multidimensionales, se crea una cuadrícula y los datos se dividen entre las celdas de la cuadrícula, creando así clústeres.\n",
|
|
"\n",
|
|
"La mejor manera de aprender sobre clustering es probarlo tú mismo, así que eso es lo que harás en este ejercicio.\n",
|
|
"\n",
|
|
"Necesitaremos algunos paquetes para completar este módulo. Puedes instalarlos con: `install.packages(c('tidyverse', 'tidymodels', 'DataExplorer', 'summarytools', 'plotly', 'paletteer', 'corrplot', 'patchwork'))`\n",
|
|
"\n",
|
|
"Alternativamente, el siguiente script verifica si tienes los paquetes necesarios para completar este módulo e instala los que falten.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\r\n",
|
|
"\r\n",
|
|
"pacman::p_load('tidyverse', 'tidymodels', 'DataExplorer', 'summarytools', 'plotly', 'paletteer', 'corrplot', 'patchwork')\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## Ejercicio - agrupa tus datos\n",
|
|
"\n",
|
|
"El clustering como técnica se beneficia enormemente de una visualización adecuada, así que comencemos visualizando nuestros datos musicales. Este ejercicio nos ayudará a decidir cuál de los métodos de clustering deberíamos usar de manera más efectiva según la naturaleza de estos datos.\n",
|
|
"\n",
|
|
"Comencemos importando los datos.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Load the core tidyverse and make it available in your current R session\r\n",
|
|
"library(tidyverse)\r\n",
|
|
"\r\n",
|
|
"# Import the data into a tibble\r\n",
|
|
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/5-Clustering/data/nigerian-songs.csv\")\r\n",
|
|
"\r\n",
|
|
"# View the first 5 rows of the data set\r\n",
|
|
"df %>% \r\n",
|
|
" slice_head(n = 5)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"A veces, podemos querer un poco más de información sobre nuestros datos. Podemos echar un vistazo a los `datos` y a `su estructura` utilizando la función [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html):\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Glimpse into the data set\r\n",
|
|
"df %>% \r\n",
|
|
" glimpse()\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"¡Buen trabajo!💪\n",
|
|
"\n",
|
|
"Podemos observar que `glimpse()` te mostrará el número total de filas (observaciones) y columnas (variables), seguido de las primeras entradas de cada variable en una fila después del nombre de la variable. Además, el *tipo de dato* de la variable se muestra inmediatamente después del nombre de cada variable dentro de `< >`.\n",
|
|
"\n",
|
|
"`DataExplorer::introduce()` puede resumir esta información de manera ordenada:\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Describe basic information for our data\r\n",
|
|
"df %>% \r\n",
|
|
" introduce()\r\n",
|
|
"\r\n",
|
|
"# A visual display of the same\r\n",
|
|
"df %>% \r\n",
|
|
" plot_intro()\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"¡Genial! Acabamos de aprender que nuestros datos no tienen valores faltantes.\n",
|
|
"\n",
|
|
"Mientras estamos en ello, podemos explorar estadísticas comunes de tendencia central (por ejemplo, [media](https://en.wikipedia.org/wiki/Arithmetic_mean) y [mediana](https://en.wikipedia.org/wiki/Median)) y medidas de dispersión (por ejemplo, [desviación estándar](https://en.wikipedia.org/wiki/Standard_deviation)) utilizando `summarytools::descr()`\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Describe common statistics\r\n",
|
|
"df %>% \r\n",
|
|
" descr(stats = \"common\")\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Veamos los valores generales de los datos. Ten en cuenta que la popularidad puede ser `0`, lo que indica canciones que no tienen clasificación. Eliminaremos esos datos en breve.\n",
|
|
"\n",
|
|
"> 🤔 Si estamos trabajando con clustering, un método no supervisado que no requiere datos etiquetados, ¿por qué estamos mostrando estos datos con etiquetas? En la fase de exploración de datos, son útiles, pero no son necesarios para que los algoritmos de clustering funcionen.\n",
|
|
"\n",
|
|
"### 1. Explorar géneros populares\n",
|
|
"\n",
|
|
"Vamos a descubrir cuáles son los géneros más populares 🎶 haciendo un conteo de las veces que aparecen.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Popular genres\r\n",
|
|
"top_genres <- df %>% \r\n",
|
|
" count(artist_top_genre, sort = TRUE) %>% \r\n",
|
|
"# Encode to categorical and reorder the according to count\r\n",
|
|
" mutate(artist_top_genre = factor(artist_top_genre) %>% fct_inorder())\r\n",
|
|
"\r\n",
|
|
"# Print the top genres\r\n",
|
|
"top_genres\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"¡Eso salió bien! Dicen que una imagen vale más que mil filas de un marco de datos (en realidad, nadie dice eso 😅). Pero entiendes la idea, ¿verdad?\n",
|
|
"\n",
|
|
"Una forma de visualizar datos categóricos (variables de tipo carácter o factor) es utilizando gráficos de barras. Hagamos un gráfico de barras con los 10 géneros principales:\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Change the default gray theme\r\n",
|
|
"theme_set(theme_light())\r\n",
|
|
"\r\n",
|
|
"# Visualize popular genres\r\n",
|
|
"top_genres %>%\r\n",
|
|
" slice(1:10) %>% \r\n",
|
|
" ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n",
|
|
" fill = artist_top_genre)) +\r\n",
|
|
" geom_col(alpha = 0.8) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"rcartocolor::Vivid\") +\r\n",
|
|
" ggtitle(\"Top genres\") +\r\n",
|
|
" theme(plot.title = element_text(hjust = 0.5),\r\n",
|
|
" # Rotates the X markers (so we can read them)\r\n",
|
|
" axis.text.x = element_text(angle = 90))\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"¡Ahora es mucho más fácil identificar que tenemos géneros `missing` 🧐!\n",
|
|
"\n",
|
|
"> Una buena visualización te mostrará cosas que no esperabas, o planteará nuevas preguntas sobre los datos - Hadley Wickham y Garrett Grolemund, [R For Data Science](https://r4ds.had.co.nz/introduction.html)\n",
|
|
"\n",
|
|
"Nota: cuando el género principal se describe como `Missing`, significa que Spotify no lo clasificó, así que eliminémoslo.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Visualize popular genres\r\n",
|
|
"top_genres %>%\r\n",
|
|
" filter(artist_top_genre != \"Missing\") %>% \r\n",
|
|
" slice(1:10) %>% \r\n",
|
|
" ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n",
|
|
" fill = artist_top_genre)) +\r\n",
|
|
" geom_col(alpha = 0.8) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"rcartocolor::Vivid\") +\r\n",
|
|
" ggtitle(\"Top genres\") +\r\n",
|
|
" theme(plot.title = element_text(hjust = 0.5),\r\n",
|
|
" # Rotates the X markers (so we can read them)\r\n",
|
|
" axis.text.x = element_text(angle = 90))\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"A partir de la pequeña exploración de datos, aprendemos que los tres géneros principales dominan este conjunto de datos. Vamos a concentrarnos en `afro dancehall`, `afropop` y `nigerian pop`, además de filtrar el conjunto de datos para eliminar cualquier elemento con un valor de popularidad de 0 (lo que significa que no fue clasificado con una popularidad en el conjunto de datos y puede considerarse ruido para nuestros propósitos):\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"nigerian_songs <- df %>% \r\n",
|
|
" # Concentrate on top 3 genres\r\n",
|
|
" filter(artist_top_genre %in% c(\"afro dancehall\", \"afropop\",\"nigerian pop\")) %>% \r\n",
|
|
" # Remove unclassified observations\r\n",
|
|
" filter(popularity != 0)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Visualize popular genres\r\n",
|
|
"nigerian_songs %>%\r\n",
|
|
" count(artist_top_genre) %>%\r\n",
|
|
" ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n",
|
|
" fill = artist_top_genre)) +\r\n",
|
|
" geom_col(alpha = 0.8) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"ggsci::category10_d3\") +\r\n",
|
|
" ggtitle(\"Top genres\") +\r\n",
|
|
" theme(plot.title = element_text(hjust = 0.5))\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Veamos si existe alguna relación lineal aparente entre las variables numéricas de nuestro conjunto de datos. Esta relación se cuantifica matemáticamente mediante la [estadística de correlación](https://en.wikipedia.org/wiki/Correlation).\n",
|
|
"\n",
|
|
"La estadística de correlación es un valor entre -1 y 1 que indica la fuerza de una relación. Los valores por encima de 0 indican una correlación *positiva* (valores altos de una variable tienden a coincidir con valores altos de la otra), mientras que los valores por debajo de 0 indican una correlación *negativa* (valores altos de una variable tienden a coincidir con valores bajos de la otra).\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Narrow down to numeric variables and fid correlation\r\n",
|
|
"corr_mat <- nigerian_songs %>% \r\n",
|
|
" select(where(is.numeric)) %>% \r\n",
|
|
" cor()\r\n",
|
|
"\r\n",
|
|
"# Visualize correlation matrix\r\n",
|
|
"corrplot(corr_mat, order = 'AOE', col = c('white', 'black'), bg = 'gold2') \r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Los datos no están fuertemente correlacionados, excepto entre `energy` y `loudness`, lo cual tiene sentido, dado que la música fuerte suele ser bastante enérgica. `Popularity` tiene una correspondencia con `release date`, lo que también tiene sentido, ya que las canciones más recientes probablemente sean más populares. La duración y la energía parecen tener una correlación también.\n",
|
|
"\n",
|
|
"¡Será interesante ver qué puede hacer un algoritmo de agrupamiento con estos datos!\n",
|
|
"\n",
|
|
"> 🎓 Ten en cuenta que la correlación no implica causalidad. Tenemos prueba de correlación, pero no prueba de causalidad. Un [sitio web divertido](https://tylervigen.com/spurious-correlations) tiene algunos gráficos que enfatizan este punto.\n",
|
|
"\n",
|
|
"### 2. Explorar la distribución de los datos\n",
|
|
"\n",
|
|
"Hagamos preguntas más sutiles. ¿Son los géneros significativamente diferentes en la percepción de su capacidad para bailar, según su popularidad? Examinemos la distribución de datos de nuestros tres géneros principales en términos de popularidad y capacidad para bailar a lo largo de un eje x y y utilizando [gráficos de densidad](https://www.khanacademy.org/math/ap-statistics/density-curves-normal-distribution-ap/density-curves/v/density-curves).\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Perform 2D kernel density estimation\r\n",
|
|
"density_estimate_2d <- nigerian_songs %>% \r\n",
|
|
" ggplot(mapping = aes(x = popularity, y = danceability, color = artist_top_genre)) +\r\n",
|
|
" geom_density_2d(bins = 5, size = 1) +\r\n",
|
|
" paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
|
|
" xlim(-20, 80) +\r\n",
|
|
" ylim(0, 1.2)\r\n",
|
|
"\r\n",
|
|
"# Density plot based on the popularity\r\n",
|
|
"density_estimate_pop <- nigerian_songs %>% \r\n",
|
|
" ggplot(mapping = aes(x = popularity, fill = artist_top_genre, color = artist_top_genre)) +\r\n",
|
|
" geom_density(size = 1, alpha = 0.5) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
|
|
" paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
|
|
" theme(legend.position = \"none\")\r\n",
|
|
"\r\n",
|
|
"# Density plot based on the danceability\r\n",
|
|
"density_estimate_dance <- nigerian_songs %>% \r\n",
|
|
" ggplot(mapping = aes(x = danceability, fill = artist_top_genre, color = artist_top_genre)) +\r\n",
|
|
" geom_density(size = 1, alpha = 0.5) +\r\n",
|
|
" paletteer::scale_fill_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
|
|
" paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Patch everything together\r\n",
|
|
"library(patchwork)\r\n",
|
|
"density_estimate_2d / (density_estimate_pop + density_estimate_dance)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Vemos que hay círculos concéntricos que se alinean, independientemente del género. ¿Podría ser que los gustos nigerianos convergen en cierto nivel de bailabilidad para este género?\n",
|
|
"\n",
|
|
"En general, los tres géneros se alinean en términos de su popularidad y bailabilidad. Determinar agrupaciones en estos datos ligeramente alineados será un desafío. Veamos si un gráfico de dispersión puede respaldar esto.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# A scatter plot of popularity and danceability\r\n",
|
|
"scatter_plot <- nigerian_songs %>% \r\n",
|
|
" ggplot(mapping = aes(x = popularity, y = danceability, color = artist_top_genre, shape = artist_top_genre)) +\r\n",
|
|
" geom_point(size = 2, alpha = 0.8) +\r\n",
|
|
" paletteer::scale_color_paletteer_d(\"futurevisions::mars\")\r\n",
|
|
"\r\n",
|
|
"# Add a touch of interactivity\r\n",
|
|
"ggplotly(scatter_plot)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Un diagrama de dispersión de los mismos ejes muestra un patrón similar de convergencia.\n",
|
|
"\n",
|
|
"En general, para la agrupación, puedes usar diagramas de dispersión para mostrar grupos de datos, por lo que dominar este tipo de visualización es muy útil. En la próxima lección, tomaremos estos datos filtrados y utilizaremos el agrupamiento k-means para descubrir grupos en estos datos que parecen superponerse de maneras interesantes.\n",
|
|
"\n",
|
|
"## **🚀 Desafío**\n",
|
|
"\n",
|
|
"En preparación para la próxima lección, crea un gráfico sobre los diversos algoritmos de agrupamiento que podrías descubrir y usar en un entorno de producción. ¿Qué tipos de problemas está tratando de resolver el agrupamiento?\n",
|
|
"\n",
|
|
"## [**Cuestionario posterior a la lección**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/28/)\n",
|
|
"\n",
|
|
"## **Revisión y autoestudio**\n",
|
|
"\n",
|
|
"Antes de aplicar algoritmos de agrupamiento, como hemos aprendido, es una buena idea entender la naturaleza de tu conjunto de datos. Lee más sobre este tema [aquí](https://www.kdnuggets.com/2019/10/right-clustering-algorithm.html)\n",
|
|
"\n",
|
|
"Profundiza tu comprensión de las técnicas de agrupamiento:\n",
|
|
"\n",
|
|
"- [Entrena y evalúa modelos de agrupamiento usando Tidymodels y amigos](https://rpubs.com/eR_ic/clustering)\n",
|
|
"\n",
|
|
"- Bradley Boehmke & Brandon Greenwell, [*Hands-On Machine Learning with R*](https://bradleyboehmke.github.io/HOML/)*.*\n",
|
|
"\n",
|
|
"## **Tarea**\n",
|
|
"\n",
|
|
"[Investiga otras visualizaciones para agrupamiento](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/assignment.md)\n",
|
|
"\n",
|
|
"## AGRADECIMIENTOS A:\n",
|
|
"\n",
|
|
"[Jen Looper](https://www.twitter.com/jenlooper) por crear la versión original en Python de este módulo ♥️\n",
|
|
"\n",
|
|
"[`Dasani Madipalli`](https://twitter.com/dasani_decoded) por crear las increíbles ilustraciones que hacen que los conceptos de aprendizaje automático sean más interpretables y fáciles de entender.\n",
|
|
"\n",
|
|
"Feliz aprendizaje,\n",
|
|
"\n",
|
|
"[Eric](https://twitter.com/ericntay), Embajador Estudiantil Gold de Microsoft Learn.\n"
|
|
],
|
|
"metadata": {}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**Descargo de responsabilidad**: \nEste documento ha sido traducido utilizando el servicio de traducción automática [Co-op Translator](https://github.com/Azure/co-op-translator). Si bien nos esforzamos por lograr precisión, tenga en cuenta que las traducciones automáticas pueden contener errores o imprecisiones. El documento original en su idioma nativo debe considerarse como la fuente autorizada. Para información crítica, se recomienda una traducción profesional realizada por humanos. No nos hacemos responsables de malentendidos o interpretaciones erróneas que puedan surgir del uso de esta traducción.\n"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"anaconda-cloud": "",
|
|
"kernelspec": {
|
|
"display_name": "R",
|
|
"language": "R",
|
|
"name": "ir"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": "r",
|
|
"file_extension": ".r",
|
|
"mimetype": "text/x-r-source",
|
|
"name": "R",
|
|
"pygments_lexer": "r",
|
|
"version": "3.4.1"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "99c36449cad3708a435f6798cfa39972",
|
|
"translation_date": "2025-09-04T02:05:14+00:00",
|
|
"source_file": "5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb",
|
|
"language_code": "es"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 1
|
|
} |