Une méthode pour mesurer honnêtement la performance d'un modèle : on le teste sur des données qu'il n'a pas vues, plusieurs fois, en faisant tourner la partie mise de côté. On obtient une erreur moyenne et sa variabilité, au lieu d'un seul chiffre qui dépend du hasard du découpage. C'est le juge de paix pour choisir entre deux modèles.
Un professeur qui interrogerait ses élèves sur les exercices corrigés en classe mesurerait leur mémoire, pas leur niveau. Il fait 5 contrôles, chacun sur un chapitre que la classe n'a pas révisé ce jour-là, et fait la moyenne.
Les lignes sont réparties au hasard en k blocs de même taille, souvent 5 ou 10. En classification, on garde la même proportion de chaque classe dans chaque bloc (découpage stratifié).
À chaque tour, un bloc est mis de côté, le modèle apprend sur les autres puis est noté sur le bloc écarté. Chaque ligne sert une fois de test, et k - 1 fois d'entraînement.
La moyenne des k notes estime la performance sur des données nouvelles. Leur écart-type dit si l'écart entre deux modèles est réel ou dû au hasard du découpage.
Pour prévoir le CA d'un magasin à partir de sa surface, de son budget publicitaire, de ses concurrents et de sa zone, l'équipe hésite entre une régression linéaire et une Random Forest.
Sur le jeu d'exemple, en validation croisée à 10 blocs, la régression linéaire se trompe de 57 k€ en moyenne et la Random Forest de 75 k€. L'écart est bien supérieur à la variabilité entre blocs : le modèle simple gagne.
Notée sur les magasins qu'elle a appris, la Random Forest affiche 27 k€ d'erreur, presque trois fois moins qu'en validation croisée. C'est le piège classique : le modèle a mémorisé, pas appris.
Noms donnés pour Python (scikit-learn). En R, une boucle sur les blocs suffit, ou les packages rsample et mlr3 pour aller plus loin.
5 ou 10. Plus de blocs : chaque modèle apprend sur plus de données, mais le calcul est plus long. Répéter la validation croisée avec plusieurs découpages (RepeatedKFold) stabilise encore le résultat.
Stratifié pour une classe rare, groupé quand plusieurs lignes concernent le même client ou magasin, chronologique pour les séries temporelles.
Choisir la mesure qui a un sens métier : erreur absolue en euros, AUC pour un score, rappel pour la fraude. La validation croisée ne corrige pas une mauvaise métrique.
Mise à l'échelle, imputation et sélection de variables doivent être refaites dans chaque bloc. Dans scikit-learn, les mettre dans un Pipeline passé à cross_val_score.
# CA des magasins : validation croisée en R
library(randomForest)
magasins <- read.csv("magasins.csv")
magasins$zone <- factor(magasins$zone)
formule <- ca_k ~ surface_m2 + budget_pub_k + nb_concurrents + zone
# 10 blocs : chaque magasin sert 9 fois à l'entraînement et 1 fois au test
set.seed(42)
bloc <- sample(rep(1:10, length.out = nrow(magasins)))
erreur_lm <- erreur_rf <- numeric(10)
for (k in 1:10) {
train <- magasins[bloc != k, ]
test <- magasins[bloc == k, ]
erreur_lm[k] <- mean(abs(test$ca_k - predict(lm(formule, data = train), test)))
erreur_rf[k] <- mean(abs(test$ca_k - predict(randomForest(formule, data = train, ntree = 300), test)))
}
cat("Régression linéaire : erreur moyenne", round(mean(erreur_lm), 1), "k€, écart-type entre blocs", round(sd(erreur_lm), 1), "\n")
cat("Random Forest : erreur moyenne", round(mean(erreur_rf), 1), "k€, écart-type entre blocs", round(sd(erreur_rf), 1), "\n")
# Piège : l'erreur mesurée sur les données d'entraînement flatte la forêt
foret <- randomForest(formule, data = magasins, ntree = 300)
cat("Random Forest, erreur sur ses propres données :", round(mean(abs(magasins$ca_k - predict(foret, magasins))), 1), "k€\n")
# CA des magasins : validation croisée en Python
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import KFold, cross_val_score
magasins = pd.read_csv("magasins.csv")
X = pd.get_dummies(magasins[["surface_m2", "budget_pub_k", "nb_concurrents", "zone"]], drop_first=True, dtype=float)
y = magasins["ca_k"]
# 10 blocs : chaque magasin sert 9 fois à l'entraînement et 1 fois au test
blocs = KFold(n_splits=10, shuffle=True, random_state=42)
modeles = {"Régression linéaire": LinearRegression(),
"Random Forest": RandomForestRegressor(n_estimators=300, random_state=42)}
for nom, modele in modeles.items():
erreurs = -cross_val_score(modele, X, y, cv=blocs, scoring="neg_mean_absolute_error")
print(f"{nom} : erreur moyenne {erreurs.mean():.1f} k€ (écart-type entre blocs {erreurs.std():.1f})")
print(" par bloc :", erreurs.round(0).tolist())
# Piège : l'erreur mesurée sur les données d'entraînement flatte la forêt
foret = modeles["Random Forest"].fit(X, y)
print("Random Forest, erreur sur ses propres données :", round((y - foret.predict(X)).abs().mean(), 1), "k€")
Les données sont découpées en k blocs. Le modèle est entraîné k fois, chaque fois sur k - 1 blocs, et évalué sur le bloc restant. La moyenne des k résultats estime la performance sur des données nouvelles, de façon plus stable qu'un découpage unique.
Oui, dès que la validation croisée sert à choisir un modèle ou des réglages. Le score du meilleur candidat est alors légèrement optimiste, puisqu'il a été retenu parce qu'il était bon. Un jeu de test mis de côté dès le départ donne le verdict final.
5 ou 10 sont les valeurs standard. Avec très peu de données, on peut monter jusqu'au leave-one-out, où chaque ligne est testée seule, mais le résultat est plus variable et le calcul plus long. Avec beaucoup de données, 5 blocs suffisent.
Utilise la validation croisée pour noter chaque combinaison de réglages et garder la meilleure.
Voir la fiche → le modèle testéSon score hors du sac (OOB) donne une estimation proche de la validation croisée, sans entraînement supplémentaire.
Voir la fiche → le gagnant du jourSur 400 lignes et des relations presque linéaires, le modèle simple bat souvent les modèles complexes.
Voir la fiche →Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.
Nous utilisons des cookies de mesure d'audience et de suivi publicitaire pour comprendre la fréquentation du site et l'efficacité de nos annonces. Rien n'est déposé sans votre accord. En savoir plus