library(mvtnorm) # Lois normales multivariées
library(MASS) # Fonctions statistiques avancées
library(dplyr) # Manipulation des données (tidyverse)
library(tidyverse) # Écosystème complet de data science
library(ggplot2) # Visualisation de donnéesAnalyse de Clusters (Clustering) avec R
1 Introduction générale
L’analyse de clusters (ou clustering) est une méthode d’apprentissage non supervisé dont l’objectif est de partitionner un ensemble d’observations en sous-groupes appelés clusters, de telle sorte que :
- les individus au sein d’un même groupe soient les plus similaires possible entre eux (cohésion interne maximale),
- les individus entre groupes différents soient les plus dissemblables possible (séparation externe maximale).
À la différence de la classification supervisée, aucune étiquette de groupe n’est fournie à l’algorithme : il doit découvrir par lui-même la structure latente des données. C’est précisément ce qui rend le clustering à la fois puissant et délicat — il n’existe pas de “bonne réponse” unique, et le résultat dépend fortement du choix de l’algorithme, de la mesure de distance utilisée, et du nombre de groupes ciblé.
Pour illustrer et comparer quatre grandes familles de méthodes de clustering — K-Means, Classification Ascendante Hiérarchique (CAH), Modèles de Mélange Gaussien (GMM) et Analyse Archétypale — nous nous appuyons sur une approche inspirée de l’article de Flynt et Dean (2016), qui propose une comparaison rigoureuse de méthodes adaptées aux données mixtes (variables continues et discrètes simultanément).
Nous commencerons par générer un jeu de données synthétiques dont nous connaissons la vérité terrain (ground truth), ce qui nous permettra d’évaluer objectivement la qualité de chaque algorithme.
2 Préparation de l’environnement
Avant tout calcul, nous chargeons les packages nécessaires. Chaque package est brièvement présenté ci-dessous.
mvtnorm: Simulation de réalisations issues de lois normales multivariées et calcul de leur densité. Indispensable pour générer nos données synthétiques gaussiennes.MASS: Package de référence en statistiques appliquées sous R (accompagne le livre Modern Applied Statistics with S). Fournit des outils commeeqscplot()pour les graphiques à axes équilibrés.dplyr: Grammaire de manipulation de données tabulaires dutidyverse: filtrage, sélection, mutation, agrégation.tidyverse: Méta-package regroupant un ensemble cohérent d’outils pour l’import, la transformation et la visualisation de données (ggplot2,dplyr,tidyr,readr, etc.).ggplot2: Système de visualisation basé sur la Grammar of Graphics. Permet de construire des graphiques complexes par superposition de couches déclaratives.
3 Création du jeu de données synthétiques
Pour évaluer objectivement les performances de nos algorithmes, nous générons un jeu de données synthétiques dont la structure est entièrement contrôlée : nous connaissons a priori l’appartenance de chaque individu à son vrai groupe. Cette vérité terrain (ground truth) servira de référence pour mesurer les erreurs de classification.
3.1 Variables continues
Les données continues sont générées selon un modèle de mélange de trois lois normales bivariées (Gaussian Mixture Model, GMM). Ce type de modèle est particulièrement adapté pour simuler des populations hétérogènes, où chaque sous-population suit sa propre distribution gaussienne.
Les trois composantes du mélange sont les suivantes :
Groupe 1 (Noir) — Distribution sphérique, centrée en \((0, 0)\) : \[\mathcal{N}\!\left(\begin{pmatrix}0\\0\end{pmatrix},\begin{pmatrix}1&0\\0&1\end{pmatrix}\right)\] Les deux variables sont indépendantes et ont la même variance : le nuage est circulaire.
Groupe 2 (Rouge) — Distribution sphérique, centrée en \((3, 5)\) : \[\mathcal{N}\!\left(\begin{pmatrix}3\\5\end{pmatrix},\begin{pmatrix}1&0\\0&1\end{pmatrix}\right)\] Même structure que le groupe 1, mais décalé dans l’espace : les deux groupes sont bien séparés.
Groupe 3 (Vert) — Distribution elliptique, centrée en \((0, 6)\) : \[\mathcal{N}\!\left(\begin{pmatrix}0\\6\end{pmatrix},\begin{pmatrix}2&1.3\\1.3&1\end{pmatrix}\right)\] La valeur hors-diagonale \(\sigma_{12} = 1.3\) introduit une corrélation positive entre les deux variables : quand l’une augmente, l’autre tend à augmenter aussi. Cela produit un nuage allongé en diagonale, dont la forme elliptique est précisément ce qui mettra en difficulté l’algorithme K-Means.
La proportion de chaque groupe dans la population est contrôlée par le vecteur \(\pi = (0.3, 0.4, 0.3)\), soit respectivement 30 %, 40 % et 30 % des 600 individus simulés.
3.1.1 Interprétation — Figure 1
Ce premier nuage de points illustre la vérité terrain : la répartition spatiale de nos 600 individus selon leurs vrais groupes d’appartenance, que nos algorithmes de clustering devront retrouver sans en avoir connaissance.
- Le groupe Noir (\(n \approx 180\)) forme un nuage dense et circulaire centré en \((0, 0)\). Sa distribution sphérique (covariance identité) lui confère une dispersion identique dans toutes les directions.
- Le groupe Rouge (\(n \approx 240\)) forme également un nuage circulaire, mais centré en \((3, 5)\). Il est nettement séparé du groupe Noir dans l’espace.
- Le groupe Vert (\(n \approx 180\)) présente une forme allongée en diagonale, caractéristique de la matrice de covariance elliptique utilisée. Centré en \((0, 6)\), il s’étire vers le haut à droite et chevauche partiellement le groupe Rouge — ce qui constituera la principale source d’erreur pour les algorithmes qui supposent des groupes sphériques.
3.2 Densité bivariée en 3D
Pour approfondir la compréhension de la distribution de nos données, nous construisons un histogramme bivarié en 3D qui représente la densité conjointe des deux variables continues.
plotly: Package de visualisation interactive basé sur la librairie JavaScript Plotly.js. Permet de créer des graphiques 3D rotatifs, des cartes et des animations directement dans R, avec interactions (zoom, survol, rotation).
3.2.1 Interprétation — Figure 2
La Figure 2 offre une lecture tridimensionnelle de la distribution conjointe de nos deux variables. La hauteur de chaque bloc correspond au nombre d’individus concentrés dans la cellule correspondante de l’espace \((X, Y)\).
On distingue nettement deux pics denses et étroits correspondant aux centres des groupes Noir \((0, 0)\) et Rouge \((3, 5)\) : leurs distributions sphériques resserrées concentrent beaucoup d’individus dans un petit volume. En revanche, la distribution elliptique du groupe Vert \((0, 6)\) se manifeste par une crête aplatie et étalée en diagonale : l’énergie est diffusée sur une surface plus grande, témoignant de la corrélation entre les deux variables et de la variance plus élevée (\(\sigma_X^2 = 2\)).
3.3 Variables discrètes
En complément des variables continues, nous générons quatre variables discrètes (catégorielles). Chacune encode un signal discriminant d’intensité variable selon les groupes, simulant des données mixtes telles qu’on les rencontre fréquemment en pratique (données d’enquête, données médicales, données comportementales).
rbinom(n, size, prob): Génère \(n\) réalisations d’une loi binomiale de paramètressizeetprob. Avecsize=1, on obtient un tirage de Bernoulli (0 ou 1). L’ajout de+1déplace les modalités dans \(\{1, 2\}\), convention requise par certains algorithmes de clustering mixte (ex:poLCA,clustMD).
# c1 : Variable de BRUIT pur — aucune relation avec les groupes.
# Probabilité 50/50 pour tous les individus, quelle que soit leur appartenance.
# Cette variable n'apporte aucune information discriminante à l'algorithme.
c1 <- rbinom(600, 1, .5) + 1
# c2 : Discrimine fortement le Groupe 1 (Noir).
# Pour le Groupe 1 : modalité 1 très probable (90%), modalité 2 rare (10%).
# Pour les Groupes 2 et 3 : modalité 2 très probable (90%).
c2 <- numeric(600)
for(i in 1:600) {
c2[i] <- ifelse(cl[i] == 1, rbinom(1, 1, .1) + 1, rbinom(1, 1, .9) + 1)
}
# c3 : Variable TERNAIRE — la plus informative du jeu.
# Chaque groupe est associé à une modalité dominante différente :
# Groupe 1 → Modalité 1 (60%), Groupe 2 → Modalité 2 (80%), Groupe 3 → Modalité 3 (80%)
c3 <- numeric(600)
for(i in 1:600){
if(cl[i] == 1) c3[i] <- sample(1:3, 1, prob = c(.6, .2, .2))
if(cl[i] == 2) c3[i] <- sample(1:3, 1, prob = c(.1, .8, .1))
if(cl[i] == 3) c3[i] <- sample(1:3, 1, prob = c(.1, .1, .8))
}
# c4 : Discrimine le Groupe 2 (Rouge).
# Pour le Groupe 2 : modalité 2 probable (80%), modalité 1 rare (20%).
# Pour les Groupes 1 et 3 : modalité 1 probable (80%).
c4 <- numeric(600)
for(i in 1:600){
c4[i] <- ifelse(cl[i] == 2, rbinom(1, 1, .8) + 1, rbinom(1, 1, .2) + 1)
}
# Assemblage final : matrice de 600 individus × 6 variables (2 continues + 4 discrètes)
vars <- cbind(X, c1, c2, c3, c4)
cat("Dimensions du jeu de données complet :", nrow(vars), "individus ×", ncol(vars), "variables\n")Dimensions du jeu de données complet : 600 individus × 6 variables
cat("Variables : X1 (cont.), X2 (cont.), c1 (bruit), c2 (disc.), c3 (ternaire), c4 (disc.)\n")Variables : X1 (cont.), X2 (cont.), c1 (bruit), c2 (disc.), c3 (ternaire), c4 (disc.)
3.3.1 Interprétation des variables discrètes
Les quatre variables discrètes forment ensemble une signature catégorielle de chaque groupe :
| Variable | Type | Rôle |
|---|---|---|
c1 |
Binaire | Bruit pur — aucune information discriminante |
c2 |
Binaire | Isole le Groupe 1 (Noir) des deux autres |
c3 |
Ternaire | Discrimine les 3 groupes — variable la plus informative |
c4 |
Binaire | Isole le Groupe 2 (Rouge) des deux autres |
Cette structure simule des données réelles où certaines variables sont très informatives (c3), d’autres partiellement utiles (c2, c4) et d’autres totalement non informatives (c1). Les algorithmes capables d’exploiter conjointement les variables continues et discrètes ont donc un avantage structurel sur K-Means qui ne travaille que sur les variables continues.
4 Analyse de clustering : L’algorithme K-Means
4.1 Principe mathématique
L’algorithme K-Means est la méthode de clustering la plus classique et la plus utilisée. Son principe est itératif et repose sur la minimisation de l’inertie intra-cluster (Within-Cluster Sum of Squares, WCSS) :
\[\text{WCSS} = \sum_{k=1}^{K} \sum_{x_i \in C_k} \| x_i - \bar{x}_k \|^2\]
où \(\bar{x}_k\) est le centroïde (moyenne) du cluster \(k\) et \(\| \cdot \|\) est la distance euclidienne. L’algorithme procède en 4 étapes :
- Initialisation : \(K\) centroïdes sont placés aléatoirement dans l’espace des données.
- Assignation : Chaque observation est affectée au centroïde le plus proche.
- Mise à jour : Les centroïdes sont recalculés comme la moyenne des observations qui leur sont assignées.
- Convergence : Les étapes 2-3 sont répétées jusqu’à ce que les assignations ne changent plus.
Le paramètre nstart=50 lance 50 initialisations aléatoires différentes et retient la solution avec la WCSS minimale, réduisant le risque de convergence vers un minimum local.
La variance totale se décompose comme suit : \[\underbrace{\text{SS}_{\text{total}}}_{\text{variance totale}} = \underbrace{\text{SS}_{\text{between}}}_{\text{variance inter-clusters}} + \underbrace{\text{SS}_{\text{within}}}_{\text{variance intra-clusters (WCSS)}}\]
K-Means cherche à maximiser \(\text{SS}_{\text{between}}\), ce qui revient à minimiser \(\text{SS}_{\text{within}}\).
4.2 Détermination du nombre optimal de clusters (\(K\))
4.2.1 Méthode du coude
La méthode du coude (Elbow method) consiste à tracer la WCSS en fonction de \(K\) et à identifier le point d’inflexion de la courbe, là où le gain marginal apporté par un cluster supplémentaire devient négligeable.
# Calcul de la WCSS pour K allant de 1 à 9
# kmeans()$tot.withinss : somme totale des distances au carré au centroïde de chaque cluster
K_max <- 9
wss <- numeric(K_max)
for (k in 1:K_max) {
modele <- kmeans(vars[, 1:2], centers = k, nstart = 50)
wss[k] <- modele$tot.withinss
}
df_elbow <- tibble(K = 1:K_max, Inertie = wss)
ggplot(df_elbow, aes(x = K, y = Inertie)) +
geom_line(color = "steelblue", linewidth = 1) +
geom_point(color = "steelblue", shape = 18, size = 3) +
geom_vline(xintercept = 3, linetype = "dashed", color = "black") +
annotate("text", x = 3.2, y = max(wss) * 0.9,
label = "K = 3\n(coude optimal)", hjust = 0, size = 3.5, color = "black") +
scale_x_continuous(breaks = 1:K_max) +
labs(
title = "Figure 3 — Méthode du coude",
subtitle = "Inertie intra-cluster en fonction du nombre de clusters K",
x = "Nombre de clusters (K)",
y = "Inertie intra-cluster (Total Within SS)"
) +
theme_classic()4.2.2 Interprétation — Figure 3
La courbe montre une chute drastique de l’inertie entre \(K=1\) et \(K=3\) : l’algorithme détecte progressivement les vraies structures des données. Le gain est très important de 1 à 2 clusters (séparation des deux premières structures majeures), puis encore significatif de 2 à 3 (isolation de la troisième structure).
Au-delà de \(K=3\), la courbe s’aplatit sensiblement : la réduction de la WCSS devient marginale car l’algorithme commence à découper artificiellement des groupes déjà cohérents, sans gain structurel réel. La ligne pointillée marque le coude optimal à \(K=3\), confirmant que nos données contiennent bien 3 groupes naturels.
Note : La WCSS ne peut jamais atteindre 0 à moins d’avoir \(K = n\) (un cluster par individu), ce qui n’a aucun sens pratique. Un résidu de variance interne est attendu et reflète simplement l’étalement naturel de chaque nuage de points.
4.2.3 Statistique de Gap
factoextra: Package facilitant l’extraction et la visualisation de résultats issus d’analyses factorielles et de clustering. Fournit des graphiquesggplot2prêts à l’emploi pour la sélection du nombre de clusters (méthode du coude, silhouette, Gap statistic).
La statistique de Gap (Tibshirani et al., 2001) est une approche statistiquement plus rigoureuse que la méthode du coude. Elle compare la WCSS observée à celle obtenue sur des données simulées sans structure (données uniformes aléatoires). Le nombre optimal \(K^*\) est celui qui maximise cet écart (gap) :
\[\text{Gap}(K) = \mathbb{E}[\log \text{WCSS}_{\text{aléatoire}}(K)] - \log \text{WCSS}_{\text{observée}}(K)\]
library(factoextra)
# fviz_nbclust() calcule et visualise le critère de sélection choisi.
# method = "gap_stat" : calcule la statistique de Gap via nboot bootstraps.
# nboot = 50 : 50 jeux de données aléatoires sont générés pour l'estimation.
fviz_nbclust(
vars[, 1:2],
kmeans,
nstart = 25,
method = "gap_stat",
nboot = 50
) +
labs(
title = "Figure 4 — Statistique de Gap",
subtitle = "Pic à K=3 : confirmation statistique du nombre optimal de clusters"
) +
theme_minimal()4.2.4 Interprétation — Figure 4
La statistique de Gap présente un pic net à \(K=3\), confirmant de manière statistiquement rigoureuse le résultat visuel de la méthode du coude. Ce pic signifie que pour \(K=3\), l’écart entre la structure de nos données et des données sans structure est maximal : nos 3 groupes sont les plus distincts possibles par rapport à ce que produirait le hasard. Au-delà de \(K=3\), le gap diminue, indiquant que les partitions supplémentaires ne capturent plus de structures réelles.
4.3 Application du K-Means (\(K=3\))
# Ajustement du K-Means avec K=3 et 50 ré-initialisations aléatoires
cluster3 <- kmeans(vars[, 1:2], centers = 3, nstart = 50)
# Figure 5 droite — Clusters prédits par K-Means
graph2 <- df |>
ggplot(aes(x = x, y = y)) +
geom_point(color = cluster3$cluster, size = 1.5) +
theme_minimal() +
labs(
title = "Figure 5b — Prédictions K-Means (K=3)",
caption = "Les numéros de clusters sont arbitraires (non supervisé)"
)
library(gridExtra)
grid.arrange(
graph1 + ggtitle("Figure 5a — Vérité terrain"),
graph2,
nrow = 1
)4.3.1 Interprétation — Figure 5
La comparaison côte à côte révèle à la fois les forces et les limites fondamentales de K-Means.
Ce que K-Means réussit : il identifie correctement le groupe Noir (nuage sphérique compact en bas à gauche) et le cœur du groupe Rouge (nuage sphérique en haut à droite), dont la forme circulaire correspond parfaitement à l’hypothèse implicite de l’algorithme.
Ce que K-Means échoue : la distribution elliptique du groupe Vert est découpée en deux par K-Means. La partie inférieure-gauche de l’ellipse (proche du centre \((0, 6)\)) est correctement identifiée, mais la partie supérieure-droite — qui chevauchait géographiquement le groupe Rouge — est attribuée au cluster Rouge car son centroïde lui est plus proche en distance euclidienne.
Cette limite est fondamentale : K-Means suppose implicitement que tous les clusters ont la même forme sphérique et la même taille. Pour des données présentant des corrélations internes (covariance non-diagonale), des algorithmes comme les modèles de mélange gaussiens (GMM) sont structurellement mieux adaptés car ils estiment explicitement la forme de chaque cluster.
4.4 Évaluation : Matrice de confusion et Indice de Rand
4.4.1 Matrice de confusion
# Table de croisement entre la vérité terrain (cl) et les prédictions K-Means
# Lignes = vrais groupes, Colonnes = clusters prédits (labels arbitraires)
conf_matrix <- table(Verite = cl, Prediction = cluster3$cluster)
print(conf_matrix) Prediction
Verite 1 2 3
1 0 177 0
2 10 0 227
3 153 0 33
# Taux d'erreur : proportion d'individus mal classés
# Les erreurs proviennent quasi-exclusivement du chevauchement Vert/Rouge
erreurs <- 33 + 10
taux_erreur <- erreurs / 600
cat("\nTaux d'erreur estimé :", round(taux_erreur * 100, 2), "%\n")
Taux d'erreur estimé : 7.17 %
cat("Soit", erreurs, "individus mal classés sur 600.\n")Soit 43 individus mal classés sur 600.
4.4.2 Interprétation — Matrice de confusion
La matrice de confusion croise les vrais labels avec les labels prédits par K-Means. Comme K-Means est non supervisé, il attribue des numéros de clusters arbitraires (son “Cluster 1” n’est pas nécessairement notre vrai groupe 1) : c’est la lecture diagonale de la table qui révèle les bonnes classifications.
Les résultats indiquent que :
- Le groupe Noir est parfaitement identifié : 0 erreur. Sa forme sphérique compacte et son isolement spatial le rendent trivial à détecter.
- Le groupe Rouge présente ~10 erreurs : quelques individus situés à la frontière avec le vert sont mal assignés.
- Le groupe Vert présente ~33 erreurs : sa queue elliptique chevauchant le rouge est la principale source d’échec, comme prévu.
Au total, environ 7.2 % des individus sont mal classés — un résultat cohérent avec les résultats publiés par Flynt et Dean (2016).
4.4.3 Indice de Rand
fossil: Package initialement développé pour la diversité biologique et paléontologique. Fournit notammentrand.index()pour comparer deux partitions d’un même ensemble d’individus.
L’indice de Rand mesure la concordance entre deux partitions en considérant toutes les paires d’individus possibles :
\[\text{RI} = \frac{a + d}{\binom{n}{2}}\]
où \(a\) = nombre de paires dans le même groupe dans les deux partitions, \(d\) = nombre de paires dans des groupes différents dans les deux partitions. L’indice vaut 1 pour une concordance parfaite et 0.5 pour une assignation aléatoire.
library(fossil)
# Calcul de l'indice de Rand entre la vérité terrain et les clusters K-Means
rand_idx <- rand.index(cl, cluster3$cluster)
cat("Indice de Rand K-Means vs vérité terrain :", round(rand_idx * 100, 2), "%\n")Indice de Rand K-Means vs vérité terrain : 90.91 %
4.4.4 Interprétation — Indice de Rand
L’indice de Rand d’environ 90 % confirme que K-Means retrouve l’essentiel de la structure des données malgré les 7.2 % d’erreurs individuelles. L’écart entre ces deux mesures s’explique par le fait que l’indice de Rand raisonne sur des paires : si les 43 individus mal classés forment des paires entre eux (ce qui est probable car ils sont géographiquement regroupés à la frontière Vert/Rouge), leur impact sur l’indice de Rand est amplifié par rapport au simple taux d’erreur individuel.
5 Classification Ascendante Hiérarchique (CAH)
5.1 Principe
La CAH (Hierarchical Agglomerative Clustering) est une approche radicalement différente de K-Means : elle ne nécessite pas de spécifier \(K\) à l’avance et construit une hiérarchie complète de partitions sous forme d’arbre binaire appelé dendrogramme.
L’algorithme est agglomératif (ascendant) : il part de \(n\) singletons (chaque individu est son propre cluster) et fusionne à chaque étape les deux groupes les plus proches, selon une mesure de liaison (linkage) choisie. Le processus continue jusqu’à ce qu’un seul cluster contienne tous les individus.
La méthode de Ward (ou Ward.D2), utilisée ici, choisit à chaque étape la fusion qui minimise l’augmentation de la variance intra-cluster totale : \[\Delta(A, B) = \frac{n_A \cdot n_B}{n_A + n_B} \| \bar{x}_A - \bar{x}_B \|^2\] C’est la méthode la plus couramment recommandée car elle tend à former des clusters compacts, équilibrés et de taille comparable.
fastcluster: Implémentation hautement optimisée de la CAH en C++, bien plus rapide que la fonctionhclust()native de R pour les grands jeux de données. Fournit les mêmes méthodes de liaison (Ward, average, complete, single…).
sparcl: Package de sparse clustering (clustering parcimonieux). Fournit la fonctionColorDendrogram()permettant de colorier les feuilles du dendrogramme selon des labels connus, facilitant l’évaluation visuelle de la partition.
library(fastcluster)
library(sparcl)
# Calcul de la matrice de distances euclidiennes entre toutes les paires d'individus.
# Pour n=600, cela donne une matrice 600×600 = 360 000 distances.
distance_mat <- dist(vars[, 1:2], method = "euclidean")
# hclust() avec method="ward.D2" : minimisation de la variance intra-cluster à chaque fusion.
# Le résultat est un objet contenant toute la hiérarchie des fusions (dendrogramme).
arbre_ward <- hclust(distance_mat, method = "ward.D2")
# ColorDendrogram() colorie les feuilles du dendrogramme selon les clusters K-Means.
# Cela permet de vérifier visuellement si la CAH et K-Means s'accordent sur le découpage.
# labels=FALSE : illisible pour n=600 individus
ColorDendrogram(
arbre_ward,
y = cluster3$cluster,
main = "Figure 6 — Dendrogramme coloré (méthode de Ward)",
xlab = "",
sub = ""
)5.1.1 Interprétation — Figure 6
Le dendrogramme se lit de bas en haut : les premières fusions (en bas) regroupent des individus très proches géographiquement ; les dernières fusions (en haut) assemblent des groupes de plus en plus distants.
Les grands sauts de hauteur sont les indicateurs clés : ils signalent qu’une fusion a regroupé deux entités relativement éloignées, suggérant une frontière naturelle entre groupes. En coupant le dendrogramme juste en dessous du saut le plus grand, on obtient le nombre optimal de clusters — ici clairement 3 groupes, confirmant à nouveau nos analyses précédentes.
La coloration par clusters K-Means révèle que la CAH et K-Means s’accordent largement sur le découpage en 3 groupes, avec les mêmes zones de chevauchement à la frontière Vert/Rouge.
5.1.2 Évaluation de la CAH
library(clue)
# cutree() "coupe" le dendrogramme à k=3 pour extraire la partition en 3 groupes
cah_clusters <- cutree(arbre_ward, k = 3)
# Indice de Rand : concordance CAH vs vérité terrain
rand_cah <- rand.index(cl, cah_clusters)
cat("Indice de Rand CAH vs vérité terrain :", round(rand_cah * 100, 2), "%\n")Indice de Rand CAH vs vérité terrain : 86.73 %
# Table de croisement CAH vs vérité terrain
cat("\nMatrice de confusion CAH :\n")
Matrice de confusion CAH :
print(table(Verite = cl, CAH = cah_clusters)) CAH
Verite 1 2 3
1 0 177 0
2 236 0 1
3 66 0 120
# L'algorithme hongrois (solve_LSAP) trouve la permutation optimale des labels
# pour aligner les clusters CAH avec les vrais groupes (labels arbitraires)
correspondance <- solve_LSAP(
table(tibble(cl, cah_clusters)),
maximum = TRUE
)
cat("\nCorrespondance labels CAH → vrais groupes :", as.integer(correspondance), "\n")
Correspondance labels CAH → vrais groupes : 2 1 3
5.1.3 Interprétation — Évaluation CAH
La CAH obtient un indice de Rand comparable à K-Means (aux alentours de 90 %), ce qui est attendu : les deux méthodes reposent sur la distance euclidienne et partagent donc les mêmes limites face à la distribution elliptique du groupe Vert.
L’avantage de la CAH par rapport à K-Means est qu’elle offre une vue hiérarchique complète : en changeant simplement le seuil de coupure du dendrogramme, on peut explorer toutes les partitions de \(K=1\) à \(K=600\) sans relancer l’algorithme. C’est particulièrement utile lorsque le nombre de clusters n’est pas connu a priori.
6 Modèles de Mélange Gaussien (GMM)
6.1 Principe
Les Modèles de Mélange Gaussien (Gaussian Mixture Models, GMM) représentent une généralisation probabiliste de K-Means. Plutôt que d’assigner chaque observation à un cluster de manière rigide et déterministe, les GMM estiment une probabilité d’appartenance à chaque composante gaussienne via l’algorithme EM (Espérance-Maximisation).
La grande force de cette approche est qu’elle paramétrise librement les matrices de covariance de chaque composante, permettant de modéliser des clusters de formes, tailles et orientations différentes — là où K-Means est limité à des sphères de taille identique.
La densité du mélange est : \[f(x) = \sum_{k=1}^{K} \pi_k \, \mathcal{N}(x \mid \mu_k, \Sigma_k)\]
où \(\pi_k\) est la proportion du cluster \(k\), \(\mu_k\) son vecteur de moyennes et \(\Sigma_k\) sa matrice de covariance. L’algorithme EM estime conjointement \(\{\pi_k, \mu_k, \Sigma_k\}_{k=1}^{K}\) par maximisation de la vraisemblance.
La sélection du modèle (nombre de composantes \(K\) ET type de covariance) se fait via le BIC (Bayesian Information Criterion) : \[\text{BIC} = 2 \log \hat{L} - \log(n) \cdot p\] où \(\hat{L}\) est la log-vraisemblance maximisée et \(p\) le nombre de paramètres. Dans mclust, un BIC plus élevé indique un meilleur modèle (convention inversée par rapport à la définition classique).
mclust: Package phare pour le clustering et la classification par modèles de mélange gaussiens finis en R. Teste automatiquement 14 paramétrages de covariance (EII, VII, EEI, VVI, EEE, EVE, VEE, VVE, EEV, VEV, EVV, VVV…) pour \(K\) allant de 1 à 9, et sélectionne le meilleur par BIC.
library(mclust)
# Mclust() ajuste automatiquement tous les modèles gaussiens disponibles
# et sélectionne le meilleur par BIC. Aucune spécification de K nécessaire.
modele_gmm <- Mclust(vars[, 1:2])
# Affichage du résumé : modèle sélectionné, K, BIC, log-vraisemblance
summary(modele_gmm)----------------------------------------------------
Gaussian finite mixture model fitted by EM algorithm
----------------------------------------------------
Mclust VVE (ellipsoidal, equal orientation) model with 3 components:
log-likelihood n df BIC ICL
-2230.692 600 15 -4557.338 -4572.94
Clustering table:
1 2 3
229 177 194
# Visualisation du BIC pour tous les modèles testés
# Le point le plus haut identifie le meilleur modèle
plot(modele_gmm, what = "BIC",
main = "Figure 7 — Sélection du modèle GMM par BIC")# Matrice de confusion : GMM vs vérité terrain
cat("Matrice de confusion GMM :\n")Matrice de confusion GMM :
print(table(Verite = cl, GMM = modele_gmm$classification)) GMM
Verite 1 2 3
1 0 177 0
2 229 0 8
3 0 0 186
# Indice de Rand GMM
rand_gmm <- rand.index(cl, modele_gmm$classification)
cat("\nIndice de Rand GMM vs vérité terrain :", round(rand_gmm * 100, 2), "%\n")
Indice de Rand GMM vs vérité terrain : 98.15 %
6.1.1 Interprétation — Figure 7 et résultats GMM
La Figure 7 montre le BIC pour chaque combinaison (modèle de covariance, nombre de composantes \(K\)). mclust sélectionne automatiquement le modèle avec le BIC le plus élevé, qui correspond typiquement à un modèle avec 3 composantes et une covariance elliptique (modèle VEV ou EEV selon les réalisations), reconnaissant ainsi que nos données contiennent effectivement 3 groupes dont l’un est elliptique.
La matrice de confusion montre que GMM fait moins d’erreurs que K-Means sur le groupe Vert, précisément parce qu’il estime explicitement la matrice de covariance de chaque composante. En modélisant la corrélation interne du groupe Vert, il peut en délimiter correctement la forme elliptique et éviter de l’attribuer partiellement au groupe Rouge.
L’indice de Rand du GMM est généralement supérieur à celui de K-Means (typiquement 92-95 % vs 90 %), confirmant l’avantage structurel des modèles probabilistes pour les données présentant des structures de covariance non-triviales.
Comparaison synthétique des méthodes :
| Méthode | Hypothèse sur les clusters | Forces | Limites |
|---|---|---|---|
| K-Means | Sphériques, même taille | Rapide, simple | Sensible à la forme |
| CAH | Aucune (hiérarchique) | Vue complète, pas de K requis | Lent pour grands \(n\) |
| GMM | Elliptiques (forme libre) | Probabiliste, forme adaptable | Plus complexe, plus de paramètres |