Régression PLS : Guide Complet — Principes, Exemples et Implémentation Python
Résumé — La régression PLS (Partial Least Squares Regression) est une méthode de modélisation supervisée qui projette les variables prédictives et la cible sur des composantes latentes en maximisant leur covariance. Particulièrement efficace face à la multicolinéarité et aux situations où le nombre de variables dépasse celui des observations, la régression PLS s’impose comme un outil incontournable en chimiométrie, en bio-informatique et en prévision économique.
Principe mathématique
La régression PLS modélise la relation entre une matrice de prédicteurs X ∈ ℝ^(n×p) et un vecteur cible y ∈ ℝ^n à travers des composantes latentes.
Décomposition PLS
Modèle :
– X = TWᵀ + E — décomposition des prédicteurs
– y = Tq + f — décomposition de la cible
T (scores), W (poids), q (chargements de y), E et f (résidus).
Maximisation de la covariance
Contrairement à la PCA qui maximise uniquement la variance de X, la régression PLS maximise la covariance entre t = Xw et y :
w₁ = argmax_w Cov(Xw, y) s.c. ‖w‖ = 1
Algorithme NIPALS
- u = y
- w = Xᵀu / ‖Xᵀu‖
- t = Xw
- q = yᵀt / (tᵀt)
- u = yq / ‖q‖
- Répéter 2-5 jusqu’à convergence
- Déflater X ← X − tpᵀ où p = Xᵀt/(tᵀt), y ← y − tq
Coefficients finaux : β_pls = W(TᵀT)⁻¹Tᵀy, donc ŷ = Xβ_pls.
Intuition
Imaginez prédire la qualité d’un vin à partir de 150 mesures spectrales. L’absorbance à 520 nm est presque identique à celle à 521 nm : multicolinéarité extrême. La régression linéaire classique échoue.
La régression PLS construit quelques composantes latentes qui résument X tout en restant corrélées avec y.
PCA vs PLS :
| Méthode | Critère | Supervisée ? |
|---|---|---|
| PCA | Variance de X | Non |
| Régression PLS | Covariance (X, y) | Oui |
La PLS est une PCA supervisée. Idéale quand p > n ou face à la multicolinéarité.
Implémentation Python
Environnement
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cross_decomposition import PLSRegression
from sklearn.linear_model import LinearRegression
from sklearn.decomposition import PCA
from sklearn.model_selection import cross_val_score, KFold, cross_val_predict
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, r2_score
import warnings
warnings.filterwarnings('ignore')
np.random.seed(42)
Données multicolinéaires
n = 100; p = 50
Z = np.random.randn(n, 3) # variables latentes
A = np.random.randn(3, p)
X = Z @ A + 0.5 * np.random.randn(n, p)
y = Z @ [2.0, -1.5, 3.0] + 0.3 * np.random.randn(n)
Validation croisée
scaler_x = StandardScaler()
scaler_y = StandardScaler()
Xs = scaler_x.fit_transform(X)
ys = scaler_y.fit_transform(y.reshape(-1,1)).ravel()
scores = []
kf = KFold(n_splits=5, shuffle=True, random_state=42)
for k in range(1, min(n,p)+1):
pls = PLSRegression(n_components=k)
s = cross_val_score(pls, Xs, ys, cv=kf, scoring='neg_mean_squared_error')
scores.append(-s.mean())
opt_k = np.argmin(scores) + 1
print(f"Composantes optimales : {opt_k}")
PLS vs PCA+LR
pls = PLSRegression(n_components=opt_k)
pls.fit(Xs, ys)
yp = pls.predict(Xs)
pca = PCA(n_components=opt_k)
Xp = pca.fit_transform(Xs)
lr = LinearRegression().fit(Xp, ys)
yp2 = lr.predict(Xp)
r2_pls = r2_score(ys, yp)
r2_pca = r2_score(ys, yp2)
print(f'Amélioration PLS')
Poids des variables
wts = pls.x_weights_[:, 0]
top10 = np.argsort(np.abs(wts))[::-1][:10]
for i in top10:
print(f" Var {i}: {wts[i]:.4f}")
Variance expliquée
var_cum = []
for k in range(1, 21):
m = PLSRegression(n_components=k).fit(Xs, ys)
var_cum.append(r2_score(ys, m.predict(Xs)))
plt.plot(range(1,21), var_cum, "go-")
plt.xlabel('Composantes'); plt.ylabel('R² cumule'); plt.show()
Hyperparamètres
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
n_components |
int | 2 | Nombre de composantes latentes. L’hyperparamètre clé — choisir par validation croisée. |
scale |
bool | True | Standardise X et y automatiquement. Recommandé par défaut. |
max_iter |
int | 500 | Itérations max de NIPALS par composante. |
tol |
float | 1e-6 | Tolérance de convergence NIPALS. |
copy |
bool | True | Copier les données d’entrée (mémoire vs sécurité). |
Choisir n_components : règle du 1-SE
mse = []
for k in range(1, 31):
yp_cv = cross_val_predict(PLSRegression(n_components=k), Xs, ys, cv=10)
mse.append(mean_squared_error(ys, yp_cv))
best = np.argmin(mse)
opt = int(np.where(np.array(mse) <= mse[best] + np.std(mse))[0][0]) + 1
Avantages et Limites
Avantages
- Multicolinéarité : la régression PLS gère les corrélations fortes entre prédicteurs sans divergence des coefficients.
- p > n : fonctionne même quand les variables dépassent les observations.
- Supervisée : oriente les composantes vers la prédiction de y, pas juste la variance de X.
- Filtre le bruit : le bruit de X sans lien avec y est ignoré.
- Multi-réponse : PLS2 gère Y multi-dimensionnel.
- Interprétable : les poids et scores VIP identifient les variables clés.
Limites
- Composantes mixtes : combinaisons linéaires de toutes les variables, difficilement interprétables physiquement.
- Sensible à n_components : un mauvais choix cause surajustement ou sous-ajustement.
- Non sélectif : utilise toutes les variables (sPLS sparse n’est pas dans scikit-learn).
- Linéaire : Kernel PLS nécessaire pour les non-linéarités.
- Outliers : sensible aux valeurs aberrantes comme la régression linéaire.
- Pas probabiliste : pas d’intervalles de confiance analytiques, pas de tests statistiques.
Cas d’usage
1. Spectroscopie et chimiométrie
Domaine historique de la régression PLS. En spectroscopie NIR, on mesure l’absorbance à des centaines de longueurs d’onde fortement corrélées. Prédire la concentration en protéines ou humidité d’un échantillon alimentaire est l’application typique.
pls = PLSRegression(n_components=8)
pls.fit(X_spectres, y_concentration)
y_pred = pls.predict(X_nouveaux)
Les scores VIP identifient les longueurs d’onde les plus informatives.
2. Données omiques p >> n
En génomique ou métabolomique, des milliers de gènes pour quelques dizaines de patients. La régression PLS exploite la structure de corrélation biologique entre gènes co-exprimés, créant des composantes pertinentes pour le phénotype cible.
3. Prévision économique
Combiner 150 indicateurs macroéconomiques corrélés pour prévoir le PIB trimestriel. La PLS sélectionne les dimensions prédictives de l’activité économique, sans perdre de temps sur les facteurs sans lien avec le PIB.
4. Données de capteurs
Réseaux industriels de capteurs (température, pression, vibrations, débit) fortement corrélés. Prédire l’efficacité énergétique d’un système HVAC à partir de 50 capteurs intercorrélés.
from sklearn.model_selection import train_test_split
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.2, random_state=42)
scaler = StandardScaler()
Xtr_s = scaler.fit_transform(Xtr)
Xte_s = scaler.transform(Xte)
pls = PLSRegression(n_components=5).fit(Xtr_s, ytr)
print(f"R² test : {r2_score(yte, pls.predict(Xte_s)):.4f}")
Voir aussi
- Maîtriser les Duodigits en Python : Guide Complet pour Optimiser vos Calculs Numériques
- Maîtriser les Permutations de Projet avec Python : Guide Complet pour Développeurs
Pour aller plus loin
- Wold, Sjöström & Eriksson (2001) — PLS-regression: a basic tool of chemometrics, Chemometrics and Intelligent Laboratory Systems, 58(2), 109-130.
- Hervé Abdi (2010) — Partial Least Squares Regression and Projection on Latent Structure, Computational Statistics, 2(1), 97-106.
- Documentation scikit-learn — cross_decomposition.PLSRegression

