t-SNE : Guide Complet — Principes, Exemples et Implémentation Python

t-SNE : Guide Complet — Principes, Exemples et Implémentation Python

t-SNE : Guide complet — Principes, Exemples et Implémentation Python

Résumé

t-SNE (t-Distributed Stochastic Neighbor Embedding) est un algorithme de réduction de dimensionalité non linéaire conçu spécifiquement pour la visualisation de données haute dimension. Contrairement à l’ACP qui préserve les distances globales, t-SNE cherche à conserver la structure locale du voisinage : les points proches dans l’espace original restent proches après projection en 2D ou 3D. Cette propriété en fait l’outil de référence pour explorer des ensembles de données complexes tels que des images, des textes embarqués ou des profils génomiques.

Principe mathématique

Le fonctionnement de t-SNE repose sur une séquence élégante de transformations probabilistes.

Étape 1 : Similarités gaussiennes en haute dimension

Pour chaque point de donnée $x_i$, t-SNE définit une distribution gaussienne centrée sur ce point. La probabilité conditionnelle $p_{j|i}$ que le point $x_j$ soit considéré comme un voisin de $x_i$ est donnée par :

$$p_{j|i} = \frac{\exp(-|x_i – x_j|^2 / 2\sigma_i^2)}{\sum_{k \neq i} \exp(-|x_i – x_k|^2 / 2\sigma_i^2)}$$

où $\sigma_i$ est la variance (ou largeur) de la gaussienne centrée sur $x_i$. Ce paramètre n’est pas fixé arbitrairement : il est déterminé automatiquement pour correspondre à la perplexité souhaitée par l’utilisateur.

La perplexité se définit comme :

$$\text{Perp}(P_i) = 2^{H(P_i)}$$

où $H(P_i)$ est l’entropie de Shannon de la distribution $P_i = {p_{j|i}}_j$. Une perplexité de 30 signifie que chaque point considère environ 30 voisins significatifs. C’est un moyen intuitif de contrôler la taille du voisinage local sans préciser explicitement le nombre de voisins.

Ensuite, on symétrise ces probabilités pour obtenir la distribution conjointe :

$$p_{ij} = \frac{p_{j|i} + p_{i|j}}{2N}$$

Étape 2 : Similarités de Student en basse dimension

Dans l’espace de plongement (généralement 2D ou 3D), on définit une distribution analogue $q_{ij}$ entre les points projetés $y_i$ et $y_j$. La différence fondamentale est que t-SNE utilise une distribution de Student à un degré de liberté (également appelée distribution de Cauchy) plutôt qu’une gaussienne :

$$q_{ij} = \frac{(1 + |y_i – y_j|^2)^{-1}}{\sum_{k \neq l} (1 + |y_k – y_l|^2)^{-1}}$$

Ce choix n’est pas anodin. La queue plus lourde de la distribution de Student permet de modéliser le fait que, dans l’espace de basse dimension, les points distants deviennent beaucoup plus nombreux (la densité diminue considérablement). Sans cela, les clusters auraient tendance à se compresser au centre de la visualisation — c’est le fameux problème de crowding (surpopulation).

Étape 3 : Minimisation de la divergence de Kullback-Leibler

L’objectif de t-SNE est de trouver les positions ${y_i}$ telles que la distribution $Q$ soit aussi proche que possible de la distribution $P$. La mesure de dissimilarité utilisée est la divergence de Kullback-Leibler (KL) :

$$KL(P | Q) = \sum_{i \neq j} p_{ij} \log \frac{p_{ij}}{q_{ij}}$$

Cette divergence est minimisée par descente de gradient. Le gradient par rapport à chaque point $y_i$ s’écrit :

$$\frac{\partial KL}{\partial y_i} = 4 \sum_{j \neq i} (p_{ij} – q_{ij}) (y_i – y_j) (1 + |y_i – y_j|^2)^{-1}$$

Ce terme est remarquablement interprétable : il s’agit d’une somme de forces d’attraction (quand $p_{ij} > q_{ij}$) et de répulsion (quand $p_{ij} < q_{ij}$). Les points qui sont proches en haute dimension mais éloignés en basse dimension sont attirés l’un vers l’autre, et inversement.

Intuition : aplatir un globe terrestre

Imaginez que vous devez créer une carte plane du monde à partir d’un globe. Vous voulez que les pays voisins restent voisins sur la carte : la France doit rester proche de l’Allemagne, le Brésil proche de l’Argentine. En revanche, il est acceptable — et même inévitable — que les distances entre continents soient déformées. Le Pacifique peut apparaître plus grand qu’il ne l’est, l’Europe plus resserrée.

C’est exactement la philosophée de t-SNE : préserver le voisinage local au détriment des distances globales. Si deux images de chiens se ressemblent, t-SNE les placera côte à côte sur la carte 2D. En revanche, la distance exacte entre le cluster des chiens et celui des chats n’a pas de signification forte : elle pourrait varier d’une exécution à l’autre.

Cette propriété est à la fois la force et la faiblesse de l’algorithme. Pour l’exploration visuelle de structures locales, c’est idéal. Pour comparer des clusters entre eux, il faut rester prudent.

Implémentation Python avec scikit-learn

Exemple de base sur les chiffres manuscrits

Le jeu de données load_digits de scikit-learn contient 1 797 images de chiffres manuscrits (8×8 pixels), soit des vecteurs de 64 dimensions. C’est un excellent point de départ pour visualiser t-SNE :

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

# Charger les données
digits = load_digits()
X, y = digits.data, digits.target

# Appliquer t-SNE
tsne = TSNE(n_components=2, perplexity=30, random_state=42)
X_embedded = tsne.fit_transform(X)

# Visualiser
fig, ax = plt.subplots(figsize=(10, 8))
scatter = ax.scatter(X_embedded[:, 0], X_embedded[:, 1], c=y, cmap="tab10", s=30, alpha=0.8)
ax.set_title("t-SNE des chiffres manuscrits (2D)")
plt.colorbar(scatter, label="Chiffre", ticks=range(10))
plt.tight_layout()
plt.show()

Le résultat montre généralement 10 clusters bien séparés, chacun correspondant à un chiffre. Les transitions floues entre certains clusters (par exemple entre les 4 et les 9) reflètent la similarité visuelle réelle entre ces chiffres.

Impact de la perplexété

La perplexété est l’hyperparamètre le plus important. Explorons son effet :

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

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

plt.tight_layout()
plt.show()

Avec une perplexité faible (5), t-SNE capture des structures très locales mais risque de fragmenter les clusters en multiples îlots. Avec une perplexité élevée (100), la vision devient plus globale et les clusters peuvent se fusionner. La valeur par défaut de 30 constitue un bon compromis pour des données de taille moyenne.

Comparaison avec l’ACP

Il est instructif de comparer t-SNE avec l’Analyse en Composantes Principales (ACP) sur le même jeu de données :

from sklearn.decomposition import PCA

# ACP
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

# t-SNE
tsne = TSNE(n_components=2, perplexity=30, random_state=42)
X_tsne = tsne.fit_transform(X)

fig, axes = plt.subplots(1, 2, figsize=(14, 5))
axes[0].scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap="tab10", s=20, alpha=0.7)
axes[0].set_title("ACP (linéaire)")
axes[1].scatter(X_tsne[:, 0], X_tsne[:, 1], c=y, cmap="tab10", s=20, alpha=0.7)
axes[1].set_title("t-SNE (non linéaire)")
for ax in axes:
    ax.set_xticks([])
    ax.set_yticks([])
plt.tight_layout()
plt.show()

L’ACP, étant linéaire, ne sépare pas toujours aussi bien les clusters. t-SNE révèle des structures non linéaires que l’ACP ne peut pas capturer. Cependant, l’ACP conserve les distances globales et est beaucoup plus rapide.

Animation des itérations

Pour comprendre comment t-SNE converge, on peut visualiser l’évolution de la carte au fil des itérations :

import matplotlib.animation as animation
from sklearn.manifold import TSNE
from sklearn.datasets import load_digits

digits = load_digits()
X, y = digits.data, digits.target

# Récupérer les états intermédiaires via le callback
states = []

def callback(Xi, i):
    states.append(Xi.copy())

tsne = TSNE(n_components=2, perplexity=30, n_iter=500,
            random_state=42, callback=callback, callback_every=50)
tsne.fit_transform(X)

# Animer
fig, ax = plt.subplots(figsize=(8, 6))
scat = ax.scatter(states[0][:, 0], states[0][:, 1], c=y, cmap="tab10", s=15)
ax.set_xticks([])
ax.set_yticks([])
titre = ax.set_title("Itération 0")

def update(frame):
    scat.set_offsets(states[frame])
    titre.set_text(f"Itération {frame * 50}")
    return scat, titre

ani = animation.FuncAnimation(fig, update, frames=len(states), interval=400)
ani.save("tsne_animation.gif", writer="pillow")
plt.show()

On observe typiquement une phase initiale de early exaggeration où les clusters se forment rapidement, suivie d’un affinage progressif des positions.

Hyperparamètres de t-SNE

La maîtrise de t-SNE passe par la compréhension de ses hyperparamètres :

Hyperparamètre Valeur par défaut Rôle
n_components 2 Dimension de l’espace de sortie (2 pour une visualisation, 3 pour un rendu en trois axes)
perplexity 30 Taille effective du voisinage local. Valeurs typiques : 5 à 50. Doit être inférieure au nombre d’échantillons
early_exaggeration 12.0 Amplifie les attractions au début pour créer des clusters bien séparés. Augmenter cette valeur produit des clusters plus denses mais le temps de calcul augmente
learning_rate “auto” Taux d’apprentissage. “auto” ajuste automatiquement en fonction du nombre d’échantillons. Un taux trop faible donne des cartes compressées ; trop élevé, des artefacts en forme de boule
n_iter 1000 Nombre d’itérations de descente de gradient. Minimum 250. Pour des visualisations de haute qualité, 2 000 à 5 000 itérations sont recommandées
metric “euclidean” Métrique de distance pour l’espace original. Peut être “cosine”, “manhattan”, “chebyshev”, etc.
init “pca” Initialisation des points. “pca” (recommandé) utilise une ACP préalable pour une convergence plus stable. “random” peut piéger l’algorithme dans des minima locaux
method “exact” “exact” pour les petits jeux de données, “barnes_hut” (approche approximative) pour accélérer sur des grands jeux

Avantages et limites

Avantages

  • Séparation exceptionnelle des clusters : t-SNE excelle à révéler des structures locales que les méthodes linéaires comme l’ACP ne détectent pas.
  • Robustesse aux non-linéarités : comme t-SNE ne suppose aucune structure linéaire sous-jacente, il s’applique à des données très complexes.
  • Invariance d’échelle relative : l’algorithme se concentre sur les proximités relatives plutôt que sur les distances absolues, ce qui le rend moins sensible à la normalisation.
  • Large adoption : visualiser des embeddings avec t-SNE est devenu une pratique standard en recherche et en industrie.

Limites

  • Non-déterminisme : même avec les mêmes données, des exécutions différentes (sauf random_state fixé) produisent des cartes différentes. La forme globale peut varier.
  • Interprétation des distances globales : la distance entre deux clusters n’est pas significative. On ne peut pas conclure que le cluster A est deux fois plus éloigné de B que de C.
  • Densité et taille des clusters : la taille apparente d’un cluster ne reflète pas nécessairement la densité réelle des données.
  • Coût computationnel : en mode exact, la complexité est quadratique, ce qui limite l’application aux jeux de données de taille modérée. L’approximation Barnes-Hut aide mais reste coûteuse au-delà de quelques centaines de milliers de points.
  • Absence de fonction de transformation : contrairement à l’ACP, t-SNE ne fournit pas de fonction permettant de projeter de nouvelles données. Chaque exécution est indépendante.

Quatre cas d’usage concrets

1. Exploration de données génomiques

En bioinformatique, t-SNE est utilisé pour visualiser des profils d’expression génique de milliers de gènes. Chaque échantillon devient un point dans un espace de plusieurs milliers de dimensions, et t-SNE révèle des sous-types cellulaires invisibles à l’œil nu. Des clusters serrés correspondent souvent à des types cellulaires distincts, tandis que des points isolés peuvent indiquer des cellules aberrantes ou des types rares.

2. Visualisation d’embeddings de langage naturel

Les modèles de traitement du langage naturel (comme BERT ou Word2Vec) produisent des représentations vectorielles de mots ou de documents en haute dimension. Projeter ces vecteurs avec t-SNE permet de vérifier la qualité des embeddings : les mots sémantiquement proches devraient apparaître dans le même voisinage. C’est un outil de diagnostic essentiel pour les praticiens du NLP.

3. Analyse d’images et transfert de style

Dans les réseaux de neurones convolutionnels, les activations des couches intermédiaires peuvent être réduites avec t-SNE pour comprendre ce que le réseau voit. On observe souvent que les premières couches captent des motifs simples (bords, textures) tandis que les couches profondes représentent des concepts plus abstraits (visages, objets). Cette analyse aide à déboguer les architectures et à identifier les biais du modèle.

4. Détection d’anomalies dans les données industrielles

En surveillance industrielle, on collecte des centaines de capteurs en temps réel. Projeter ces observations avec t-SNE révèle le fonctionnement normal comme un gros nuage dense, tandis que les états anormaux (pannes imminentes, défauts de production) apparaissent comme des points isolés en périphérie. Cette visualisation guide la mise en place de seuils d’alerte et facilite l’interprétation par les opérateurs.

Bonnes pratiques

  1. Toujours fixer random_state pour la reproductibilité.
  2. Exécuter plusieurs fois avec différentes graines pour vérifier la stabilité des clusters.
  3. Commencer par l’ACP pour réduire la dimension en-dessous de 50 avant d’appliquer t-SNE (surtout si les données originales ont des milliers de dimensions).
  4. Varier la perplexité pour examiner la robustesse de la structure détectée.
  5. Ne pas interpréter les distances entre clusters ni la taille relative des amas.
  6. Préserver les labels pour colorer les points et valider visuellement la cohérence des clusters.

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.