SOM (Self-Organizing Map) : Guide Complet — Carte Auto-Organisatrice de Kohonen

SOM (Self-Organizing Map) : Guide Complet — Carte Auto-Organisatrice de Kohonen

SOM (Self-Organizing Map) — Carte Auto-Organisatrice de Kohonen

Résumé

La Self-Organizing Map (SOM), ou carte auto-organisatrice de Kohonen, est un algorithme d’apprentissage non supervisé qui projette des données de haute dimension sur une grille bidimensionnelle tout en préservant leur structure topologique. Introduite par Teuvo Kohonen en 1982, la SOM demeure l’une des approches les plus élégantes pour la visualisation et le clustering de données complexes. Contrairement à des méthodes comme le K-Means, qui produisent simplement des groupes plats, la SOM organise ses neurones sur une grille spatiale où les régions voisines correspondent à des données similaires. Cette propriété topologique unique en fait un outil privilégié pour l’exploration de données, la détection de motifs et la cartographie de concepts dans des domaines aussi variés que la bio-informatique, la finance ou le traitement d’images.


Principe Mathématique

La Grille de Neurones

L’architecture fondamentale d’une SOM repose sur une grille régulière de neurones (généralement 1D, 2D hexagonale ou rectangulaire). Chaque neurone i possède un vecteur de poids wi ∈ ℝ^d de même dimension que les données d’entrée. Ces vecteurs de poids jouent le rôle de « prototypes » ou « centroïdes » adaptatifs, similaires aux centres du K-Means, mais organisés spatialement sur la grille.

Étape 1 : Recherche du BMU (Best Matching Unit)

Pour chaque vecteur d’entrée x, l’algorithme identifie le Meilleur Neurone Correspondant — le BMU — en calculant la distance euclidienne entre x et chaque vecteur de poids :

BMU = argmin_i || x - w_i ||

Le BMU est le neurone dont le vecteur de poids est le plus proche du vecteur d’entrée courant. Cette étape est analogue à l’affectation du K-Means, mais au lieu de simplement assigner le point au cluster le plus proche, la SOM utilise cette information pour mettre à jour une région entière de la grille.

Étape 2 : Mise à Jour des Poids avec Voisinage Gaussien

Contrairement au K-Means qui ne met à jour que le centroïde gagnant, la SOM met à jour le BMU et ses voisins sur la grille. La règle de mise à jour s’écrit :

w_j ← w_j + η · h_ij · (x - w_j)

où :

  • η (éta) est le taux d’apprentissage (learning rate), un scalaire positif qui décroît au fil des itérations.
  • h_ij est la fonction de voisinage gaussienne entre le BMU (neurone i) et le neurone voisin j :
h_ij(t) = exp( -d(i,j)² / (2 · σ(t)²) )
  • d(i,j) est la distance sur la grille entre les neurones i et j (distance euclidienne ou de Manhattan sur les coordonnées de la grille).
  • σ(t) est le rayon de voisinage à l’itération t, qui décroît progressivement.

Décroissance Temporelle du Taux d’Apprentissage et du Rayon

Un aspect crucial de la SOM est la décroissance progressive des deux hyperparamètres clés :

η(t) = η₀ · exp(-t / τ₁)
σ(t) = σ₀ · exp(-t / τ₂)

η₀ est le taux d’apprentissage initial, σ₀ le rayon de voisinage initial, et τ₁, τ₂ sont des constantes de temps liées au nombre total d’itérations T :

τ₁ = T / ln(η₀)
τ₂ = T / ln(σ₀)

Cette double décroissance assure deux phases distinctes :

  1. Phase d’organisation globale (σ grand, η élevé) : au début de l’entraînement, le large voisinage permet à des régions entières de la carte de se déplacer collectivement, créant un ordre topologique grossier. La carte se plie progressivement pour épouser la distribution sous-jacente des données, un peu comme un tissu élastique qui se moule sur une forme complexe.
  2. Phase de raffinement local (σ petit, η faible) : vers la fin de l’entraînement, seul un petit nombre de voisins proches du BMU est affecté, permettant un ajustement fin de la carte. Le voisinage se contracte jusqu’à ne concerner que le BMU lui-même, similaire à une descente de gradient locale.

Ce mécanisme à deux phases est la clé de voûte de l’algorithme : sans la phase d’organisation, la carte resterait piégée dans des minima locaux ; sans la phase de raffinement, la précision resterait médiocre.

Pourquoi la Topologie se Préserve-t-elle ?

La force du voisinage gaussien est que deux points d’entrée proches dans l’espace d’origine activeront probablement des BMU voisins sur la grille. Par conséquent, leurs vecteurs de poids seront tirés dans des directions similaires, maintenant ainsi une cohérence spatiale entre proximité dans l’espace d’origine et proximité sur la carte. Cette propriété de préservation topologique distingue fondamentalement la SOM du simple clustering.


Intuition Géographique : Une Carte du Monde des Données

Imaginez que vous possédez des milliers de profils clients, chacun décrit par cinquante variables (âge, revenus, fréquence d’achat, préférences, etc.). Visualiser directement cet espace à cinquante dimensions est impossible pour un esprit humain. La SOM agit comme un cartographe algorithmique : elle prend ce paysage multidimensionnel et le projette sur une grille 2D lisible.

Sur cette carte, les régions voisines regroupent des profils similaires. En haut à gauche, vous trouverez peut-être les jeunes urbains à fort pouvoir d’achat. En bas à droite, les retraités ruraux aux achats occasionnels. Entre les deux, des zones de transition représentent des clientèles hybrides. Si deux points sont côte à côte sur la carte, ils se ressemblent dans l’espace d’origine ; s’ils sont éloignés, ils diffèrent significativement.

C’est précisément cette capacité à révéler la structure latente des données à travers une représentation spatiale intuitive qui rend la SOM si puissante. Elle transforme l’invisible en visible.


Implémentation Python Complète

Installation

pip install minisom matplotlib numpy seaborn scikit-learn

Code Complet avec U-Matrix, Heatmap et Clustering

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from minisom import MiniSom
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from scipy.spatial.distance import euclidean

# 1. Chargement et prepa ration des donnees
iris = load_iris()
X = iris.data
y = iris.target
feature_names = iris.feature_names
class_names = iris.target_names

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 2. Initialisation et entrainement de la SOM
grid_size = (10, 10)
sigma = 2.0
learning_rate = 0.5
n_iter = 1000

som = MiniSom(
    grid_size[0], grid_size[1],
    input_len=X_scaled.shape[1],
    sigma=sigma,
    learning_rate=learning_rate,
    topology="hexagonal",
    neighborhood_function="gaussian",
    random_seed=42
)

som.random_weights_init(X_scaled)

print("Entraine ment de la carte auto-organisatrice...")
som.train_random(X_scaled, n_iter)
print(f"Entraine ment termine  apres {n_iter} iterations.")

# 3. Visualisation : U-Matrix (Distance Map)
fig, axes = plt.subplots(2, 2, figsize=(14, 12))

u_matrix = som.distance_map()
im0 = axes[0, 0].imshow(u_matrix, cmap="bone_r")
axes[0, 0].set_title("U-Matrix - Distance Map", fontsize=13, fontweight="bold")
axes[0, 0].set_xlabel("Position sur la grille")
axes[0, 0].set_ylabel("Position sur la grille")
plt.colorbar(im0, ax=axes[0, 0], label="Distance moyenne")

# 4. Marquage des classes sur la carte
colors_list = ["red", "green", "blue"]
markers_list = ["o", "s", "^"]

win_map = {}
for idx, sample in enumerate(X_scaled):
    winner = som.winner(sample)
    key = (winner[0], winner[1])
    if key not in win_map:
        win_map[key] = []
    win_map[key].append(y[idx])

for cls in range(len(class_names)):
    positions = []
    for (i, j), labels in win_map.items():
        if cls in labels:
            count = labels.count(cls)
            for _ in range(min(count, 3)):
                noise_x = np.random.uniform(-0.15, 0.15)
                noise_y = np.random.uniform(-0.15, 0.15)
                positions.append((i + noise_x, j + noise_y))

    if positions:
        pos_arr = np.array(positions)
        axes[0, 0].scatter(
            pos_arr[:, 0], pos_arr[:, 1],
            c=[colors_list[cls]], marker=markers_list[cls],
            label=class_names[cls], alpha=0.7, s=40
        )

axes[0, 0].legend(fontsize=10)

# 5. Heatmap par variable
for idx, name in enumerate(feature_names):
    row = idx // 2
    col = idx % 2
    if row < 2 and col < 2:
        component = som.get_weights()[:, :, idx]
        axes[row, col].imshow(component, cmap="viridis")
        axes[row, col].set_title(
            f"Composante : {name}",
            fontsize=11, fontweight="bold"
        )
        plt.colorbar(
            axes[row, col].images[-1],
            ax=axes[row, col], shrink=0.8
        )

plt.tight_layout()
plt.show()

# 6. Clustering a partir de la SOM
from sklearn.cluster import KMeans

weights = som.get_weights()
weight_vectors = weights.reshape(-1, weights.shape[2])

k_som = 3
kmeans = KMeans(n_clusters=k_som, random_state=42, n_init=10)
som_clusters = kmeans.fit_predict(weight_vectors)

point_clusters = []
for sample in X_scaled:
    winner = som.winner(sample)
    cluster_idx = winner[0] * grid_size[1] + winner[1]
    point_clusters.append(som_clusters[cluster_idx])

point_clusters = np.array(point_clusters)

fig, ax = plt.subplots(1, 1, figsize=(8, 6))
for cls in range(k_som):
    mask = point_clusters == cls
    ax.scatter(
        X_scaled[mask, 0], X_scaled[mask, 1],
        alpha=0.6, label=f"Cluster SOM {cls}", s=50
    )
ax.set_title("Clustering SOM + K-Means", fontsize=13, fontweight="bold")
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

# 7. Evaluation de la qualite du clustering
from sklearn.metrics import adjusted_rand_score

ari = adjusted_rand_score(y, point_clusters)
print(f"\nAdjusted Rand Index (vraies classes vs clusters SOM) : {ari:.4f}")

# 8. Quantification de l'erreur
quantization_errors = []
for sample in X_scaled:
    winner = som.winner(sample)
    w = som.get_weights()[winner[0], winner[1]]
    error = euclidean(sample, w)
    quantization_errors.append(error)

mean_qe = np.mean(quantization_errors)
print(f"Erreur moyenne de quantification : {mean_qe:.4f}")
print(f"Ecart-type de l'erreur : {np.std(quantization_errors):.4f}")

# 9. Prediction d'un nouveau point
def predict_som(new_sample, som_model, scaler_ref):
    sample_scaled = scaler_ref.transform(new_sample.reshape(1, -1))
    winner = som_model.winner(sample_scaled[0])
    return winner

new_data = np.array([[5.1, 3.5, 1.4, 0.2]])
winner = predict_som(new_data, som, scaler)
print(f"\nBMU pour le nouveau point : ({winner[0]}, {winner[1]})")
print("Ce point se situe dans la region de la carte correspondant aux Iris setosa.")

Explication du Code

Le code ci-dessus met en œuvre un pipeline complet d’analyse par SOM :

  • Phase de préparation : Les données Iris sont normalisées avec StandardScaler, une étape indispensable car la SOM repose sur des distances euclidiennes.
  • Entraînement : La fonction train_random de MiniSom présente les échantillons de manière aléatoire, ce qui évite tout biais lié à l’ordre des données.
  • U-Matrix (Unified Distance Matrix) : Cette visualisation affiche les distances moyennes entre neurones adjacents. Les régions claires indiquent des frontières entre clusters (grandes distances), tandis que les régions sombres correspondent à des zones homogènes.
  • Cartes de composantes : Chaque heatmap montre comment une variable spécifique varie sur la grille, révélant la contribution de chaque caractéristique à la structure des données.
  • Clustering hybride : En appliquant un K-Means sur les vecteurs de poids de la SOM, on obtient un clustering plus robuste que le K-Means seul, car les poids sont déjà organisés topologiquement.
  • Évaluation : L’Adjusted Rand Index (ARI) mesure la concordance entre les clusters obtenus et les véritables étiquettes.

Hyperparamètres Essentiels

Le choix des hyperparamètres influence profondément la qualité de la carte. Voici un guide pratique :

Hyperparamètre Rôle Valeurs typiques Effets d’un mauvais choix
grid_size Dimensions de la grille (lignes × colonnes) (10,10) à (50,50) selon la taille du dataset Trop petit : sous-spécification, clusters fusionnés. Trop grand : surapprentissage, régions vides.
sigma Rayon initial du voisinage gaussien 1/3 à 1/2 de la dimension de la grille Trop petit : pas d’organisation topologique. Trop grand : tous les neurones bougent ensemble.
learning_rate Taux d’apprentissage initial (η₀) 0.3 à 0.7 Trop élevé : instabilité et oscillations. Trop faible : convergence lente, carte mal organisée.
n_iter Nombre total d’itérations 500 à 10 000 Trop faible : entraînement incomplet. Trop élevé : temps de calcul excessif, gains marginaux.

Heuristiques pratiques

  • Règle du pouce pour la taille de grille : grid_size ≈ 5 × √nn est le nombre d’échantillons. Pour 150 échantillons, cela donne environ 61 neurones, soit une grille 8×8 ou 10×10.
  • Sigma initial : environ le tiers de la plus grande dimension de la grille. Pour une grille 10×10, σ₀ = 3 est un bon point de départ.
  • Learning rate : commencez avec 0.5, puis ajustez en observant la stabilité de l’erreur de quantification.
  • Topologie hexagonale vs rectangulaire : l’hexagonale offre une meilleure isotropie (6 voisins au lieu de 4), ce qui produit des frontières de clusters plus naturelles.

Avantages et Limites

Avantages

  1. Préservation topologique : La SOM maintient les relations de voisinage entre les données, offrant une représentation spatiale cohérente que le K-Means ne peut pas fournir.
  2. Visualisation intuitive : La projection sur une grille 2D permet aux analystes d’explorer visuellement des données multidimensionnelles. L’U-Matrix révèle instantanément la structure de clusters.
  3. Robustesse au bruit : Le mécanisme de voisinage gaussien lisse les effets des points aberrants, car l’influence d’un outlier se diffuse sur plusieurs neurones.
  4. Pas d’hypothèse de distribution : Contrairement aux modèles gaussiens (GMM), la SOM ne suppose aucune forme particulière pour la distribution des données.
  5. Interprétabilité des poids : Chaque neurone possède un vecteur de poids directement interprétable comme un prototype représentatif de sa région.

Limites

  1. Coût computationnel : La recherche du BMU nécessite de calculer la distance avec tous les neurones à chaque itération, soit O(N × M × d) où N est le nombre d’échantillons, M le nombre de neurones et d la dimension.
  2. Dépendance à l’initialisation : Les poids initiaux influencent le résultat final. Plusieurs exécutions avec des graines différentes sont recommandées pour la stabilité.
  3. Hyperparamètres sensibles : La taille de grille, sigma et le learning rate doivent être ajustés soigneusement. Il n’existe pas de règle universellement optimale.
  4. Difficulté avec les données catégorielles : La SOM repose sur des distances continues. Les données catégorielles nécessitent un encodage préalable (one-hot, embedding) qui peut biaiser les résultats.
  5. Non-déterministe partiel : Même avec une graine fixée, l’ordre aléatoire de présentation des échantillons introduit une variabilité qui complique la reproductibilité stricte.

4 Cas d’Usage Concrets

1. Exploration de Données Clients en Marketing

Une banque souhaite segmenter sa clientèle à partir de 30 variables comportementales. La SOM révèle cinq zones distinctes sur la carte : jeunes actifs connectés, familles stables, retraités conservateurs, entrepreneurs à haut rendement et clients précaires. L’U-Matrix montre clairement les frontières entre ces segments. Le marketing peut alors adapter ses offres à chaque zone, avec des campagnes ciblées bien plus efficaces qu’un segmentage par règles métier arbitraires.

2. Analyse de Spectres en Bio-informatique

En protéomique, les spectres de masse de milliers de protéines forment des signaux de très haute dimension. La SOM permet de cartographier les similarités structurelles : les protéines de fonctions proches se regroupent spontanément sur la carte, révélant des familles fonctionnelles même en l’absence d’annotation préalable. Des chercheurs ont utilisé cette approche pour découvrir de nouvelles familles de protéines inconnues.

3. Détection d’Anomalies Industrielles

Sur une ligne de production équipée de centaines de capteurs, la SOM apprend la cartographie du fonctionnement normal. Lorsqu’un nouveau point de mesure tombe sur une région de la carte non couverte lors de l’entraînement (ou très éloignée de tout BMU connu), l’erreur de quantification exceptionnelle signale une anomalie potentielle. Cette approche est utilisée dans l’industrie pétrolière pour détecter des dérives de forage avant qu’elles ne deviennent critiques.

4. Organisation de Documents Textuels

En combinant la SOM avec des embeddings de mots (Word2Vec, BERT), on peut projeter des milliers de documents sur une carte 2D où les thèmes similaires se regroupent naturellement. Cette technique est employée par les bibliothèques numériques et les moteurs de recherche pour créer des « cartes thématiques » navigables, permettant aux utilisateurs d’explorer visuellement un corpus documentaire. Contrairement à un classement hiérarchique rigide, la SOM capture les zones de recouvrement entre disciplines, révélant les domaines interdisciplinaires.


Voir Aussi


Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.