UMAP : Guide Complet — Principes, Exemples et Implémentation Python

UMAP : Guide Complet — Principes, Exemples et Implémentation Python

UMAP : Guide complet — Principes, Exemples et Implémentation Python

Résumé — UMAP (Uniform Manifold Approximation and Projection) est un algorithme de réduction de dimensionalité qui préserve simultanément la structure locale et globale des données. Plus rapide que t-SNE et capable d’extrapoler, il repose sur la théorie des variétés topologiques et l’optimisation de graphes. Développé par Leland McInnes et John Healy, UMAP est devenu l’outil de référence pour la visualisation de données haute dimension dans de nombreux domaines scientifiques.


Principe mathématique

UMAP repose sur trois piliers mathématiques fondamentaux qui le distinguent nettement de ses prédécesseurs :

1. Construction du graphe k-NN flou : Pour chaque point $x_i$, on identifie ses $k$ plus proches voisins. On définit une distance locale adaptative $\rho_i$ (distance au $k$-ième voisin) et une échelle $\sigma_i$ déterminée par recherche binaire pour que la somme des poids des arêtes issues de $x_i$ soit cohérente. La similarité entre $x_i$ et $x_j$ est donnée par :

$$w_{ij} = \exp\left(-\frac{\max(0, d(x_i, x_j) – \rho_i)}{\sigma_i}\right)$$

L’astuce clé ici est l’adaptation locale : chaque point a son propre rayon $\sigma_i$, ce qui signifie que UMAP s’adapte automatiquement aux variations de densité dans les données. Là où d’autres algorithmes utilisent un paramètre global unique, UMAP ajuste sa sensibilité localement.

2. Graphe symétrique (union floue) : Les arêtes calculées ci-dessus sont orientées ($w_{ij} \neq w_{ji}$). Pour obtenir un graphe non-orienté, UMAP applique une union floue probabiliste :

$$w’{ij} = w$$} + w_{ji} – w_{ij} \cdot w_{ji

Cette opération peut se comprendre comme un “OU probabiliste” : la force de la connexion entre deux points est forte si au moins l’un des deux considère l’autre comme un voisin proche. C’est ce qui permet à UMAP de bien gérer les clusters de densités très différentes.

3. Optimisation de l’embedding basse dimension : En dimension cible (typiquement 2), on définit des similarités avec une distribution de Student décalée :

$$q_{ij} = (1 + a \cdot ||y_i – y_j||^{2b})^{-1}$$

où $a$ et $b$ sont des paramètres déterminés par min_dist et spread. L’optimisation minimise la cross-entropy (et non la KL-divergence comme t-SNE) par descente de gradient stochastique :

$$CE = \sum_{i \neq j} w’{ij} \log\left(\frac{w’\right) + (1 – w’}}{q_{ij}{ij}) \log\left(\frac{1 – w’\right)$$}}{1 – q_{ij}

Fondement théorique : Contrairement à t-SNE qui était essentiellement heuristique, UMAP est justifié par la topologie algébrique. Les auteurs démontrent que sous l’hypothèse d’un échantillonnage uniforme sur une variété riemannienne, le graphe k-NN flou est une approximation du nerf d’un recouvrement de la variété. Ce lien avec la théorie de Čech fournit une base mathématique solide à l’algorithme.


Intuition

Imaginez que vous dessinez une carte du métro d’une grande ville. Les stations voisines doivent rester proches sur le plan, mais vous pouvez déformer les distances entre quartiers éloignés pour que tout tienne sur une page. t-SNE fait cela avec une précision remarquable pour les détails, mais au prix de perdre toute information sur les distances globales — impossible de savoir si deux groupes de stations sont proches ou éloignés l’un de l’autre.

UMAP, lui, parvient à préserver à la fois le voisinage immédiat et la structure d’ensemble. Les quartiers restent dans le bon ordre relatif, et on peut même distinguer les artères principales qui les relient. C’est comme si vous aviez la précision du t-SNE pour les détails, mais la fidélité du PCA pour la vue d’ensemble.

L’analogie du tissu : Imaginez un tissu froissé en 3D. PCA l’aplatit brutalement en le déchirant. t-SNE le découpe en morceaux qu’il dispose joliment mais sans respecter l’ordre original. UMAP, lui, défroisse le tissu avec soin en préservant à la fois les motifs locaux (le motif du tissu reste reconnaissable) et la forme globale (les bords restent aux bons endroits).

Pourquoi est-ce plus rapide que t-SNE ? : t-SNE calcule la similarité pour toutes les paires de points, ce qui coûte $O(n^2)$. UMAP ne calcule que les $k$ voisins de chaque point, ramenant le coût à $O(n \cdot k \cdot \log(n))$ grâce aux structures de données d’approximation de plus proches voisins (k-d trees, RP-trees). Sur 70 000 points MNIST, t-SNE prend plusieurs minutes quand UMAP boucle en quelques secondes.


Implémentation Python

Exemple 1 : UMAP sur MNIST avec umap-learn

import umap
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_openml

# Charger MNIST (échantillon pour la vitesse)
mnist = fetch_openml('mnist_784', version=1, as_frame=False)
X, y = mnist.data[:7000], mnist.target[:7000]

# Configuration du réducteur UMAP
reducer = umap.UMAP(
    n_components=2,
    n_neighbors=15,
    min_dist=0.1,
    metric='euclidean',
    random_state=42
)

# Transformation
X_embedded = reducer.fit_transform(X)

# Visualisation
fig, ax = plt.subplots(1, 1, figsize=(10, 8))
scatter = ax.scatter(
    X_embedded[:, 0], X_embedded[:, 1],
    c=y.astype(int), cmap='tab10', s=5, alpha=0.7
)
plt.colorbar(scatter, ticks=range(10))
ax.set_title('UMAP : Visualisation MNIST en 2D')
ax.set_xlabel('Composante UMAP 1')
ax.set_ylabel('Composante UMAP 2')
plt.tight_layout()
plt.savefig('umap_mnist.png', dpi=150)
print(f"UMAP terminé. Forme de l'embedding : {X_embedded.shape}")
print(f"Les 10 chiffres forment des clusters bien séparés en 2D.")

Exemple 2 : Comparaison UMAP vs t-SNE vs PCA

import umap
from sklearn.datasets import load_digits
from sklearn.manifold import TSNE
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import time

X, y = load_digits(return_X_y=True)

# PCA (référence linéaire)
t0 = time.time()
pca = PCA(n_components=2).fit_transform(X)
pca_time = time.time() - t0
print(f"PCA : {pca_time:.3f}s")

# t-SNE
t0 = time.time()
tsne = TSNE(n_components=2, perplexity=30, random_state=42).fit_transform(X)
tsne_time = time.time() - t0
print(f"t-SNE : {tsne_time:.3f}s")

# UMAP
t0 = time.time()
umap_res = umap.UMAP(n_components=2, n_neighbors=10, random_state=42).fit_transform(X)
umap_time = time.time() - t0
print(f"UMAP : {umap_time:.3f}s")
print(f"UMAP est {tsne_time/umap_time:.1f}x plus rapide que t-SNE")

# Affichage comparatif
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
for ax, res, title in zip(axes, [pca, tsne, umap_res], ['PCA', 't-SNE', 'UMAP']):
    sc = ax.scatter(res[:, 0], res[:, 1], c=y, cmap='tab10', s=10)
    ax.set_title(f'{title}\n({len(set(y))} chiffres)')
    ax.set_xticks([])
    ax.set_yticks([])
plt.suptitle('Comparaison PCA / t-SNE / UMAP : Chiffres manuscrits')
plt.tight_layout()
plt.savefig('umap_comparison.png', dpi=150)

Exemple 3 : UMAP avec données supervisées (y comme information)

import umap
from sklearn.datasets import load_iris
from sklearn.metrics import silhouette_score

# iris
X, y = load_iris(return_X_y=True)

# Recherche du meilleur n_neighbors par silhouette
best_score, best_k = -1, None
results = []
for k in [3, 5, 10, 15, 20, 30]:
    embedding = umap.UMAP(n_neighbors=k, n_components=2, random_state=42).fit_transform(X)
    score = silhouette_score(embedding, y)
    results.append((k, score))
    if score > best_score:
        best_score, best_k = score, k
    print(f"  k={k:2d} → silhouette={score:.3f}")

print(f"\nMeilleur n_neighbors : {best_k} (silhouette={best_score:.3f})")

Exemple 4 : Transform de nouvelles données (capacité d’extrapolation)

import umap
import numpy as np
from sklearn.datasets import make_classification

# Données d'entraînement
X_train, y_train = make_classification(n_samples=2000, n_features=50, n_classes=3, random_state=42)

# Ajuster UMAP sur les données d'entraînement
reducer = umap.UMAP(n_components=2, random_state=42)
X_train_2d = reducer.fit_transform(X_train)
print(f"Entraînement terminé. Forme : {X_train_2d.shape}")

# Transformer de NOUVELLES données sans réentraînement
X_new = np.random.randn(200, 50)
X_new_2d = reducer.transform(X_new)
print(f"Transformation de nouvelles données : {X_new_2d.shape}")
print(f"UMAP est l'un des rares algorithmes non supervisés à supporter transform().")

Hyperparamètres

Hyperparamètre Valeur défaut Impact Recommandation
n_neighbors 15 Contrôle l’équilibre local/global. Faible (5-10) = clusters fins, élevé (30-100) = vue globale Commencer à 15, ajuster selon l’échelle souhaitée
min_dist 0.1 Distance minimale dans l’embedding. 0.01 = points très serrés, 0.99 = points dispersés 0.05-0.1 pour clustering, 0.3-0.5 pour visualisation
n_components 2 Dimension cible : 2 pour visualisation, 5-50 pour prétraitement supervisé 2 ou 3 pour visualiser, 10-50 pour pipeline ML
metric ‘euclidean’ Métrique de distance entre points ‘cosine’ pour texte/NLP, ‘correlation’ pour bio
spread 1.0 Échelle effective de l’embedding (avec min_dist détermine a et b) Garder 1.0 dans la plupart des cas
alpha 1.0 Taux d’apprentissage initial de l’optimisation 0.5-1.0; baisser si l’optimisation oscille
negative_sample_rate 5 Ratio échantillons négatifs/positifs 5 (défaut) pour vitesse, 10 pour qualité maximale
random_state None Graine pour la reproductibilité Toujours fixer pour des résultats reproductibles

Avantages de UMAP

  1. Préservation globale : Contrairement à t-SNE qui ne préserve que les voisinages locaux, UMAP conserve également la structure à grande échelle. Les relations entre clusters sont significatives.
  2. Rapidité exceptionnelle : Grâce à l’approximation k-NN (RP-trees), UMAP est 5 à 50 fois plus rapide que t-SNE sur des jeux de données de taille moyenne à grande.
  3. Capacité d’extrapolation : Via transform(), UMAP peut projeter de nouvelles données dans un embedding existant sans recalcul complet — unique parmi les algorithmes de visualisation non linéaires.
  4. Flexibilité dimensionnelle : Bien que surtout utilisé en 2D/3D, UMAP fonctionne efficacement jusqu’à 50-100 dimensions pour le prétraitement avant des modèles supervisés, offrant une alternative non linéaire à l’ACP.
  5. Large éventail de métriques : Support natif de dizaines de métriques (euclidienne, cosine, Manhattan, Hamming, Jaccard, Hellinger, Wasserstein…) permettant de traiter text, images, séquences, et données catégorielles.

Limites de UMAP

  1. Sensibilité aux hyperparamètres : n_neighbors et min_dist ont un impact majeur sur le résultat. Il n’existe pas de valeur universellement optimale — un réglage par grid search est souvent nécessaire.
  2. Absence d’interprétabilité des axes : Comme t-SNE, les composantes UMAP n’ont pas de signification physique directe, contrairement aux composantes principales de l’ACP.
  3. Variabilité stochastique : Différentes graines aléatoires produisent des visualisations différentes, ce qui peut être déstabilisant pour les utilisateurs novices.
  4. Dépendance à numba : La bibliothèque umap-learn dépend de numba, qui compile les fonctions lors de la première exécution (délai initial) et peut poser des problèmes d’installation sur certaines combinaisons de versions Python/OS.
  5. Coût mémoire sur très grands jeux : Malgré son efficacité algorithmique, la construction du graphe k-NN consomme $O(n \cdot k)$ mémoire, ce qui devient problématique au-delà de quelques millions de points.

4 cas d’usage concrets

1. Visualisation de données transcriptomiques (single-cell RNA-seq)

En génomique, les données d’expression génique mesurent l’activité de 20 000+ gènes dans des milliers de cellules individuelles. UMAP est devenu l’outil standard de visualisation dans ce domaine, ayant largement remplacé t-SNE dans les pipelines comme Scanpy et Seurat. Il permet aux biologistes d’identifier visuellement des sous-populations cellulaires (types cellulaires, états de différenciation, cycles cellulaires) et d’explorer les trajectoires de développement.

2. Clustering assisté par UMAP + HDBSCAN

Une approche puissante consiste à projeter les données en 10-50 dimensions avec UMAP, puis à appliquer HDBSCAN ou DBSCAN. L’embedding UMAP rend les structures de clusters plus denses et mieux séparées que dans l’espace original. C’est particulièrement efficace pour les données où les clusters ont des formes non sphériques et des densités variées — des situations où K-Means et l’ACP échouent.

3. Exploration d’espaces de recommandation

Dans les systèmes de recommandation (e-commerce, streaming, presse), les utilisateurs et les contenus sont représentés par des vecteurs de 100 à 500 dimensions. UMAP permet aux équipes produit de visualiser la structure de cet espace : quels contenus sont proches ? Y a-t-il des zones vides (opportunités de contenu manquant) ? Les clusters correspondent-ils à des genres ou des catégories métier ? Cette compréhension visuelle aide à concevoir de meilleures stratégies de recommandation et à détecter des biais.

4. Détection d’anomalies en cybersécurité et industrie

En surveillance réseau, les connexions normales forment un continuum dense dans l’espace UMAP. Les anomalies (attaques DDoS, intrusions, tentatives de phishing) apparaissent comme des points ou de petits groupes isolés, clairement séparés de la masse principale. De même, dans l’industrie, des mesures de capteurs déviantes (début de panne, usure anormale) se détachent visuellement. Cette propriété est exploitée dans des dashboards de monitoring temps réel où un opérateur humain surveille la topologie UMAP pour détecter les dérives anormales.


Bonnes pratiques pour utiliser UMAP

  • Toujours normaliser les données avant UMAP (StandardScaler ou MinMaxScaler), comme pour toute méthode basée sur les distances.
  • Essayer plusieurs valeurs de n_neighbors : commencez à 5, 15, 30 et 50. Plus la valeur est faible, plus UMAP se concentre sur la structure locale fine.
  • Fixer random_state pour la reproductibilité, surtout si vous présentez les résultats à des collègues ou dans une publication.
  • Combiner avec PCA : pour les très grandes données, appliquez d’abord une ACP pour réduire à 50 dimensions, puis UMAP pour la visualisation 2D. Cela accélère considérablement le calcul sans perte significative de qualité.
  • Utiliser transform() avec précaution : les nouvelles données sont projetées dans l’embedding existant, ce qui est rapide mais peut donner des résultats moins bons qu’un réentraînement complet si la distribution des nouvelles données est très différente.

Conclusion

UMAP représente une avancée significative dans le domaine de la réduction de dimensionalité. En combinant une base théorique solide (topologie algébrique) avec des approximations algorithmiques efficaces (k-NN flou, descente de gradient stochastique), il offre un compromis inégalé entre qualité de préservation, vitesse de calcul et polyvalence.

Face au choix entre PCA, t-SNE et UMAP, la règle pratique est la suivante : PCA pour l’interprétabilité et la vitesse maximale, t-SNE pour des visualisations fines de petits jeux de données, UMAP pour tout le reste — grandes données, structure globale, pre-processing supervisé, et extraposition.


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.