Machine Learning 2 — Régression
:::tip Notebook Kaggle Le code complet et exécutable de ce chapitre est sur Kaggle : Ouvrir →
Versions anglaise et chinoise disponibles depuis la page d'accueil. :::
Le cœur du cours commence ici. Nous attaquons la régression : prédire une valeur numérique à partir d'autres valeurs. Nous codons d'abord la régression linéaire à la main pour comprendre les rouages, puis nous passons à scikit-learn pour aller plus vite.
Pourquoi ce chapitre ?
La régression est la première grande famille de problèmes en ML. Vous y apprenez :
- la régression linéaire par moindres carrés et la descente de gradient ;
- les métriques pour évaluer une prédiction numérique ;
- le découpage train/test et la validation croisée ;
- la régression polynomiale et la régularisation Ridge ;
- les k-plus-proches-voisins et l'importance de la normalisation.
La régression linéaire
L'idée la plus simple : trouver une droite qui passe au plus près d'un nuage de points.
Nous voulons que la droite minimise les résidus — l'écart entre la valeur observée et la valeur prédite.
La méthode des moindres carrés
Nous choisissons et pour minimiser la somme des carrés des résidus :
Pourquoi le carré ? Deux raisons : ça pénalise plus fort les grosses erreurs, et ça donne une solution analytique propre.
La solution
En annulant les dérivées partielles, on tombe sur :
La droite passe toujours par le point moyen .
La descente de gradient
Quand on a beaucoup de variables (ou pour les modèles plus complexes que vous verrez plus tard), la solution analytique n'existe plus. On passe à la descente de gradient : ajuster progressivement les paramètres dans la direction qui fait baisser la loss.
où est le learning rate (taux d'apprentissage). Trop petit, l'apprentissage rampe ; trop grand, la loss diverge. Le bon choix se fait souvent par essai-erreur.
Trois variantes selon le nombre d'exemples utilisés à chaque mise à jour :
- Batch : tous les exemples à chaque étape. Précis mais lent sur gros datasets.
- SGD (Stochastic) : un seul exemple. Rapide mais bruité.
- Minibatch : un sous-ensemble (typiquement 32 ou 64). Le compromis utilisé en pratique.
Métriques d'évaluation
Une fois le modèle entraîné, comment savoir s'il prédit bien ? Plusieurs métriques :
| Métrique | Formule | Interprétation |
|---|---|---|
| MAE | $\frac{1}{n}\sum | y_i - \hat{y}_i |
| MSE | pénalise plus les grosses erreurs | |
| RMSE | comme MSE mais dans l'unité de | |
| MAPE | $\frac{1}{n}\sum | (y_i - \hat{y}_i)/y_i |
| R² | part de variance expliquée |
Le R² vaut 1 pour un modèle parfait, 0 pour un modèle qui ne fait pas mieux que prédire la moyenne, et peut être négatif pour un modèle pire que la moyenne.
:::warning MAE vs RMSE Si MAE et RMSE divergent fortement, c'est qu'il y a des outliers. RMSE explose à cause du carré, MAE encaisse mieux. :::
Train/test et validation croisée
Évaluer un modèle sur les données qui ont servi à l'entraîner, c'est comme noter un étudiant sur les annales qu'il a apprises par cœur. Toujours réserver une partie des données pour le test.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
Pour ne pas dépendre d'un seul tirage, la validation croisée en k plis entraîne fois sur des découpages différents et moyenne les scores :
from sklearn.model_selection import cross_val_score
scores = cross_val_score(model, X, y, cv=5, scoring='r2')
print(scores.mean(), scores.std())
Régression polynomiale et régularisation
Quand la relation n'est pas une droite, on ajoute des puissances de comme nouvelles variables :
Le modèle reste linéaire en ses coefficients, mais devient courbe. Plus le degré est élevé, plus le modèle peut s'ajuster aux données — y compris au bruit. C'est le surapprentissage (overfitting).
Ridge : pénaliser les gros coefficients
Pour empêcher les coefficients de partir dans tous les sens, on ajoute un terme de pénalité à la fonction de coût :
C'est la régression Ridge. Le paramètre contrôle la force de la régularisation : plus est grand, plus les coefficients sont contraints à rester petits.
from sklearn.linear_model import Ridge
model = Ridge(alpha=1.0)
Variantes proches : Lasso (pénalité en valeur absolue, fait de la sélection de variables), ElasticNet (combinaison Ridge + Lasso).
k plus proches voisins (k-NN)
Le k-NN regressor est une méthode très différente : pas de formule globale, on regarde les voisins les plus proches dans le jeu d'entraînement et on moyenne leurs valeurs cibles.
from sklearn.neighbors import KNeighborsRegressor
model = KNeighborsRegressor(n_neighbors=5)
Le choix de est un arbitrage : petit → modèle flexible mais sensible au bruit ; grand → prédictions plus lisses mais qui peuvent rater les détails.
Normalisation : indispensable pour le k-NN
Le k-NN repose entièrement sur des distances. Si une variable a une échelle 1000 fois plus grande qu'une autre, elle écrase tout dans le calcul de distance.
Solution : mettre toutes les variables sur la même échelle.
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
:::warning Le piège du data leakage
On ajuste le scaler uniquement sur le train (fit_transform), puis on applique au test (transform). Sinon, on fait fuiter de l'information du test dans la procédure d'entraînement.
:::
Pipeline scikit-learn
Pour éviter les erreurs et chaîner proprement plusieurs étapes :
from sklearn.pipeline import Pipeline
pipe = Pipeline([
('scaler', StandardScaler()),
('model', KNeighborsRegressor(n_neighbors=5)),
])
pipe.fit(X_train, y_train)
y_hat = pipe.predict(X_test)
Le Pipeline garantit que le scaler est ajusté uniquement sur le train, même en validation croisée.