Formation ML / Apprentissage non supervisé

Clustering hiérarchique

Débutant 35 min 13 sections

Les points fusionnent deux à deux jusqu'au dernier ; la hauteur de coupe fixe le nombre de groupes.

Objectifs d'apprentissage

  • Comprendre la différence entre approches agglomérative et divisive
  • Interpréter un dendrogramme
  • Choisir le nombre de clusters avec le dendrogramme
  • Implémenter le clustering hiérarchique avec scikit-learn

Prérequis

Module K-Means Clustering recommandé

Le code de cette page s'exécute dans votre navigateur. Le premier lancement télécharge Python et ses bibliothèques.

Théorie

Qu'est-ce que le clustering hiérarchique?

Le clustering hiérarchique créé une hiérarchie de clusters, représentée par un arbre appelé dendrogramme.

Deux approches:

  • Agglomérative (bottom-up): Chaque point est un cluster, on fusionne iterativement
  • Divisive (top-down): Tous les points forment un cluster, on divise iterativement

L'approche agglomérative est la plus courante.

Algorithme agglomératif:

  1. Chaque point = 1 cluster
  2. Trouver les 2 clusters les plus proches
  3. Les fusionner en 1 cluster
  4. Répéter jusqu'à n'avoir qu'un seul cluster

Avantages:

  • Pas besoin de spécifier k à l'avance
  • Dendrogramme visualise la structure à tous les niveaux
  • Pas d'initialisation aléatoire (déterministe)

Inconvénients:

  • Complexité O(n^3) en mémoire et temps
  • Pas adapte aux très grands datasets (>10K points)
  • Une fusion ne peut pas être défaite
Théorie

Schéma: Construction du dendrogramme

Algorithme agglomératif étape par étape:

flowchart TD subgraph E1 ["Étape 1"] A1["A"] B1["B"] C1["C"] D1["D"] E1T["E"] end subgraph E2 ["Étape 2: Fusion A+B"] AB["A-B"] C2["C"] D2["D"] E2T["E"] end subgraph E3 ["Étape 3: Fusion D+E"] AB2["A-B"] C3["C"] DE["D-E"] end subgraph E4 ["Étape 4: Fusion AB+C"] ABC["A-B-C"] DE2["D-E"] end subgraph E5 ["Étape 5: Fusion finale"] ALL["A-B-C-D-E"] end E1 --> E2 --> E3 --> E4 --> E5 class ALL ml-node-accent

Le dendrogramme:

flowchart TD ROOT["Racine
(tous les points)"] L["Cluster Gauche"] R["Cluster Droit"] LL["A"] LR["B"] RL["C"] RR["D"] ROOT --> L ROOT --> R L --> LL L --> LR R --> RL R --> RR class ROOT ml-node-main

Couper le dendrogramme à une certaine hauteur donne un nombre spécifique de clusters.

Exemple concret avec code couleur - Fusion de clusters:

Clusters actuels:

  • $\textcolor{#3498db}{Cluster\ A}$: points {$\textcolor{#3498db}{P_1, P_2}$} avec centre $(\textcolor{#3498db}{1.0}, \textcolor{#3498db}{2.0})$
  • $\textcolor{#e67e22}{Cluster\ B}$: points {$\textcolor{#e67e22}{P_3}$} avec centre $(\textcolor{#e67e22}{1.5}, \textcolor{#e67e22}{2.5})$
  • $\textcolor{#9B7AC4}{Cluster\ C}$: points {$\textcolor{#9B7AC4}{P_4, P_5}$} avec centre $(\textcolor{#9B7AC4}{8.0}, \textcolor{#9B7AC4}{7.0})$

Étape 1 - Calculer les distances entre clusters (linkage: average):

$d(\textcolor{#3498db}{A}, \textcolor{#e67e22}{B}) = \sqrt{(\textcolor{#3498db}{1.0} - \textcolor{#e67e22}{1.5})^2 + (\textcolor{#3498db}{2.0} - \textcolor{#e67e22}{2.5})^2} = \textcolor{#27ae60}{\mathbf{0.71}}$

$d(\textcolor{#3498db}{A}, \textcolor{#9B7AC4}{C}) = \sqrt{(\textcolor{#3498db}{1.0} - \textcolor{#9B7AC4}{8.0})^2 + (\textcolor{#3498db}{2.0} - \textcolor{#9B7AC4}{7.0})^2} = \textcolor{#e74c3c}{\mathbf{8.60}}$

$d(\textcolor{#e67e22}{B}, \textcolor{#9B7AC4}{C}) = \sqrt{(\textcolor{#e67e22}{1.5} - \textcolor{#9B7AC4}{8.0})^2 + (\textcolor{#e67e22}{2.5} - \textcolor{#9B7AC4}{7.0})^2} = \textcolor{#e74c3c}{\mathbf{7.91}}$

Étape 2 - Fusionner les plus proches:

Distance minimale: $d(\textcolor{#3498db}{A}, \textcolor{#e67e22}{B}) = \textcolor{#27ae60}{0.71}$

Résultat: Fusionner $\textcolor{#3498db}{A}$ et $\textcolor{#e67e22}{B}$ → Nouveau $\textcolor{#27ae60}{\mathbf{Cluster\ AB}}$

Légende des couleurs:

  • $\textcolor{#3498db}{Bleu}$: Cluster A et ses coordonnées
  • $\textcolor{#e67e22}{Orange}$: Cluster B et ses coordonnées
  • $\textcolor{#9B7AC4}{Violet}$: Cluster C (éloigné)
  • $\textcolor{#27ae60}{Vert}$: Distance minimale / clusters fusionnes
  • $\textcolor{#e74c3c}{Rouge}$: Distances trop grandes
Avancé Exercice manuel: À vous de calculer!

Objectif: Construire un dendrogramme à la main (clustering hiérarchique agglomératif).

CONTEXTE

4 points en 1D : A=1, B=2, C=6, D=7

Méthode : Agglomérative (bottom-up) avec linkage single (distance min entre clusters)

PARTIE 1 : Matrice des distances initiale

1.1) Calculez la distance entre chaque paire de points 1.2) Quels sont les 2 points les plus proches ?

PARTIE 2 : Première fusion

2.1) Fusionnez les 2 points les plus proches en un cluster 2.2) Calculez les distances du nouveau cluster aux autres points

PARTIE 3 : Suite des fusions

3.1) Quelle est la prochaine fusion ? 3.2) Continuez jusqu'à n'avoir qu'un seul cluster 3.3) À quelle hauteur coupe-t-on pour avoir 2 clusters ?

Avancé Solution de l'exercice manuel

SOLUTION DÉTAILLÉE

PARTIE 1 : Matrice des distances initiale

1.1) Distances :

ABCD
A0156
B1045
C5401
D6510

1.2) Plus proches : $\textcolor{#3498db}{(A,B)}$ et $\textcolor{#e67e22}{(C,D)}$ avec distance = 1

PARTIE 2 : Première fusion

2.1) Fusion : {A,B} → hauteur = $\textcolor{#F7E64D}{1}$

2.2) Distances (single linkage = min) :

  • d({A,B}, C) = min(d(A,C), d(B,C)) = min(5,4) = 4
  • d({A,B}, D) = min(d(A,D), d(B,D)) = min(6,5) = 5
{A,B}CD
{A,B}045
C401
D510

PARTIE 3 : Suite des fusions

3.1) Prochaine fusion : {C,D} (distance = 1) → hauteur = $\textcolor{#F7E64D}{1}$

3.2) Distances :

{A,B}{C,D}
{A,B}04
{C,D}40

Fusion finale : {{A,B}, {C,D}} → hauteur = $\textcolor{#e74c3c}{4}$

Dendrogramme :

Hauteur
   4  ─────────┬─────────
               │
   1  ───┬───  │  ───┬───
         │     │     │
   0     A  B  │  C  D

3.3) Pour 2 clusters :

$\boxed{\text{Couper entre hauteur 1 et 4}}$

→ Clusters : {A,B} et {C,D}

Légende : $\textcolor{#3498db}{Bleu}$: cluster 1, $\textcolor{#e67e22}{Orange}$: cluster 2, $\textcolor{#F7E64D}{Jaune}$: fusions

Code

Explorer les données

print("=" * 70)
print("       EXPLORATION DES DONNEES POUR CLUSTERING HIERARCHIQUE")
print("=" * 70)

print("""
Le clustering hierarchique cree un ARBRE de clusters (dendrogramme).
Contrairement a K-Means, on n'a pas besoin de specifier k a l'avance!

Le dendrogramme nous montre la structure COMPLETE des donnees:
- En bas: chaque point est son propre cluster
- En haut: tous les points forment un seul cluster
- La hauteur indique la "dissimilarite" entre clusters fusionnes
""")

print("\n" + "=" * 70)
print("1. APERCU DU DATASET")
print("=" * 70)
display(df.head(10), title="Premieres lignes du dataset")

print("""
Ce dataset contient des points 2D qui forment naturellement des groupes.
Notre objectif: decouvrir cette structure de maniere HIERARCHIQUE.
""")

print("\n" + "=" * 70)
print("2. DIMENSIONS ET STATISTIQUES")
print("=" * 70)

n_points, n_features = df.shape
print(f"""
DIMENSIONS:
  • Nombre de points: {n_points}
  • Nombre de features: {n_features} (x, y)

STATISTIQUES DESCRIPTIVES:
""")
display(df.describe().round(2), title="Statistiques")

print(f"""
OBSERVATIONS:
  • X varie de {df['x'].min():.1f} a {df['x'].max():.1f}
  • Y varie de {df['y'].min():.1f} a {df['y'].max():.1f}
  • Les donnees semblent bien reparties dans l'espace
""")

print("\n" + "=" * 70)
print("3. VISUALISATION DES DONNEES")
print("=" * 70)

print("""
Visualisons les donnees pour avoir une intuition des clusters possibles.
""")

plt.figure(figsize=(10, 6))
plt.scatter(df['x'], df['y'], alpha=0.6, color='#9B7AC4', s=40, edgecolors='white', linewidth=0.5)
plt.xlabel('X', fontsize=12)
plt.ylabel('Y', fontsize=12)
plt.title('Donnees de Clustering - Structure a Decouvrir', fontsize=14, fontweight='bold')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

print("""
ANALYSE VISUELLE:
  • On distingue visuellement plusieurs groupes de points
  • Certains groupes semblent plus denses que d'autres
  • Le clustering hierarchique va nous reveler la structure COMPLETE

AVANTAGE DU HIERARCHIQUE:
  → Pas besoin de decider combien de clusters maintenant!
  → Le dendrogramme nous montrera TOUTES les possibilites.
""")

print("\n" + "=" * 70)
print("              PRET POUR LA CONSTRUCTION DU DENDROGRAMME")
print("=" * 70)
Ctrl+Entrée

Cliquez sur « Exécuter » pour voir le résultat.

Code

Construire le dendrogramme

from scipy.cluster.hierarchy import dendrogram, linkage
from sklearn.preprocessing import StandardScaler

print("=" * 70)
print("       CONSTRUCTION DU DENDROGRAMME")
print("=" * 70)

print("""
Le DENDROGRAMME est un arbre qui represente l'historique complet des
fusions de clusters. C'est l'outil principal du clustering hierarchique!

ETAPES DE CONSTRUCTION:
1. Normaliser les donnees (StandardScaler)
2. Calculer la matrice de linkage (distances entre clusters)
3. Construire l'arbre des fusions
""")

print("\n" + "=" * 70)
print("1. PREPARATION DES DONNEES")
print("=" * 70)

X = df[['x', 'y']].values
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

print(f"""
Donnees brutes: {X.shape[0]} points x {X.shape[1]} dimensions

POURQUOI NORMALISER?
  • Les features doivent avoir le meme poids dans les distances
  • Sans normalisation, une feature avec grande variance dominerait
  • StandardScaler: moyenne=0, ecart-type=1

VERIFICATION DE LA NORMALISATION:
  • Avant: X moyen = {X.mean(axis=0).round(2)}, std = {X.std(axis=0).round(2)}
  • Apres: X moyen = {X_scaled.mean(axis=0).round(4)}, std = {X_scaled.std(axis=0).round(4)}
""")

print("\n" + "=" * 70)
print("2. CALCUL DE LA MATRICE DE LINKAGE")
print("=" * 70)

print("""
Le LINKAGE definit comment calculer la distance entre clusters.

METHODE 'WARD' (utilisee ici):
  • Minimise l'augmentation de variance intra-cluster
  • Tend a creer des clusters spheriques et de taille similaire
  • Recommandee pour la plupart des cas
""")

Z = linkage(X_scaled, method='ward')

print(f"""
MATRICE DE LINKAGE CALCULEE:
  • Forme: {Z.shape}
  • Chaque ligne = une fusion: [cluster1, cluster2, distance, nb_points]
  • Nombre de fusions effectuees: {len(Z)}
  • Distance min de fusion: {Z[:, 2].min():.4f}
  • Distance max de fusion: {Z[:, 2].max():.4f}
""")

print("\n" + "=" * 70)
print("3. VISUALISATION DU DENDROGRAMME")
print("=" * 70)

print("""
LECTURE DU DENDROGRAMME:
  • Axe X: echantillons (feuilles de l'arbre)
  • Axe Y: distance (hauteur de fusion)
  • Chaque 'pont' horizontal = une fusion de clusters
  • La hauteur du pont = dissimilarite entre les clusters fusionnes
""")

plt.figure(figsize=(14, 7))
dendrogram(Z, truncate_mode='lastp', p=30, show_leaf_counts=True,
           leaf_rotation=90, leaf_font_size=10)
plt.xlabel('Echantillons (ou nombre de points dans le sous-arbre)', fontsize=12)
plt.ylabel('Distance de fusion', fontsize=12)
plt.title('Dendrogramme - Vue Hierarchique Complete', fontsize=14, fontweight='bold')
plt.grid(True, alpha=0.3, axis='y')
plt.tight_layout()
plt.show()

print("""
INTERPRETATION:
  • Les grands "sauts" verticaux indiquent des separations naturelles
  • Plus on coupe bas, plus on a de clusters
  • Plus on coupe haut, moins on a de clusters

COMMENT CHOISIR LE NOMBRE DE CLUSTERS?
  → Cherchez le plus grand "saut" vertical (gap)
  → Cela correspond a une separation naturelle des donnees
  → On va voir comment faire dans la section suivante!

ANALOGIE BIOLOGIQUE:
  Le dendrogramme ressemble a un arbre genealogique:
  - Les feuilles = individus (points de donnees)
  - Les branches = ancetres communs (clusters)
  - La racine = ancetre commun a tous (cluster unique)
""")

print("\n" + "=" * 70)
print("              DENDROGRAMME CONSTRUIT AVEC SUCCES!")
print("=" * 70)
Ctrl+Entrée

Cliquez sur « Exécuter » pour voir le résultat.

Contenu verrouillé
6 / 13

Continuez votre apprentissage

Vous avez exploré 6 sections de ce module. Connectez-vous pour débloquer le reste du cours, incluant les exercices pratiques et les solutions.

Ctrl ou Cmd plus Entrée exécute le code. Tab indente ; Échap puis Tab quitte l'éditeur.