Polydesk-logotype
Polydesk.ai — Header

t-SNE (t-distributed Stochastic Neighbor Embedding)

t-SNE est un algorithme de réduction de dimensionnalité non linéaire conçu pour visualiser des données de haute dimension en 2D ou 3D, en préservant la structure locale des voisinages entre points proches.

Inventé par Laurens van der Maaten et Geoffrey Hinton en 2008, t-SNE est devenu la référence pour la visualisation exploratoire en machine learning, bioinformatique et NLP. Son principe : si deux points sont proches dans l’espace de haute dimension, ils doivent rester proches dans la projection 2D. Le résultat est souvent spectaculaire : des clusters visuellement nets émergent de données à des centaines de dimensions.

Depuis quelques années, UMAP l’a largement remplacé pour les nouveaux projets grâce à sa vitesse et sa meilleure préservation de la structure globale. Mais t-SNE reste omniprésent dans la littérature et dans certains domaines (single-cell RNA-seq), et comprendre ses forces et ses pièges est essentiel pour tout data scientist.

Fiche rapide : t-SNE
Nom complet
t-distributed Stochastic Neighbor Embedding
Auteurs
Laurens van der Maaten et Geoffrey Hinton (2008)
Type
Réduction de dimensionnalité non linéaire (visualisation)
Préserve
Structure locale (voisinages)
Ne préserve pas
Distances globales, tailles relatives des clusters
Paramètre clé
Perplexité (typiquement 5 à 50)
Complexité
O(n²) exact, O(n log n) Barnes-Hut
Calcul Python
sklearn.manifold.TSNE, openTSNE

Comment fonctionne t-SNE

Étape 1 : Similarités en haute dimension

Pour chaque paire de points dans l’espace original, t-SNE calcule une probabilité conditionnelle qui reflète leur similarité. Les points proches reçoivent une probabilité élevée, les points éloignés une probabilité quasi nulle. Ces probabilités sont calculées via des distributions gaussiennes centrées sur chaque point, dont la largeur est ajustée par la perplexité.

Étape 2 : Similarités en basse dimension

Dans l’espace 2D (l’embedding), les similarités entre points sont modélisées par une distribution t de Student (d’où le « t » dans t-SNE). L’utilisation d’une distribution à queues lourdes plutôt qu’une gaussienne est l’innovation clé de t-SNE par rapport à son prédécesseur SNE : elle permet de mieux séparer les clusters en 2D en donnant plus d’espace aux points modérément éloignés.

Étape 3 : Optimisation par descente de gradient

L’algorithme minimise la divergence de Kullback-Leibler (KL) entre les distributions de similarité en haute dimension et en basse dimension, via une descente de gradient stochastique. Le processus est itératif : les points bougent progressivement dans l’espace 2D jusqu’à convergence.

La phase d’early exaggeration (exagération précoce) multiplie artificiellement les similarités en haute dimension pendant les premières itérations, forçant les clusters à se former rapidement avant l’optimisation fine.

La perplexité : le paramètre clé

La perplexité est le paramètre le plus important de t-SNE. Elle contrôle l’équilibre entre la préservation de la structure locale et globale. On peut la voir comme une estimation continue du nombre de voisins proches que chaque point devrait avoir.

Effet de la perplexité

Perplexité basse (5-10) : l’algorithme se concentre sur les voisins très proches. Révèle la microstructure mais peut fragmenter les clusters naturels en sous-groupes artificiels. Risque de voir des patterns dans du bruit.

Perplexité moyenne (20-50) : la plage recommandée par défaut. Bon compromis entre structure locale et relations entre clusters. Scikit-learn utilise 30 par défaut.

Perplexité haute (50-100+) : prend en compte des voisinages plus larges. Mieux pour la structure globale mais peut fusionner des clusters distincts. Ne doit pas dépasser le nombre de points dans le dataset.

Règle d’or : testez toujours plusieurs perplexités L’erreur la plus fréquente est d’utiliser une seule valeur de perplexité et de considérer le résultat comme définitif. Testez au minimum 3 valeurs (par exemple 10, 30, 50) et comparez les visualisations. Les structures qui persistent à travers différentes perplexités sont fiables. Celles qui apparaissent uniquement à une perplexité spécifique sont suspectes.

Guide de choix de la perplexité

Taille du dataset Perplexité recommandée Logique
< 200 points 5-15 Peu de voisins disponibles, gardez la perplexité basse
200-2 000 15-40 Plage standard, 30 est un bon défaut
2 000-10 000 30-50 Plus de données, perplexité plus élevée possible
> 10 000 50-100+ Grands datasets, augmentez la perplexité pour la structure globale

t-SNE en Python avec scikit-learn

Usage de base

from sklearn.manifold import TSNE
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_digits
import matplotlib.pyplot as plt

# Charger les données (digits : 64 features, 10 classes)
X, y = load_digits(return_X_y=True)

# Standardiser
X_scaled = StandardScaler().fit_transform(X)

# t-SNE en 2D
tsne = TSNE(n_components=2, perplexity=30,
            max_iter=1000, random_state=42)
X_2d = tsne.fit_transform(X_scaled)

# Visualisation
plt.figure(figsize=(10, 8))
scatter = plt.scatter(X_2d[:, 0], X_2d[:, 1],
                      c=y, cmap='tab10', s=5, alpha=0.7)
plt.colorbar(scatter, label='Chiffre')
plt.title('t-SNE des chiffres manuscrits (perplexité=30)')
plt.xlabel('t-SNE 1')
plt.ylabel('t-SNE 2')
plt.tight_layout()
plt.show()

Pipeline PCA + t-SNE (recommandé)

Scikit-learn recommande de réduire d’abord la dimensionnalité avec la PCA (50 composantes pour les données denses, SVD tronquée pour les données creuses) avant d’appliquer t-SNE. Cela accélère considérablement le calcul et peut stabiliser les résultats.

from sklearn.decomposition import PCA
from sklearn.pipeline import Pipeline

pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('pca', PCA(n_components=50)),
    ('tsne', TSNE(n_components=2, perplexity=30,
                  max_iter=1000, random_state=42))
])

X_2d = pipeline.fit_transform(X)

Comparer plusieurs perplexités

fig, axes = plt.subplots(1, 3, figsize=(18, 5))
perplexities = [10, 30, 50]

for ax, perp in zip(axes, perplexities):
    tsne = TSNE(n_components=2, perplexity=perp,
                max_iter=1000, random_state=42)
    X_2d = tsne.fit_transform(X_scaled)
    ax.scatter(X_2d[:, 0], X_2d[:, 1], c=y,
               cmap='tab10', s=3, alpha=0.7)
    ax.set_title(f'Perplexité = {perp}')
    ax.set_xticks([])
    ax.set_yticks([])

plt.suptitle('Effet de la perplexité sur t-SNE')
plt.tight_layout()
plt.show()

Les autres paramètres importants

Learning rate

Le taux d’apprentissage contrôle la taille des pas de la descente de gradient. Depuis scikit-learn 1.2, la valeur par défaut est 'auto', calculée comme max(N / early_exaggeration / 4, 50). En pratique, laissez le défaut sauf si le résultat ressemble à une boule uniforme (learning rate trop élevé) ou à un nuage compressé (learning rate trop bas).

Nombre d’itérations (max_iter)

Le défaut est 1 000 itérations, ce qui suffit pour la plupart des cas. Les petites perplexités peuvent nécessiter plus d’itérations pour converger. Si votre embedding semble instable, augmentez à 2 000-5 000. La convergence est atteinte quand la KL divergence se stabilise.

Early exaggeration

Facteur multiplicatif appliqué aux similarités pendant la phase initiale (défaut : 12). Augmenter cette valeur pousse les clusters à se séparer plus fortement. Réduisez si les clusters semblent artificiellement éloignés.

Initialisation

Depuis scikit-learn 1.2, l’initialisation par défaut est 'pca' (les deux premières composantes principales). C’est plus stable que l’initialisation aléatoire ('random') et produit des résultats plus reproductibles.

Les 5 pièges majeurs de t-SNE

Piège n°1 : les tailles de clusters ne sont pas fiables

C’est le piège le plus courant. t-SNE adapte sa notion de « distance » à la densité locale. Il dilate les clusters denses et compresse les clusters épars. Un cluster qui apparaît gros en 2D n’est pas nécessairement plus dispersé en haute dimension. Ne comparez jamais les tailles visuelles des clusters dans un plot t-SNE.

Piège n°2 : les distances entre clusters ne sont pas fiables

Les distances entre clusters bien séparés dans un plot t-SNE ne reflètent pas fidèlement les distances dans l’espace original. Deux clusters éloignés en 2D ne sont pas nécessairement plus éloignés qu’un autre pair de clusters rapprochés. La structure globale (relations entre clusters) est sacrifiée au profit de la structure locale (voisinages au sein de chaque cluster).

Piège n°3 : voir des clusters dans du bruit

t-SNE peut créer l’illusion de clusters même sur des données parfaitement aléatoires. Avec une faible perplexité sur du bruit gaussien uniforme, l’algorithme produit des groupes visuels convaincants qui n’ont aucune signification. Solution : testez plusieurs perplexités et vérifiez les clusters avec des métriques de clustering indépendantes (silhouette score, etc.).

Piège n°4 : résultats non reproductibles

t-SNE utilise une optimisation non convexe : différentes initialisations produisent des résultats différents. Fixez toujours random_state pour la reproductibilité. Mais attention : deux exécutions avec le même random_state mais des paramètres différents (perplexité, learning rate) produiront des embeddings très différents. La forme des clusters peut changer, leur position aussi.

Piège n°5 : utiliser t-SNE comme prétraitement ML

t-SNE n’a pas de méthode .transform() : il ne peut pas projeter de nouvelles données sur un embedding existant. Il ne préserve pas les distances globales. Et ses résultats varient entre exécutions. Pour du prétraitement avant un modèle supervisé, utilisez PCA ou UMAP.

L’article de référence L’article interactif « How to Use t-SNE Effectively » (Wattenberg et al., Distill, 2016) est la meilleure ressource pour développer une intuition correcte de t-SNE. Il montre visuellement comment la perplexité affecte les résultats et comment interpréter (et ne pas interpréter) les plots. Lecture fortement recommandée avant toute utilisation sérieuse de t-SNE.

t-SNE vs UMAP : faut-il encore utiliser t-SNE ?

Critère t-SNE UMAP
Vitesse Lent (O(n log n) Barnes-Hut) Rapide (nettement plus rapide)
Structure globale Mal préservée Mieux préservée
Structure locale Excellente Excellente
Nouvelles données Non (pas de .transform()) Oui (.transform() disponible)
Prétraitement ML Non recommandé Possible
Grands datasets (100K+) Très lent Gérable
Maturité / littérature Très établi (2008) Plus récent (2018)
Paramètre clé Perplexité (5-50) n_neighbors (5-200)

Notre verdict : pour un nouveau projet, préférez UMAP. Utilisez t-SNE si vous travaillez dans un domaine où il est le standard établi (bioinformatique single-cell), si vous voulez comparer vos résultats à la littérature existante, ou si vous avez un petit dataset (< 5 000 points) où la différence de vitesse est négligeable.

Applications principales de t-SNE

Bioinformatique : single-cell RNA-seq

Le domaine où t-SNE a eu le plus d’impact. Projeter des milliers de cellules (chacune décrite par 20 000+ gènes) en 2D pour identifier les types cellulaires. Le pipeline standard : normalisation → PCA (50 composantes) → t-SNE (2D). Bien que UMAP gagne du terrain, t-SNE reste très utilisé grâce à la masse de littérature existante.

Visualisation d’embeddings NLP

Projeter des embeddings de mots ou de phrases (Word2Vec, BERT) en 2D pour vérifier que les mots sémantiquement proches sont regroupés. Utile pour le diagnostic de modèles de langage.

Classification d’images

Visualiser les features extraites par un CNN (couche avant la couche de classification) pour comprendre comment le réseau organise les images. Les classes bien séparées en t-SNE 2D indiquent que le réseau a appris des représentations discriminantes.

Détection d’anomalies visuelle

Les anomalies apparaissent souvent comme des points isolés ou éloignés des clusters principaux dans un plot t-SNE. Utile pour identifier visuellement les outliers avant une analyse plus formelle.

Alternatives et variantes

UMAP : le remplaçant principal. Plus rapide, mieux pour la structure globale, supporte .transform().

openTSNE : implémentation Python optimisée de t-SNE avec support des GPU, initialisation PCA, et multi-perplexité. Plus rapide que scikit-learn pour les grands datasets.

FIt-SNE : implémentation rapide basée sur l’interpolation de Barnes-Hut. Complexité O(n) au lieu de O(n log n).

TriMap : alternative récente qui préserve mieux la structure globale en utilisant des triplets de points.

Verdict

t-SNE est un outil de visualisation puissant mais exigeant. Il produit des plots spectaculaires qui révèlent la structure locale des données de haute dimension, mais ses résultats sont sensibles aux paramètres et faciles à surinterprétrer. La règle d’or : testez plusieurs perplexités, ne faites jamais confiance aux tailles ou distances entre clusters, et utilisez t-SNE comme outil exploratoire, pas comme preuve définitive.

Pour un nouveau projet, UMAP est généralement le meilleur choix. Mais si vous travaillez avec la littérature bioinformatique ou si vous avez besoin de reproduire des résultats existants, t-SNE reste pertinent. Dans tous les cas, maîtriser ses pièges est indispensable pour tout data scientist.


Questions fréquentes sur t-SNE

Quelle perplexité choisir pour t-SNE ?

La perplexité recommandée varie entre 5 et 50, avec 30 comme valeur par défaut. Pour les petits datasets ( 10 000), augmentez à 50-100. La règle la plus importante : ne vous fiez jamais à une seule valeur. Testez toujours au minimum 3 perplexités (par exemple 10, 30, 50) et comparez les visualisations. Les patterns stables à travers différentes perplexités sont fiables.

Peut-on utiliser t-SNE pour le clustering ?

Non, t-SNE est un outil de visualisation, pas de clustering. Les distances dans l’espace t-SNE ne sont pas fiables et les tailles de clusters sont déformées. Si vous voulez des clusters, utilisez d’abord un algorithme de clustering (K-Means, DBSCAN) sur les données originales (ou après PCA), puis visualisez les labels obtenus sur un plot t-SNE. T-SNE sert à voir la structure, pas à la quantifier.

Pourquoi t-SNE est-il si lent ?

L’algorithme exact a une complexité O(n²) car il compare toutes les paires de points. L’approximation Barnes-Hut (défaut dans scikit-learn) réduit à O(n log n), mais ça reste lent sur les grands datasets. Solutions : réduisez d’abord avec PCA (50 composantes), sous-échantillonnez si nécessaire, ou passez à UMAP qui est nettement plus rapide. Pour les très grands datasets (> 100 000 points), openTSNE ou FIt-SNE offrent de meilleures performances que scikit-learn.

Pourquoi t-SNE donne des résultats différents à chaque exécution ?

L’optimisation de t-SNE est non convexe : il existe plusieurs minima locaux, et l’algorithme converge vers l’un d’eux selon l’initialisation aléatoire. Deux exécutions produisent des embeddings visuellement différents (positions, orientations) même si la structure des clusters est similaire. Fixez random_state pour la reproductibilité dans vos analyses. Depuis scikit-learn 1.2, l’initialisation par PCA (init='pca') réduit significativement cette variabilité.

UMAP a-t-il remplacé t-SNE ?

En grande partie, oui. UMAP est plus rapide, préserve mieux la structure globale, supporte la transformation de nouvelles données, et peut servir de prétraitement ML. t-SNE reste pertinent dans les domaines où il est le standard historique (bioinformatique single-cell) et pour reproduire des résultats de la littérature. Pour un nouveau projet sans contrainte historique, UMAP est le choix par défaut.

Polydesk.ai — Footer