PCA (Principal Component Analysis / Analyse en Composantes Principales)
La PCA (Principal Component Analysis) est une technique de réduction de dimensionnalité linéaire qui identifie les axes (composantes principales) capturant le maximum de variance dans les données, puis projette les données sur ces axes pour produire une représentation de dimension inférieure.
C’est l’algorithme de réduction de dimensionnalité le plus utilisé en machine learning et en statistiques. Rapide, interprétable et mathématiquement élégante, la PCA transforme un ensemble de variables potentiellement corrélées en un ensemble réduit de variables non corrélées (les composantes principales), ordonnées par quantité de variance capturée. La première composante capture le plus de variance, la deuxième capture le maximum de variance restante orthogonalement à la première, et ainsi de suite.
- Nom complet
- Principal Component Analysis (Analyse en Composantes Principales)
- Type
- Réduction de dimensionnalité linéaire, non supervisée
- Objectif
- Trouver les directions de variance maximale dans les données
- Entrée
- Matrice n × d (n observations, d features)
- Sortie
- Matrice n × k (k composantes principales, k ≤ d)
- Prérequis
- Standardisation des données (obligatoire)
- Calcul Python
sklearn.decomposition.PCA- Complexité
- O(n · d²) pour la version exacte
L’intuition derrière la PCA
Imaginez un nuage de points dans un espace à 3 dimensions. Ce nuage n’est pas sphérique : il est étiré dans une direction, modérément étalé dans une deuxième, et presque plat dans la troisième. La PCA identifie ces trois directions et les classe par importance (quantité d’étirement).
La première composante principale (PC1) est la direction le long de laquelle les données sont le plus étalées (variance maximale). La deuxième (PC2) est la direction de variance maximale parmi toutes les directions perpendiculaires à PC1. La troisième (PC3) capture la variance restante.
Si PC1 et PC2 capturent ensemble 95 % de la variance totale, vous pouvez projeter vos données sur ces deux axes et ne perdre que 5 % de l’information. Vous avez réduit 3 dimensions à 2, en préservant l’essentiel de la structure.
Le même raisonnement s’applique de 1 000 dimensions à 50 : si 50 composantes capturent 95 % de la variance, les 950 dimensions restantes ne portent que 5 % d’information (principalement du bruit).
Les mathématiques de la PCA (version accessible)
Étape 1 : Standardisation
Les features doivent avoir une moyenne de 0 et un écart-type de 1. Sans cela, une feature exprimée en milliers (comme un revenu) dominera les composantes principales par rapport à une feature en unités (comme un âge). La PCA est fondamentalement sensible à l’échelle.
Étape 2 : Matrice de covariance
La PCA calcule la matrice de covariance des données standardisées. Cette matrice (d × d) décrit comment chaque paire de features varie conjointement. Les éléments diagonaux sont les variances individuelles (toutes égales à 1 après standardisation). Les éléments hors diagonale sont les covariances.
Étape 3 : Décomposition en valeurs propres
La matrice de covariance est décomposée en vecteurs propres (eigenvectors) et valeurs propres (eigenvalues). Chaque vecteur propre définit la direction d’une composante principale. Sa valeur propre associée mesure la quantité de variance capturée dans cette direction. Les vecteurs propres sont orthogonaux entre eux.
Étape 4 : Sélection et projection
On trie les vecteurs propres par valeur propre décroissante, on sélectionne les K premiers, et on projette les données sur ces K axes. Le résultat est un nouveau dataset de dimension K, où chaque colonne est une composante principale non corrélée avec les autres.
PCA en Python avec scikit-learn
Usage de base
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris
import numpy as np
# Charger les données
X, y = load_iris(return_X_y=True)
# Standardiser (obligatoire avant PCA)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# PCA avec 2 composantes
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)
print(f"Shape originale : {X.shape}") # (150, 4)
print(f"Shape réduite : {X_pca.shape}") # (150, 2)
print(f"Variance PC1 : {pca.explained_variance_ratio_[0]:.2%}")
print(f"Variance PC2 : {pca.explained_variance_ratio_[1]:.2%}")
print(f"Variance totale : {pca.explained_variance_ratio_.sum():.2%}")
Sur le dataset Iris (4 features), la PCA avec 2 composantes capture environ 96 % de la variance totale. PC1 seule en capture environ 73 % et PC2 environ 23 %.
Sélection automatique par variance cible
Scikit-learn permet de spécifier un seuil de variance à conserver, et détermine automatiquement le nombre de composantes nécessaire :
# Garder 95% de la variance
pca_95 = PCA(n_components=0.95)
X_reduced = pca_95.fit_transform(X_scaled)
print(f"Composantes retenues : {pca_95.n_components_}")
print(f"Variance conservée : {pca_95.explained_variance_ratio_.sum():.2%}")
Le scree plot (graphique de variance expliquée)
Le scree plot est l’outil visuel principal pour choisir le nombre de composantes. Il affiche la variance expliquée par chaque composante et/ou la variance cumulée :
import matplotlib.pyplot as plt
# PCA complète pour voir toutes les composantes
pca_full = PCA()
pca_full.fit(X_scaled)
# Variance par composante et cumulative
var_ratio = pca_full.explained_variance_ratio_
cum_var = np.cumsum(var_ratio)
fig, ax = plt.subplots(figsize=(8, 5))
ax.bar(range(1, len(var_ratio)+1), var_ratio,
alpha=0.6, color='#7c3aed', label='Par composante')
ax.step(range(1, len(cum_var)+1), cum_var,
where='mid', color='#f97316', lw=2, label='Cumulée')
ax.axhline(y=0.95, color='gray', linestyle='--', label='Seuil 95%')
ax.set_xlabel('Composante principale')
ax.set_ylabel('Variance expliquée')
ax.set_title('Scree Plot')
ax.legend()
plt.tight_layout()
plt.show()
Le « coude » du scree plot (point où la courbe cumulée s’aplatit) indique le nombre de composantes à conserver. Si la courbe atteint 95 % à la 3ᵉ composante, 3 composantes suffisent.
Le cercle de corrélation (loadings)
Le cercle de corrélation montre la contribution de chaque feature originale aux composantes principales. C’est l’outil d’interprétation principal de la PCA :
# Loadings : contributions des features aux composantes
loadings = pca.components_.T * np.sqrt(pca.explained_variance_)
fig, ax = plt.subplots(figsize=(7, 7))
feature_names = ['Sepal L', 'Sepal W', 'Petal L', 'Petal W']
for i, name in enumerate(feature_names):
ax.arrow(0, 0, loadings[i, 0], loadings[i, 1],
head_width=0.03, color='#7c3aed', alpha=0.8)
ax.text(loadings[i, 0]*1.1, loadings[i, 1]*1.1, name)
circle = plt.Circle((0, 0), 1, fill=False, color='gray', ls='--')
ax.add_patch(circle)
ax.set_xlim(-1.2, 1.2)
ax.set_ylim(-1.2, 1.2)
ax.set_xlabel('PC1')
ax.set_ylabel('PC2')
ax.set_title('Cercle de corrélation')
ax.set_aspect('equal')
plt.grid(alpha=0.3)
plt.show()
Les flèches proches du cercle unitaire contribuent fortement aux composantes. Les flèches dans la même direction sont corrélées positivement, celles en directions opposées sont corrélées négativement.
Méthodes pour choisir le nombre de composantes
| Méthode | Principe | Quand l’utiliser |
|---|---|---|
| Seuil de variance (90-95 %) | Garder assez de composantes pour expliquer X % de la variance | Usage général, le plus courant |
| Scree plot (coude) | Trouver le point d’inflexion de la courbe de variance | Exploration visuelle |
| Critère de Kaiser | Garder les composantes avec une valeur propre > 1 | Données standardisées (variance moyenne = 1) |
| MLE de Minka | Estimation bayésienne du nombre de composantes | PCA(n_components='mle') dans scikit-learn |
| Validation croisée | Tester l’impact sur un modèle supervisé en aval | Quand la PCA est un prétraitement |
Cas d’usage de la PCA
Prétraitement avant ML supervisé
Réduire la dimensionnalité avant d’entraîner un classifieur ou un régresseur élimine le bruit, réduit l’overfitting et accélère l’entraînement. Exemple : passer de 1 000 features à 100 composantes principales avant un XGBoost.
Visualisation en 2D
Projeter des données de haute dimension sur PC1 et PC2 pour une visualisation rapide. Moins sophistiquée que t-SNE ou UMAP pour révéler des clusters non linéaires, mais beaucoup plus rapide et interprétable.
Débruitage
Les premières composantes capturent le signal, les dernières capturent le bruit. En reconstruisant les données à partir des seules premières composantes (via pca.inverse_transform()), vous obtenez une version débruitée. Utilisé en traitement d’images et de signaux.
Traitement de la multicolinéarité
Quand des features sont fortement corrélées, les modèles linéaires (régression) deviennent instables. La PCA produit des composantes non corrélées par construction, éliminant le problème de multicolinéarité.
Compression d’images (Eigenfaces)
L’application historique : représenter des visages comme combinaisons de « eigenfaces » (composantes principales du dataset de visages). Avec 50 à 100 composantes au lieu de milliers de pixels, on reconstruit des visages reconnaissables. Le même principe s’applique à toute compression d’images.
Bioinformatique
La PCA est le premier outil utilisé en génomique pour visualiser la structure de populations (différences génétiques entre groupes), et en transcriptomique pour réduire les données d’expression génique (20 000+ gènes) avant le clustering.
Variantes de la PCA
Incremental PCA
Pour les datasets trop gros pour tenir en mémoire. Traite les données par mini-batches : sklearn.decomposition.IncrementalPCA.
Sparse PCA
Produit des composantes avec des coefficients nuls (sparse), améliorant l’interprétabilité. Utile quand vous voulez identifier quelles features contribuent à chaque composante : sklearn.decomposition.SparsePCA.
Kernel PCA
Applique un kernel trick (comme les SVM) pour capturer des relations non linéaires. Projette les données dans un espace de haute dimension via un kernel (RBF, polynomial), puis applique la PCA dans cet espace. Plus puissant que la PCA linéaire mais plus lent et avec des hyperparamètres à régler.
Randomized PCA
Approximation rapide de la PCA utilisant des projections aléatoires. Très efficace sur les grands datasets quand on ne veut garder que quelques composantes. C’est le solver par défaut de scikit-learn quand les conditions s’y prêtent (svd_solver='randomized').
Limites et pièges de la PCA
Limite n°1 : hypothèse de linéarité
La PCA ne capture que les relations linéaires. Si la structure des données est une spirale, un cercle ou toute forme non linéaire, la PCA produira un résultat médiocre. Pour les structures non linéaires, utilisez UMAP, t-SNE, Kernel PCA ou des autoencodeurs.
Limite n°2 : sensibilité à l’échelle
Ne pas standardiser avant la PCA est l’erreur la plus fréquente. Sans standardisation, les composantes principales sont dominées par les features à grande échelle, indépendamment de leur utilité.
Limite n°3 : sensibilité aux outliers
Les outliers tirent les composantes principales vers eux car la PCA maximise la variance (et les outliers créent de la variance). Sur des données avec des valeurs extrêmes, envisagez une Robust PCA ou un prétraitement des outliers.
Limite n°4 : interprétabilité réduite
Les composantes principales sont des combinaisons linéaires de toutes les features originales. « PC1 » ne correspond à aucune variable métier. Pour retrouver l’interprétabilité, examinez les loadings (contributions) ou utilisez Sparse PCA.
Verdict
La PCA est le couteau suisse de la réduction de dimensionnalité. Elle n’est pas la plus puissante (elle rate les structures non linéaires), ni la plus spectaculaire en visualisation (UMAP/t-SNE produisent des plots plus jolis), mais elle est la plus polyvalente. Rapide, déterministe, interprétable, avec transformation inverse, elle est incontournable dans tout pipeline ML.
En pratique, commencez toujours par une PCA exploratoire sur vos données de haute dimension. Le scree plot vous dit combien de dimensions portent réellement l’information. Le cercle de corrélation vous dit quelles features comptent. Et si la PCA à 2D ne montre pas de clusters nets, c’est le signal pour passer à UMAP.
Questions fréquentes sur la PCA
Faut-il standardiser les données avant la PCA ?
Oui, presque toujours. La PCA maximise la variance, donc les features à grande échelle dominent les composantes principales si elles ne sont pas standardisées. Utilisez StandardScaler() (moyenne 0, écart-type 1) avant d’appliquer la PCA. L’exception unique : si toutes vos features sont déjà dans la même unité et la même échelle (par exemple, des intensités de pixels toutes entre 0 et 255), la standardisation est optionnelle.
Combien de composantes principales faut-il garder ?
La règle la plus courante est de conserver assez de composantes pour expliquer 90 à 95 % de la variance totale. Utilisez PCA(n_components=0.95) dans scikit-learn pour automatiser ce choix. Le scree plot aide visuellement : cherchez le « coude » après lequel les composantes supplémentaires n’apportent plus de variance significative. Si la PCA alimente un modèle supervisé en aval, testez plusieurs valeurs de K par validation croisée et choisissez celle qui maximise la performance du modèle.
Quelle est la différence entre PCA et t-SNE ?
La PCA est linéaire, rapide, interprétable et préserve la structure globale (variance). t-SNE est non linéaire, lent, non interprétable mais excelle à révéler les clusters locaux en 2D. Utilisez la PCA pour le prétraitement ML, la compression et l’analyse de variance. Utilisez t-SNE (ou mieux, UMAP) pour la visualisation exploratoire de structures complexes. En pratique, les deux se combinent souvent : PCA d’abord (50-100 composantes) puis UMAP (2D).
La PCA peut-elle être utilisée pour la classification ?
La PCA elle-même ne fait pas de classification : c’est un outil de transformation des features. Mais elle est très couramment utilisée comme étape de prétraitement avant un classifieur. En réduisant les dimensions, elle peut améliorer les performances (moins d’overfitting, entraînement plus rapide) et résoudre les problèmes de multicolinéarité. Si vous voulez une réduction supervisée (qui tient compte des labels), utilisez plutôt la LDA (Linear Discriminant Analysis).
La PCA fonctionne-t-elle avec des données textuelles ?
Pas directement sur du texte brut, mais sur des représentations numériques du texte. Après avoir transformé les documents en vecteurs TF-IDF ou en embeddings, la PCA (ou sa variante SVD tronquée pour les matrices creuses) réduit la dimensionnalité. La SVD tronquée appliquée à une matrice TF-IDF est connue sous le nom de LSA (Latent Semantic Analysis), une technique fondatrice du NLP. Pour les embeddings denses (768+ dimensions issus de BERT ou Sentence Transformers), la PCA réduit efficacement à 50-100 dimensions avant le clustering ou la recherche de similarité.