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.
ML-For-Beginners/translations/fr/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb

499 lines
29 KiB

{
"cells": [
{
"cell_type": "markdown",
"source": [
"## **Musique nigériane extraite de Spotify - une analyse**\n",
"\n",
"Le clustering est un type d'[apprentissage non supervisé](https://wikipedia.org/wiki/Apprentissage_non_supervis%C3%A9) qui suppose qu'un ensemble de données n'est pas étiqueté ou que ses entrées ne sont pas associées à des sorties prédéfinies. Il utilise divers algorithmes pour trier les données non étiquetées et fournir des regroupements en fonction des motifs qu'il discerne dans les données.\n",
"\n",
"[**Quiz avant le cours**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/27/)\n",
"\n",
"### **Introduction**\n",
"\n",
"[Le clustering](https://link.springer.com/referenceworkentry/10.1007%2F978-0-387-30164-8_124) est très utile pour explorer les données. Voyons s'il peut aider à découvrir des tendances et des motifs dans la manière dont les audiences nigérianes consomment de la musique.\n",
"\n",
"> ✅ Prenez une minute pour réfléchir aux utilisations du clustering. Dans la vie quotidienne, le clustering se produit chaque fois que vous avez une pile de linge à trier pour séparer les vêtements des membres de votre famille 🧦👕👖🩲. En science des données, le clustering intervient lorsqu'il s'agit d'analyser les préférences d'un utilisateur ou de déterminer les caractéristiques d'un ensemble de données non étiqueté. Le clustering, d'une certaine manière, aide à donner du sens au chaos, comme un tiroir à chaussettes.\n",
"\n",
"Dans un cadre professionnel, le clustering peut être utilisé pour déterminer des segments de marché, comme identifier quels groupes d'âge achètent quels articles, par exemple. Une autre utilisation serait la détection d'anomalies, peut-être pour repérer des fraudes dans un ensemble de données de transactions par carte de crédit. Ou encore, vous pourriez utiliser le clustering pour identifier des tumeurs dans un lot de scans médicaux.\n",
"\n",
"✅ Prenez une minute pour réfléchir à la manière dont vous avez pu rencontrer le clustering 'dans la nature', dans un contexte bancaire, e-commerce ou commercial.\n",
"\n",
"> 🎓 Fait intéressant, l'analyse de clusters a vu le jour dans les domaines de l'anthropologie et de la psychologie dans les années 1930. Pouvez-vous imaginer comment elle aurait pu être utilisée ?\n",
"\n",
"Alternativement, vous pourriez l'utiliser pour regrouper des résultats de recherche - par liens d'achat, images ou avis, par exemple. Le clustering est utile lorsque vous avez un grand ensemble de données que vous souhaitez réduire et sur lequel vous voulez effectuer une analyse plus détaillée. Cette technique peut donc être utilisée pour mieux comprendre les données avant de construire d'autres modèles.\n",
"\n",
"✅ Une fois vos données organisées en clusters, vous leur attribuez un identifiant de cluster. Cette technique peut être utile pour préserver la confidentialité d'un ensemble de données ; vous pouvez alors vous référer à un point de données par son identifiant de cluster, plutôt que par des données identifiables plus révélatrices. Pouvez-vous penser à d'autres raisons pour lesquelles vous préféreriez utiliser un identifiant de cluster plutôt que d'autres éléments du cluster pour l'identifier ?\n",
"\n",
"### Premiers pas avec le clustering\n",
"\n",
"> 🎓 La manière dont nous créons des clusters dépend beaucoup de la façon dont nous regroupons les points de données en groupes. Décomposons un peu le vocabulaire :\n",
">\n",
"> 🎓 ['Transductif' vs. 'inductif'](https://wikipedia.org/wiki/Transduction_(machine_learning))\n",
">\n",
"> L'inférence transductive est dérivée des cas d'entraînement observés qui correspondent à des cas de test spécifiques. L'inférence inductive est dérivée des cas d'entraînement qui mènent à des règles générales, lesquelles sont ensuite appliquées aux cas de test.\n",
">\n",
"> Un exemple : Imaginez que vous avez un ensemble de données partiellement étiqueté. Certains éléments sont des 'disques', d'autres des 'CD', et certains sont vides. Votre tâche est de fournir des étiquettes pour les éléments vides. Si vous choisissez une approche inductive, vous entraîneriez un modèle à rechercher des 'disques' et des 'CD', et appliqueriez ces étiquettes aux données non étiquetées. Cette approche aurait du mal à classer des éléments qui sont en réalité des 'cassettes'. Une approche transductive, en revanche, gère ces données inconnues plus efficacement en regroupant des éléments similaires et en appliquant ensuite une étiquette à un groupe. Dans ce cas, les clusters pourraient refléter 'objets musicaux ronds' et 'objets musicaux carrés'.\n",
">\n",
"> 🎓 ['Géométrie non plate' vs. 'plate'](https://datascience.stackexchange.com/questions/52260/terminology-flat-geometry-in-the-context-of-clustering)\n",
">\n",
"> Tirée de la terminologie mathématique, la géométrie non plate vs. plate fait référence à la mesure des distances entre les points par des méthodes géométriques 'plates' ([Euclidiennes](https://wikipedia.org/wiki/G%C3%A9om%C3%A9trie_euclidienne)) ou 'non plates' (non Euclidiennes).\n",
">\n",
"> 'Plate' dans ce contexte fait référence à la géométrie Euclidienne (dont certaines parties sont enseignées comme la géométrie 'plane'), et 'non plate' fait référence à la géométrie non Euclidienne. Quel rapport avec l'apprentissage automatique ? Eh bien, en tant que deux domaines enracinés dans les mathématiques, il doit y avoir une manière commune de mesurer les distances entre les points dans les clusters, et cela peut être fait de manière 'plate' ou 'non plate', selon la nature des données. Les [distances Euclidiennes](https://wikipedia.org/wiki/Distance_euclidienne) sont mesurées comme la longueur d'un segment de ligne entre deux points. Les [distances non Euclidiennes](https://wikipedia.org/wiki/G%C3%A9om%C3%A9trie_non_euclidienne) sont mesurées le long d'une courbe. Si vos données, visualisées, semblent ne pas exister sur un plan, vous pourriez avoir besoin d'utiliser un algorithme spécialisé pour les traiter.\n",
"\n",
"<p >\n",
" <img src=\"../../images/flat-nonflat.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Infographie par Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"\n",
"> 🎓 ['Distances'](https://web.stanford.edu/class/cs345a/slides/12-clustering.pdf)\n",
">\n",
"> Les clusters sont définis par leur matrice de distances, c'est-à-dire les distances entre les points. Cette distance peut être mesurée de plusieurs façons. Les clusters Euclidiens sont définis par la moyenne des valeurs des points et contiennent un 'centroïde' ou point central. Les distances sont donc mesurées par rapport à ce centroïde. Les distances non Euclidiennes font référence aux 'clustroïdes', le point le plus proche des autres points. Les clustroïdes peuvent à leur tour être définis de différentes manières.\n",
">\n",
"> 🎓 ['Contraint'](https://wikipedia.org/wiki/Constrained_clustering)\n",
">\n",
"> Le [clustering contraint](https://web.cs.ucdavis.edu/~davidson/Publications/ICDMTutorial.pdf) introduit l'apprentissage 'semi-supervisé' dans cette méthode non supervisée. Les relations entre les points sont marquées comme 'ne peut pas lier' ou 'doit lier', ce qui impose certaines règles à l'ensemble de données.\n",
">\n",
"> Un exemple : Si un algorithme est laissé libre sur un lot de données non étiquetées ou semi-étiquetées, les clusters qu'il produit peuvent être de mauvaise qualité. Dans l'exemple ci-dessus, les clusters pourraient regrouper 'objets musicaux ronds', 'objets musicaux carrés', 'objets triangulaires' et 'biscuits'. Si on lui donne des contraintes ou des règles à suivre (\"l'objet doit être en plastique\", \"l'objet doit pouvoir produire de la musique\"), cela peut aider à 'contraindre' l'algorithme à faire de meilleurs choix.\n",
">\n",
"> 🎓 'Densité'\n",
">\n",
"> Les données 'bruyantes' sont considérées comme 'denses'. Les distances entre les points dans chacun de ses clusters peuvent s'avérer, après examen, plus ou moins denses, ou 'concentrées', et ces données doivent donc être analysées avec la méthode de clustering appropriée. [Cet article](https://www.kdnuggets.com/2020/02/understanding-density-based-clustering.html) montre la différence entre l'utilisation des algorithmes de clustering K-Means et HDBSCAN pour explorer un ensemble de données bruyant avec une densité de clusters inégale.\n",
"\n",
"Approfondissez votre compréhension des techniques de clustering dans ce [module d'apprentissage](https://docs.microsoft.com/learn/modules/train-evaluate-cluster-models?WT.mc_id=academic-77952-leestott)\n",
"\n",
"### **Algorithmes de clustering**\n",
"\n",
"Il existe plus de 100 algorithmes de clustering, et leur utilisation dépend de la nature des données à traiter. Discutons de quelques-uns des principaux :\n",
"\n",
"- **Clustering hiérarchique**. Si un objet est classé par sa proximité avec un objet voisin, plutôt qu'avec un objet plus éloigné, les clusters sont formés en fonction de la distance entre leurs membres. Le clustering hiérarchique se caractérise par la combinaison répétée de deux clusters.\n",
"\n",
"<p >\n",
" <img src=\"../../images/hierarchical.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Infographie par Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"\n",
"- **Clustering par centroïde**. Cet algorithme populaire nécessite de choisir 'k', ou le nombre de clusters à former, après quoi l'algorithme détermine le point central d'un cluster et regroupe les données autour de ce point. Le [clustering K-means](https://wikipedia.org/wiki/K-means_clustering) est une version populaire du clustering par centroïde qui divise un ensemble de données en K groupes prédéfinis. Le centre est déterminé par la moyenne la plus proche, d'où son nom. La distance au carré par rapport au cluster est minimisée.\n",
"\n",
"<p >\n",
" <img src=\"../../images/centroid.png\"\n",
" width=\"600\"/>\n",
" <figcaption>Infographie par Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"\n",
"- **Clustering basé sur la distribution**. Basé sur la modélisation statistique, le clustering basé sur la distribution se concentre sur la détermination de la probabilité qu'un point de données appartienne à un cluster, et l'y attribue en conséquence. Les méthodes de mélange gaussien appartiennent à ce type.\n",
"\n",
"- **Clustering basé sur la densité**. Les points de données sont attribués à des clusters en fonction de leur densité, ou de leur regroupement autour les uns des autres. Les points de données éloignés du groupe sont considérés comme des anomalies ou du bruit. DBSCAN, Mean-shift et OPTICS appartiennent à ce type de clustering.\n",
"\n",
"- **Clustering basé sur une grille**. Pour les ensembles de données multidimensionnels, une grille est créée et les données sont réparties entre les cellules de la grille, créant ainsi des clusters.\n",
"\n",
"La meilleure façon d'apprendre le clustering est de l'essayer vous-même, et c'est ce que vous ferez dans cet exercice.\n",
"\n",
"Nous aurons besoin de quelques packages pour compléter ce module. Vous pouvez les installer avec : `install.packages(c('tidyverse', 'tidymodels', 'DataExplorer', 'summarytools', 'plotly', 'paletteer', 'corrplot', 'patchwork'))`\n",
"\n",
"Alternativement, le script ci-dessous vérifie si vous avez les packages nécessaires pour compléter ce module et les installe pour vous si certains sont manquants.\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": [
"## Exercice - Regroupez vos données\n",
"\n",
"Le clustering, en tant que technique, est grandement facilité par une bonne visualisation. Commençons donc par visualiser nos données musicales. Cet exercice nous aidera à déterminer quelle méthode de clustering utiliser le plus efficacement en fonction de la nature de ces données.\n",
"\n",
"Allons-y directement en important les données.\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": [
"Parfois, nous pouvons vouloir obtenir un peu plus d'informations sur nos données. Nous pouvons examiner les `données` et `leur structure` en utilisant la fonction [*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": [
"Bon travail ! 💪\n",
"\n",
"On peut observer que `glimpse()` vous donne le nombre total de lignes (observations) et de colonnes (variables), puis les premières entrées de chaque variable dans une ligne après le nom de la variable. De plus, le *type de données* de la variable est indiqué immédiatement après le nom de chaque variable entre `< >`.\n",
"\n",
"`DataExplorer::introduce()` peut résumer ces informations de manière concise :\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": [
"Super ! Nous venons d'apprendre que nos données ne contiennent aucune valeur manquante.\n",
"\n",
"Pendant que nous y sommes, nous pouvons explorer les statistiques courantes de tendance centrale (par exemple, [moyenne](https://en.wikipedia.org/wiki/Arithmetic_mean) et [médiane](https://en.wikipedia.org/wiki/Median)) ainsi que les mesures de dispersion (par exemple, [écart-type](https://en.wikipedia.org/wiki/Standard_deviation)) en utilisant `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": [
"Examinons les valeurs générales des données. Notez que la popularité peut être `0`, ce qui indique des chansons qui n'ont pas de classement. Nous les supprimerons bientôt.\n",
"\n",
"> 🤔 Si nous travaillons avec le clustering, une méthode non supervisée qui ne nécessite pas de données étiquetées, pourquoi montrons-nous ces données avec des étiquettes ? Lors de la phase d'exploration des données, elles sont utiles, mais elles ne sont pas nécessaires pour que les algorithmes de clustering fonctionnent.\n",
"\n",
"### 1. Explorer les genres populaires\n",
"\n",
"Allons-y et découvrons les genres les plus populaires 🎶 en comptant le nombre d'occurrences.\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": [
"Ça s'est bien passé ! On dit qu'une image vaut mille lignes d'un tableau de données (en fait, personne ne dit jamais ça 😅). Mais vous voyez l'idée, n'est-ce pas ?\n",
"\n",
"Une façon de visualiser des données catégoriques (variables de type caractère ou facteur) est d'utiliser des diagrammes en barres. Créons un diagramme en barres des 10 genres les plus populaires :\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": [
"Maintenant, c'est beaucoup plus facile d'identifier que nous avons des genres `manquants` 🧐 !\n",
"\n",
"> Une bonne visualisation vous montrera des choses auxquelles vous ne vous attendiez pas, ou soulèvera de nouvelles questions sur les données - Hadley Wickham et Garrett Grolemund, [R For Data Science](https://r4ds.had.co.nz/introduction.html)\n",
"\n",
"Notez que lorsque le genre principal est décrit comme `Manquant`, cela signifie que Spotify ne l'a pas classifié, alors débarrassons-nous-en.\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": [
"À partir de cette petite exploration des données, nous apprenons que les trois genres principaux dominent ce jeu de données. Concentrons-nous sur `afro dancehall`, `afropop` et `nigerian pop`, et filtrons également le jeu de données pour supprimer tout ce qui a une valeur de popularité égale à 0 (ce qui signifie qu'il n'a pas été classé avec une popularité dans le jeu de données et peut être considéré comme du bruit pour nos objectifs) :\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": [
"Voyons s'il existe une relation linéaire apparente entre les variables numériques de notre ensemble de données. Cette relation est quantifiée mathématiquement par la [statistique de corrélation](https://en.wikipedia.org/wiki/Correlation).\n",
"\n",
"La statistique de corrélation est une valeur comprise entre -1 et 1 qui indique la force d'une relation. Des valeurs supérieures à 0 indiquent une corrélation *positive* (des valeurs élevées d'une variable tendent à coïncider avec des valeurs élevées de l'autre), tandis que des valeurs inférieures à 0 indiquent une corrélation *négative* (des valeurs élevées d'une variable tendent à coïncider avec des valeurs faibles de l'autre).\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": [
"Les données ne sont pas fortement corrélées, sauf entre `energy` et `loudness`, ce qui est logique, étant donné que la musique forte est généralement assez énergique. `Popularity` a une correspondance avec `release date`, ce qui est également logique, car les chansons plus récentes sont probablement plus populaires. La longueur et l'énergie semblent également avoir une corrélation.\n",
"\n",
"Il sera intéressant de voir ce qu'un algorithme de clustering peut tirer de ces données !\n",
"\n",
"> 🎓 Notez que corrélation ne signifie pas causalité ! Nous avons une preuve de corrélation, mais aucune preuve de causalité. Un [site web amusant](https://tylervigen.com/spurious-correlations) propose des visuels qui soulignent ce point.\n",
"\n",
"### 2. Explorer la distribution des données\n",
"\n",
"Posons-nous des questions plus subtiles. Les genres sont-ils significativement différents dans la perception de leur danseabilité, en fonction de leur popularité ? Examinons la distribution des données de nos trois genres principaux pour la popularité et la danseabilité le long d'un axe x et y donné à l'aide de [courbes de densité](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": [
"Nous observons que des cercles concentriques s'alignent, quel que soit le genre. Serait-il possible que les goûts nigérians convergent à un certain niveau de dansabilité pour ce genre ?\n",
"\n",
"En général, les trois genres s'alignent en termes de popularité et de dansabilité. Identifier des regroupements dans ces données faiblement alignées sera un défi. Voyons si un diagramme de dispersion peut nous aider à confirmer cela.\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 nuage de points des mêmes axes montre un schéma similaire de convergence.\n",
"\n",
"En général, pour le regroupement, vous pouvez utiliser des nuages de points pour montrer des groupes de données, donc maîtriser ce type de visualisation est très utile. Dans la prochaine leçon, nous utiliserons ces données filtrées et appliquerons le regroupement par k-means pour découvrir des groupes dans ces données qui semblent se chevaucher de manière intéressante.\n",
"\n",
"## **🚀 Défi**\n",
"\n",
"En préparation de la prochaine leçon, créez un graphique sur les différents algorithmes de regroupement que vous pourriez découvrir et utiliser dans un environnement de production. Quels types de problèmes le regroupement cherche-t-il à résoudre ?\n",
"\n",
"## [**Quiz après le cours**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/28/)\n",
"\n",
"## **Révision & Auto-apprentissage**\n",
"\n",
"Avant d'appliquer des algorithmes de regroupement, comme nous l'avons appris, il est important de comprendre la nature de votre jeu de données. Lisez davantage sur ce sujet [ici](https://www.kdnuggets.com/2019/10/right-clustering-algorithm.html)\n",
"\n",
"Approfondissez votre compréhension des techniques de regroupement :\n",
"\n",
"- [Entraîner et évaluer des modèles de regroupement avec Tidymodels et ses outils](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",
"## **Devoir**\n",
"\n",
"[Explorez d'autres visualisations pour le regroupement](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/assignment.md)\n",
"\n",
"## REMERCIEMENTS À :\n",
"\n",
"[Jen Looper](https://www.twitter.com/jenlooper) pour avoir créé la version originale en Python de ce module ♥️\n",
"\n",
"[`Dasani Madipalli`](https://twitter.com/dasani_decoded) pour avoir créé les illustrations incroyables qui rendent les concepts d'apprentissage automatique plus compréhensibles et faciles à assimiler.\n",
"\n",
"Bon apprentissage,\n",
"\n",
"[Eric](https://twitter.com/ericntay), Gold Microsoft Learn Student Ambassador.\n"
],
"metadata": {}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Avertissement** : \nCe document a été traduit à l'aide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions d'assurer l'exactitude, veuillez noter que les traductions automatisées peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue d'origine doit être considéré comme la source faisant autorité. Pour des informations critiques, il est recommandé de faire appel à une traduction humaine professionnelle. Nous déclinons toute responsabilité en cas de malentendus ou d'interprétations erronées résultant de l'utilisation de cette traduction.\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:01:19+00:00",
"source_file": "5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb",
"language_code": "fr"
}
},
"nbformat": 4,
"nbformat_minor": 1
}