Régression pas à pas en R : forward, backward et both avec stepAIC et leaps

Laissez un algorithme choisir vos prédicteurs — puis vérifiez ce choix honnêtement par validation croisée

Un guide pratique de la régression pas à pas en R : sélection forward, élimination backward et sélection pas à pas bidirectionnelle (remplacement séquentiel). Exécutez-les avec MASS::stepAIC (le moteur piloté par l’AIC) et leaps::regsubsets, choisissez un modèle par AIC/BIC, puis évaluez la formule retenue honnêtement par validation croisée dans un workflow tidymodels. Inclut une mise en garde lucide sur les pièges connus de la sélection pas à pas (R² gonflé, instabilité, p-values faussées). Démontré sur les données swiss intégrées.

Date de publication

25 juin 2026

Modifié

7 juillet 2026

AstucePoints clés à retenir
  • La régression pas à pas recherche automatiquement un bon sous-ensemble de prédicteurs en ajoutant et/ou retirant les variables une à une, en conservant le modèle qui prédit le mieux avec le moins de termes.
  • Trois directions : la sélection forward (partir d’un modèle vide, ajouter le meilleur prédicteur à chaque étape), l’élimination backward (partir du modèle complet, retirer le plus faible à chaque étape) et le both / remplacement séquentiel (ajouter comme en forward, mais re-vérifier et retirer les termes qui n’aident plus).
  • Le moteur de référence est MASS::stepAIC() — il ajoute/retire des variables pour minimiser l’AIC, un score qui récompense l’ajustement mais pénalise les termes superflus. leaps::regsubsets() est l’alternative qui renvoie le meilleur modèle de chaque taille pour que vous les compariez.
  • tidymodels n’a pas d’étape pas à pas native. C’est attendu — la façon honnête et actuelle est d’exécuter stepAIC/leaps en R base, puis de réinjecter la formule retenue dans un workflow pour l’évaluer équitablement par validation croisée.
  • Ne faites jamais confiance au R² ou aux p-values du modèle sélectionné lui-même. La sélection pas à pas gonfle le R², fausse les p-values, et l’ensemble retenu est instable d’un échantillon à l’autre. Validez le choix sur des données mises de côté (CV) — c’est le seul score honnête.
  • Sur les données swiss, les trois directions convergent vers le même modèle à 4 variables, qui se valide mieux en validation croisée que le modèle complet à 5 variables (RMSE 7.50 vs 7.84) — un gain petit mais réel.
Obtenez le livre — Machine Learning Essentials (PDF)

Introduction

Vous avez une régression avec une poignée de prédicteurs candidats et une question lancinante : ai-je vraiment besoin de tous ? Un modèle comportant moins de variables, bien choisies, est plus facile à expliquer, moins coûteux à documenter en données, et prédit souvent mieux les données nouvelles — car chaque prédicteur inutile que vous retirez est une chose de moins sur laquelle le modèle peut surapprendre.

La régression pas à pas (aussi appelée sélection pas à pas ou sélection pas à pas de variables) automatise cette recherche. Elle ajoute et retire des prédicteurs de façon itérative, en notant chaque modèle candidat, et conserve le sous-ensemble qui donne le modèle le plus performant — celui dont l’erreur de prédiction est la plus faible. Elle se décline en trois variantes :

  1. Sélection forward — partir d’aucun prédicteur, puis ajouter itérativement le plus contributif, en s’arrêtant lorsque ajouter davantage n’aide plus.
  2. Sélection backward (élimination backward) — partir du modèle complet (tous les prédicteurs), puis retirer itérativement le moins contributif, en s’arrêtant lorsque chaque prédicteur restant mérite sa place.
  3. Bidirectionnelle / pas à pas (remplacement séquentiel) — une combinaison : ajouter comme en forward, mais après chaque ajout re-vérifier et retirer toute variable qui n’améliore plus l’ajustement.

Utilisez la sélection pas à pas lorsque vous avez plusieurs prédicteurs plausibles et voulez un modèle compact et bien ajusté sans essayer à la main toutes les combinaisons — elle est particulièrement commode dans les contextes à grande dimension (beaucoup de prédicteurs, p. ex. en génomique) où les méthodes forward et pas à pas peuvent fonctionner même lorsque le nombre de prédicteurs dépasse le nombre d’échantillons.

NoteForward et backward n’ont pas la même portée
  • Les sélections forward et bidirectionnelle fonctionnent même lorsque vous avez plus de prédicteurs que d’échantillons (n < p) — courant en données génomiques — car elles partent petit et grandissent.
  • L’élimination backward exige n > p, puisqu’elle doit d’abord ajuster le modèle complet.

Un avertissement d’emblée, parce qu’il compte : la sélection pas à pas est commode mais ce n’est pas un repas gratuit. Elle a tendance au surapprentissage — le R² et les p-values du modèle sélectionné lui-même sont optimistes, et l’ensemble de variables retenu peut changer si vous ré-échantillonnez les données. Nous enseignerons les méthodes et vous montrerons comment vérifier honnêtement leur travail par validation croisée. Cette leçon s’appuie sur la leçon workflow tidymodels et la leçon validation croisée ; pour l’alternative exhaustive qui note chaque sous-ensemble, voir régression best subsets, et pour l’approche moderne par rétrécissement, régression pénalisée.

Les données

Nous utiliserons le jeu de données intégré swiss : fertilité standardisée et cinq indicateurs socio-économiques pour 47 provinces francophones de Suisse aux alentours de 1888. L’objectif est de prédire Fertility à partir des cinq autres variables — et de découvrir lesquelles nous sont réellement nécessaires.

data("swiss")

# 47 Swiss provinces: predict Fertility from five socio-economic indicators
head(swiss, 4)
             Fertility Agriculture Examination Education Catholic
Courtelary        80.2        17.0          15        12     9.96
Delemont          83.1        45.1           6         9    84.84
Franches-Mnt      92.5        39.7           5         5    93.40
Moutier           85.8        36.5          12         7    33.77
             Infant.Mortality
Courtelary               22.2
Delemont                 22.2
Franches-Mnt             20.2
Moutier                  20.3

Cinq prédicteurs candidats — Agriculture, Examination, Education, Catholic et Infant.Mortality — et 47 lignes. Suffisamment peu pour qu’on puisse réellement voir chaque sous-ensemble sélectionné, ce qui fait de swiss un jeu d’apprentissage parfait pour la sélection de variables.

Le modèle complet : le point de départ

La sélection pas à pas compare les sous-modèles au modèle complet — celui qui contient chaque prédicteur. Ajustez-le une fois avec le lm() de R base et lisez son résumé :

data("swiss")

full.model <- lm(Fertility ~ ., data = swiss)
summary(full.model)

Call:
lm(formula = Fertility ~ ., data = swiss)

Residuals:
     Min       1Q   Median       3Q      Max 
-15.2743  -5.2617   0.5032   4.1198  15.3213 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)      66.91518   10.70604   6.250 1.91e-07 ***
Agriculture      -0.17211    0.07030  -2.448  0.01873 *  
Examination      -0.25801    0.25388  -1.016  0.31546    
Education        -0.87094    0.18303  -4.758 2.43e-05 ***
Catholic          0.10412    0.03526   2.953  0.00519 ** 
Infant.Mortality  1.07705    0.38172   2.822  0.00734 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 7.165 on 41 degrees of freedom
Multiple R-squared:  0.7067,    Adjusted R-squared:  0.671 
F-statistic: 19.76 on 5 and 41 DF,  p-value: 5.594e-10

Regardez la colonne de la p-value. Deux prédicteurs ne tirent visiblement pas leur poids : Examination (p ≈ 0.31) et, dans une moindre mesure, les autres sont tous significatifs. Le modèle complet explique bien les données (R² ajusté ≈ 0.67), mais si Examination n’apporte rien, un modèle plus épuré peut prédire les données nouvelles aussi bien, voire mieux. C’est exactement la question à laquelle la sélection pas à pas répond — automatiquement, par un score raisonné plutôt qu’en jugeant les p-values à l’œil.

Pas à pas bidirectionnel avec MASS::stepAIC()

Le moteur de référence pour la sélection pas à pas en R est stepAIC() du package MASS. Il ajoute et retire des prédicteurs pour minimiser l’AIC (Akaike Information Criterion) — un score qui récompense un bon ajustement mais pénalise chaque terme superflu, si bien qu’il préfère naturellement les modèles plus petits sauf si une variable mérite vraiment sa place. Son argument direction prend "both" (pas à pas), "forward" ou "backward".

Commençons par la sélection bidirectionnelle. Nous passons le modèle complet et laissons stepAIC() se déplacer dans l’une ou l’autre direction à chaque étape (trace = FALSE fait taire le journal étape par étape) :

library(MASS)
data("swiss")

full.model <- lm(Fertility ~ ., data = swiss)

# Both-direction stepwise selection, minimising AIC
step.model <- stepAIC(full.model, direction = "both", trace = FALSE)
summary(step.model)

Call:
lm(formula = Fertility ~ Agriculture + Education + Catholic + 
    Infant.Mortality, data = swiss)

Residuals:
     Min       1Q   Median       3Q      Max 
-14.6765  -6.0522   0.7514   3.1664  16.1422 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)      62.10131    9.60489   6.466 8.49e-08 ***
Agriculture      -0.15462    0.06819  -2.267  0.02857 *  
Education        -0.98026    0.14814  -6.617 5.14e-08 ***
Catholic          0.12467    0.02889   4.315 9.50e-05 ***
Infant.Mortality  1.07844    0.38187   2.824  0.00722 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 7.168 on 42 degrees of freedom
Multiple R-squared:  0.6993,    Adjusted R-squared:  0.6707 
F-statistic: 24.42 on 4 and 42 DF,  p-value: 1.717e-10

stepAIC() renvoie directement le meilleur modèle final — déjà réajusté, prêt à lire. Il a retiré Examination et conservé quatre prédicteurs :

\[ Fertility \sim Agriculture + Education + Catholic + Infant.Mortality \]

Lisez le résultat en langage clair :

  • Chaque prédicteur restant est désormais statistiquement significatif (tous p < 0.05) — Examination, le seul terme qui ne l’était pas, a disparu.
  • Le R² ajusté est ≈ 0.67 — quasi identique à celui du modèle complet, atteint avec un prédicteur de moins. C’est tout l’intérêt : même pouvoir explicatif, un modèle plus simple.
  • Les signes sont interprétables : Education et Agriculture sont associés à une fertilité plus faible, tandis que Catholic et Infant.Mortality sont associés à une fertilité plus élevée.
NoteCe que fait réellement l’AIC

À chaque étape, stepAIC() envisage d’ajouter ou de retirer une variable et calcule l’AIC de chaque candidat. Il passe au changement qui abaisse le plus l’AIC, et s’arrête lorsque aucun ajout ou retrait isolé ne l’améliore plus. Comme AIC = (défaut d’ajustement) + (pénalité pour le nombre de termes), il équilibre automatiquement l’exactitude contre la complexité — sans seuil de p-value arbitraire requis.

Sélection forward et backward

La même fonction réalise la sélection forward seule et backward seule — il suffit de changer direction. L’élimination backward part du modèle complet et retire des termes :

library(MASS)
data("swiss")

full.model <- lm(Fertility ~ ., data = swiss)
back.model <- stepAIC(full.model, direction = "backward", trace = FALSE)

# The formula backward elimination settled on
formula(back.model)
Fertility ~ Agriculture + Education + Catholic + Infant.Mortality

La sélection forward fait l’inverse : elle part d’un modèle vide (intercept seulement) et ajoute le prédicteur le plus utile à chaque étape. La sélection forward a besoin d’un scope pour que stepAIC() connaisse le modèle le plus grand qu’il est autorisé à construire :

library(MASS)
data("swiss")

# Start empty; scope says "you may add up to all five predictors"
null.model <- lm(Fertility ~ 1, data = swiss)
forward.model <- stepAIC(
  null.model, direction = "forward",
  scope = list(lower = ~ 1,
               upper = ~ Agriculture + Examination + Education + Catholic + Infant.Mortality),
  trace = FALSE
)
formula(forward.model)
Fertility ~ Education + Catholic + Infant.Mortality + Agriculture

Sur les données swiss, les trois directions s’accordent : elles retirent chacune Examination et conservent les mêmes quatre prédicteurs. Cet accord est rassurant — mais ne l’attendez pas en général. Avec davantage de prédicteurs, ou avec des prédicteurs corrélés, les sélections forward et backward peuvent aboutir à des modèles différents, car l’ordre dans lequel les variables entrent ou sortent change celles qui paraissent « contributives » à chaque étape. (Cette dépendance au chemin est l’une des faiblesses connues du pas à pas — nous y reviendrons plus bas.)

Comparer les tailles de modèle avec leaps::regsubsets()

stepAIC() vous remet un modèle final. Parfois, vous préférez voir le meilleur modèle de chaque taille — le meilleur modèle à 1 variable, le meilleur à 2 variables, et ainsi de suite — et choisir vous-même parmi eux. C’est ce que fait regsubsets() du package leaps. Son argument method prend lui aussi "forward", "backward" et "seqrep" (remplacement séquentiel = bidirectionnel) :

library(leaps)
data("swiss")

# Best model of each size, up to all 5 predictors, by sequential replacement
models <- regsubsets(Fertility ~ ., data = swiss, nvmax = 5, method = "seqrep")
summary(models)$outmat
         Agriculture Examination Education Catholic Infant.Mortality
1  ( 1 ) " "         " "         "*"       " "      " "             
2  ( 1 ) " "         " "         "*"       "*"      " "             
3  ( 1 ) " "         " "         "*"       "*"      "*"             
4  ( 1 ) "*"         "*"         "*"       "*"      " "             
5  ( 1 ) "*"         "*"         "*"       "*"      "*"             

Lisez ce tableau ligne par ligne. Chaque ligne est le meilleur modèle de cette taille, et une "*" marque les variables qu’il inclut :

  • 1 variable : Education seule — le prédicteur unique le plus fort de la fertilité.
  • 2 variables : ajoute Catholic.
  • 3 variables : ajoute Infant.Mortality.
  • 4 variables : intègre Agriculture et Examination (c’est ici que le « remplacement séquentiel » mérite son nom — il peut remplacer une variable, pas seulement en ajouter une).
  • 5 variables : le modèle complet.

regsubsets() ne désigne pas de gagnant — il vous donne les candidats. Pour choisir, comparez-les à l’aide d’un critère. Le BIC (Bayesian Information Criterion) pénalise la complexité plus fortement que l’AIC, il favorise donc les modèles plus petits ; le R² ajusté récompense l’ajustement tout en facturant les termes superflus. Les deux sont renvoyés dans le résumé :

library(leaps)
data("swiss")

models <- regsubsets(Fertility ~ ., data = swiss, nvmax = 5, method = "seqrep")
res <- summary(models)

# One row per model size (1 to 5 predictors)
data.frame(
  n_vars = 1:5,
  adjR2  = round(res$adjr2, 3),
  BIC    = round(res$bic, 1)
)
  n_vars adjR2   BIC
1      1 0.428 -19.6
2      2 0.555 -28.6
3      3 0.639 -35.7
4      4 0.616 -30.1
5      5 0.671 -34.6
library(leaps)
data("swiss")

res <- summary(regsubsets(Fertility ~ ., data = swiss, nvmax = 5, method = "seqrep"))

# Which size wins on each criterion?
c(best_by_adjR2 = which.max(res$adjr2),
  best_by_BIC   = which.min(res$bic))
best_by_adjR2   best_by_BIC 
            5             3 

Ici les deux critères divergent, ce qui est courant et instructif : le R² ajusté apprécie le modèle à 5 variables (complet), tandis que le BIC plus strict préfère le modèle plus épuré à 3 variables. stepAIC(), à l’aide de l’AIC (une pénalité intermédiaire entre les deux), a abouti à 4 variables. Il n’existe pas de réponse « correcte » unique à partir de ces scores en échantillon seuls — c’est précisément pourquoi l’étape suivante compte.

Le test honnête : évaluer le modèle retenu par validation croisée

Chaque score jusqu’ici — R², AIC, BIC, R² ajusté — a été calculé sur les mêmes données que celles sur lesquelles le modèle a été sélectionné. Cela les rend optimistes : la sélection pas à pas a activement cherché les variables qui ajustent cet échantillon le mieux, si bien que le modèle gagnant se flatte lui-même. La seule question honnête est à quel point le modèle sélectionné prédit-il des données qu’il n’a jamais vues ? — et la réponse est la validation croisée.

NotePourquoi il n’y a pas de step_*() pour cela dans tidymodels — et que faire à la place

tidymodels n’a pas d’étape de sélection pas à pas native. C’est un choix de conception délibéré : l’instabilité et l’inférence gonflée du pas à pas en font une mauvaise adéquation avec la philosophie du framework (il privilégie la régression pénalisée à la place — voir régression pénalisée). Le workflow honnête et actuel est donc en deux étapes :

  1. Sélectionner la formule en R base avec stepAIC() ou leaps (ci-dessus).
  2. Évaluer cette formule fixe avec un workflow tidymodels + validation croisée — exactement comme vous évalueriez n’importe quel autre modèle.

Cela maintient la sélection transparente et le scoring honnête. Notez une mise en garde importante : faire la sélection une fois sur l’ensemble des données puis valider par validation croisée la formule retenue donne une estimation légèrement optimiste (la sélection elle-même a « vu » toutes les lignes). La version pleinement rigoureuse ré-exécute la sélection à l’intérieur de chaque pli ; pour une comparaison rapide et pratique d’une poignée de formules candidates fixes — ce que nous faisons ici — l’approche en deux étapes est le choix standard et lisible.

Enveloppez la formule retenue par stepAIC dans un workflow et notez-la par validation croisée à 10 plis. Nous notons le modèle complet de la même façon, afin de pouvoir comparer des chiffres honnêtes, hors échantillon :

library(rsample)
library(parsnip)
library(workflows)
library(recipes)
library(tune)
library(yardstick)
data("swiss")

lm_spec <- linear_reg() |> set_engine("lm") |> set_mode("regression")

# The model stepwise selection chose (4 predictors)
selected_wf <- workflow() |>
  add_recipe(recipe(Fertility ~ Agriculture + Education + Catholic + Infant.Mortality, data = swiss)) |>
  add_model(lm_spec)

# The full model (all 5 predictors), for comparison
full_wf <- workflow() |>
  add_recipe(recipe(Fertility ~ ., data = swiss)) |>
  add_model(lm_spec)

set.seed(123)
folds <- vfold_cv(swiss, v = 10)

selected_cv <- fit_resamples(selected_wf, folds, metrics = metric_set(rmse, rsq, mae))
full_cv     <- fit_resamples(full_wf,     folds, metrics = metric_set(rmse, rsq, mae))

# Compare cross-validated RMSE / R² / MAE
rbind(
  cbind(model = "selected (4 vars)", collect_metrics(selected_cv)[, c(".metric", "mean", "std_err")]),
  cbind(model = "full (5 vars)",     collect_metrics(full_cv)[,     c(".metric", "mean", "std_err")])
)
              model .metric      mean    std_err
1 selected (4 vars)     mae 6.2201454 0.48892475
2 selected (4 vars)    rmse 7.4989210 0.61641478
3 selected (4 vars)     rsq 0.5697723 0.10863240
4     full (5 vars)     mae 6.4225431 0.53307867
5     full (5 vars)    rmse 7.8376182 0.65271681
6     full (5 vars)     rsq 0.5243613 0.09735617

Lisez la comparaison — c’est le moment de vérité :

  • Le modèle sélectionné à 4 variables affiche un RMSE validé par validation croisée plus faible (≈ 7.50) que le modèle complet à 5 variables (≈ 7.84), un MAE plus faible et un R² validé par validation croisée plus élevé. Retirer Examination n’a pas seulement simplifié le modèle — il l’a fait prédire un peu mieux les données nouvelles, parce que ce prédicteur ajoutait du bruit, pas du signal.
  • L’amélioration est petite mais réelle, et elle pointe dans la même direction que le choix de l’AIC. Lorsqu’un modèle plus épuré l’emporte sur des données mises de côté, vous disposez d’une preuve authentique pour le préférer — pas seulement un score en échantillon que n’importe quelle variable supplémentaire aurait fait remonter.
AstuceÀ retenir, prêt à coller

« La sélection pas à pas bidirectionnelle (MASS::stepAIC) sur les données swiss a retiré Examination et conservé un modèle à 4 prédicteurs. Évalué par validation croisée à 10 plis, ce modèle prédit la fertilité avec un RMSE de ≈ 7.5 — légèrement mieux que le modèle complet à 5 prédicteurs (RMSE ≈ 7.8) — confirmant que le modèle plus simple est le meilleur prédicteur. »

À voir : quelle taille de modèle prédit le mieux ?

Pour rendre visuel le compromis taille–exactitude, voici le RMSE validé par validation croisée du meilleur modèle de chaque taille (issu de leaps), tracé en fonction du nombre de prédicteurs. Le point le plus bas est la taille que vous voulez :

library(leaps)
library(rsample)
library(parsnip)
library(workflows)
library(recipes)
library(tune)
library(yardstick)
library(ggplot2)
data("swiss")

# Best variable subset of each size (sequential replacement)
res <- summary(regsubsets(Fertility ~ ., data = swiss, nvmax = 5, method = "seqrep"))
preds <- colnames(res$outmat)
lm_spec <- linear_reg() |> set_engine("lm") |> set_mode("regression")

# 10-fold CV the best model of each size on the SAME folds
set.seed(123)
folds <- vfold_cv(swiss, v = 10)

cv_one <- function(k) {
  vars <- preds[res$outmat[k, ] == "*"]                       # the k chosen predictors
  form <- reformulate(vars, response = "Fertility")
  wf   <- workflow() |> add_recipe(recipe(form, data = swiss)) |> add_model(lm_spec)
  m    <- collect_metrics(fit_resamples(wf, folds, metrics = metric_set(rmse)))
  data.frame(n_vars = k, rmse = m$mean, se = m$std_err)
}
cv_by_size <- do.call(rbind, lapply(1:5, cv_one))

ggplot(cv_by_size, aes(x = n_vars, y = rmse)) +
  geom_errorbar(aes(ymin = rmse - se, ymax = rmse + se), width = 0.15, color = "gray50") +
  geom_line(color = "#3a86d4") +
  geom_point(color = "#3a86d4", size = 3.5) +
  scale_x_continuous(breaks = 1:5) +
  labs(
    x = "Number of predictors", y = "Cross-validated RMSE (lower = better)",
    title = "How many predictors does the swiss model need?",
    subtitle = "10-fold CV of the best subset of each size — the 4-variable model is the sweet spot"
  ) +
  theme_minimal()

Dot-and-error-bar plot of 10-fold cross-validated RMSE for the best 1- to 5-variable models of the swiss data. RMSE falls steeply from the 1-variable model, reaches its minimum around the 4-variable model, then ticks up slightly for the full 5-variable model; each point carries a fold-to-fold standard-error bar.

La courbe chute brusquement à mesure que les premiers prédicteurs utiles entrent, atteint son creux autour de quatre variables, puis remonte légèrement pour le modèle complet — preuve visuelle que le cinquième prédicteur (Examination) nuit à l’exactitude hors échantillon. C’est la version honnête de la sélection de modèle : ne lisez pas le gagnant sur un R² en échantillon, lisez-le sur la courbe de validation croisée.

À manier avec précaution : les pièges de la sélection pas à pas

La régression pas à pas est réellement utile, mais c’est le genre d’outil qui vous induit discrètement en erreur si vous faites confiance à sa sortie sans esprit critique. Soyez honnête sur ses trois faiblesses bien documentées :

  • R² gonflé et ajustement optimiste. Le modèle sélectionné a été choisi pour ajuster votre échantillon, si bien que son R² et son erreur résiduelle paraissent meilleurs qu’ils ne le seront sur des données nouvelles. Ne rapportez jamais le R² du modèle sélectionné lui-même comme son exactitude prédictive — rapportez un chiffre validé par validation croisée (comme ci-dessus).
  • p-values et erreurs standards faussées. Les p-values classiques affichées par summary() sur un modèle sélectionné par pas à pas ne sont pas valides — elles ignorent que les variables ont été choisies en regardant les données. Traitez-les comme descriptives, pas comme d’honnêtes tests d’hypothèse.
  • Instabilité. L’ensemble de variables sélectionné peut changer avec un petit changement dans les données, surtout lorsque les prédicteurs sont corrélés (forward et backward peuvent diverger, comme noté plus haut). Le modèle retenu est l’un de plusieurs presque équivalents, pas un sous-ensemble « vrai » de façon unique.
NoteVers quoi se tourner à la place — ou en complément

Pour la prédiction avec de nombreux prédicteurs ou des prédicteurs corrélés, la régression pénalisée (ridge, lasso, elastic net) est généralement le choix meilleur et plus stable : elle rétrécit les coefficients en douceur plutôt que de prendre des décisions dures d’inclusion/exclusion, et le lasso peut mettre des variables à zéro pour vous — voir régression pénalisée. Pour rechercher tous les sous-ensembles de façon exhaustive (faisable lorsque les prédicteurs sont peu nombreux), voir régression best subsets. Quoi que vous sélectionniez, validez le choix par validation croisée — c’est la partie que la sélection pas à pas ne peut pas faire à votre place.

La sélection pas à pas a besoin d’un nombre unique pour comparer des modèles de tailles différentes. L’AIC (Akaike Information Criterion) est ce nombre. Pour un modèle ajusté par maximum de vraisemblance avec \(k\) paramètres estimés et une log-vraisemblance maximisée \(\hat{L}\) :

\[ AIC = 2k - 2 \ln(\hat{L}). \]

Le second terme récompense l’ajustement (un modèle mieux ajusté a un \(\hat{L}\) plus grand, ce qui abaisse l’AIC) ; le premier terme, \(2k\), facture une pénalité pour chaque paramètre ajouté. Un nouveau prédicteur n’abaisse l’AIC que si l’ajustement qu’il achète l’emporte sur sa pénalité — l’AIC intègre donc une défense contre le surapprentissage, et un AIC plus bas est meilleur. Le BIC utilise la même forme avec une pénalité plus lourde, dépendante de la taille d’échantillon (\(\ln(n)\,k\) au lieu de \(2k\)), il punit donc la complexité plus durement et tend à sélectionner des modèles plus petits — ce qui explique pourquoi, sur swiss, le BIC a préféré 3 prédicteurs tandis que l’AIC en a gardé 4. Aucun n’est « juste » dans l’absolu ; l’AIC vise l’exactitude prédictive, le BIC vise l’identification du vrai modèle. Lorsqu’ils divergent, laissez la validation croisée trancher.

🟢 Avec un agent IA

Vous ne savez pas quels prédicteurs conserver — ou si votre modèle pas à pas surapprend ? Demandez à Prova « exécute une sélection pas à pas sur mes données et valide par validation croisée le modèle retenu pour voir s’il prédit vraiment mieux » — elle répond avec du code stepAIC/leaps + tidymodels que vous pouvez exécuter sur vos propres données, puis vous aide à lire l’AIC, le RMSE validé par validation croisée, et à juger si vous pouvez faire confiance à la sélection. The runtime is the judge. Ask Prova →

Problèmes courants

  • stepAIC() introuvable. Il vit dans le package MASS — exécutez library(MASS) d’abord. (Surveillez l’ordre de chargement : MASS::select masque dplyr::select, alors chargez MASS avant tidyverse, ou appelez dplyr::select() explicitement.)
  • La sélection forward n’ajoute rien / renvoie le modèle vide. La sélection forward a besoin d’un scope avec une formule upper listant les prédicteurs qu’elle est autorisée à ajouter. Sans lui, stepAIC() n’a aucun candidat à considérer — passez scope = list(lower = ~ 1, upper = ~ <all predictors>).
  • regsubsets() échoue avec « n < p » pour la sélection backward. L’élimination backward doit ajuster le modèle complet d’abord, ce qui est impossible quand vous avez moins d’échantillons que de prédicteurs. Utilisez method = "forward" (ou "seqrep") dans le cas à grande dimension à la place.
  • L’exactitude de test de votre modèle sélectionné est pire que ce que summary() suggérait. Attendu — les R²/p-values en échantillon sont optimistes après sélection. Notez toujours la formule retenue par validation croisée, jamais avec les chiffres que summary() imprime sur le modèle sélectionné.

Questions fréquentes

Utilisez MASS::stepAIC() sur un modèle lm()/glm() ajusté : stepAIC(full.model, direction = "both"). L’argument direction choisit la stratégie — "both" (pas à pas), "forward" ou "backward" — et la fonction renvoie le meilleur modèle final, sélectionné en minimisant l’AIC. Le package leaps (regsubsets()) est l’alternative lorsque vous voulez comparer le meilleur modèle de chaque taille.

Partez d’un modèle à intercept seulement et laissez stepAIC() ajouter des prédicteurs : stepAIC(lm(y ~ 1, data), direction = "forward", scope = list(lower = ~ 1, upper = ~ x1 + x2 + x3)). La formule upper du scope liste chaque prédicteur qu’il peut ajouter. La sélection forward fonctionne même lorsque vous avez plus de prédicteurs que d’échantillons. Avec leaps, utilisez regsubsets(..., method = "forward").

Ajustez le modèle complet, puis exécutez stepAIC(full.model, direction = "backward") — il retire le prédicteur le moins utile à chaque étape jusqu’à ce que l’AIC cesse de s’améliorer. Avec leaps, utilisez regsubsets(..., method = "backward"). L’élimination backward exige plus d’échantillons que de prédicteurs (n > p), car elle doit d’abord ajuster le modèle complet.

La sélection forward part d’aucun prédicteur et ajoute le plus utile à chaque étape ; l’élimination backward part de tous les prédicteurs et retire le moins utile. La bidirectionnelle (pas à pas / remplacement séquentiel) les combine — ajoutant comme en forward mais re-vérifiant et retirant les termes qui n’aident plus. Les méthodes forward et pas à pas peuvent fonctionner quand les prédicteurs dépassent les échantillons ; la backward ne le peut pas. Sur des données bien comportées elles s’accordent souvent, mais avec des prédicteurs corrélés elles peuvent aboutir à des modèles différents.

Elle est commode mais imparfaite. La sélection pas à pas gonfle le R², fausse les p-values (elles ignorent que les variables ont été choisies sur les données), et l’ensemble sélectionné est instable d’un échantillon à l’autre. Utilisez-la comme un outil exploratoire rapide, validez toujours le modèle retenu par validation croisée, et pour une prédiction sérieuse préférez la régression pénalisée (lasso/ridge/elastic net), qui sélectionne et rétrécit de façon plus stable.

Testez vos connaissances

En utilisant le jeu de données mtcars, prédisez mpg à partir de toutes les autres variables. Ajustez le modèle complet, exécutez un stepAIC() bidirectionnel pour sélectionner un sous-ensemble, puis évaluez la formule retenue par validation croisée à 10 plis dans un workflow tidymodels et comparez son RMSE à celui du modèle complet.

La structure est identique à celle de la leçon — remplacez swiss/Fertility ~ . par mtcars/mpg ~ .. Utilisez MASS::stepAIC(full.model, direction = "both") pour la sélection, puis formula(step.model) pour lire les prédicteurs retenus, et insérez cette formule dans une recipe() à l’intérieur d’un workflow pour fit_resamples().

library(MASS)
library(rsample); library(parsnip); library(workflows)
library(recipes); library(tune); library(yardstick)
data("mtcars")

# 1. Select with stepAIC
full.model <- lm(mpg ~ ., data = mtcars)
step.model <- stepAIC(full.model, direction = "both", trace = FALSE)
formula(step.model)        # e.g. mpg ~ wt + qsec + am

# 2. Evaluate the selected formula by 10-fold CV
lm_spec <- linear_reg() |> set_engine("lm") |> set_mode("regression")
sel_wf  <- workflow() |>
  add_recipe(recipe(formula(step.model), data = mtcars)) |>
  add_model(lm_spec)

set.seed(123)
folds <- vfold_cv(mtcars, v = 10)
collect_metrics(fit_resamples(sel_wf, folds, metrics = metric_set(rmse, rsq)))

stepAIC() conserve généralement wt, qsec et am — un modèle compact à 3 prédicteurs dont le RMSE validé par validation croisée est compétitif avec (souvent meilleur que) celui du modèle complet à 10 prédicteurs, qui surapprend ce petit jeu de données.

Vérification rapide. Un collègue exécute une élimination backward, rapporte le summary() du modèle sélectionné avec « toutes les p-values < 0.01, R² = 0.88 », et conclut que le modèle est excellent. Pourquoi devriez-vous être sceptique face à ces chiffres, et que devriez-vous demander à la place ?

Les deux chiffres sont optimistes parce que le modèle a été sélectionné à partir des données. Les p-values ignorent que les variables ont été choisies en regardant la réponse, elles surestiment donc la significativité ; le R² est gonflé parce que la sélection a trié sur le volet les variables qui ajustent cet échantillon. Demandez une erreur validée par validation croisée (p. ex. RMSE/R² à 10 plis) sur la formule retenue — la seule estimation honnête de la façon dont le modèle prédit des données nouvelles.

Conclusion

Vous avez exécuté les trois stratégies pas à pas sur les données swissforward, backward et bidirectionnelle — avec MASS::stepAIC() (piloté par l’AIC, renvoie le modèle final) et leaps::regsubsets() (renvoie le meilleur modèle de chaque taille à comparer par AIC/BIC/R²-ajusté). Les trois ont convergé vers un modèle à 4 prédicteurs, et — c’est crucial — vous avez confirmé ce choix de la façon honnête : en enveloppant la formule retenue dans un workflow tidymodels et en la validant par validation croisée, où elle a devancé le modèle complet (RMSE 7.50 vs 7.84). La discipline à retenir : le pas à pas sélectionne, mais il ne peut pas valider — son propre R² et ses p-values sont optimistes, alors laissez les données mises de côté être le juge.

Ensuite, comparez cela à la recherche exhaustive de régression best subsets, ou rencontrez l’alternative moderne plus stable dans régression pénalisée.

Leçons connexes

Vous préférez un livre ? Machine Learning Essentials est disponible en PDF téléchargeable — toutes les leçons de cette série, hors ligne et à vous.

Obtenir le livre (PDF) →Les leçons restent gratuites en ligne.
Cette page vous a-t-elle été utile ?

Prouvez que vous savez le faire. Maîtrisez toute la série Sélection de modèles en R — suivez votre parcours, construisez des projets et obtenez un certificat.

Commencer gratuitement →

Passez à Pro — Prova illimité sur vos propres données et un certificat vérifiable qui atteste la compétence.

dès 15 $/mois facturé annuellement

Passer à Pro →

✓ Vous êtes Pro — continuez. The runtime is the judge.

Recevez les nouvelles leçons R & Python par e-mail

Pratique, reproductible, sans spam. Désinscription à tout moment.

Double opt-in. Nous ne partageons jamais votre e-mail.

Partager cette pageXLinkedInRedditHN
Note

Cette leçon est reproductible : chaque modèle, métrique et figure a été produit par le code montré — copiez n’importe quel bloc et exécutez-le pour les reproduire. The runtime is the judge.

Références

  • James, G., Witten, D., Hastie, T., & Tibshirani, R. (2014). An Introduction to Statistical Learning, with Applications in R. Springer. (Chapitre 6 — Sélection et régularisation des modèles linéaires.)
  • Bruce, P., & Bruce, A. (2017). Practical Statistics for Data Scientists. O’Reilly.
  • Kuhn, M., & Silge, J. Tidy Modeling with R. En ligne, gratuit (CC BY-NC-SA).

Réutilisation

Citation

BibTeX
@online{2026,
  author = {},
  title = {Régression pas à pas en R : forward, backward et both avec
    stepAIC et leaps},
  date = {2026-06-25},
  url = {https://www.datanovia.com/learn/machine-learning/model-selection/stepwise-regression},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
“Régression pas à pas en R : forward, backward et both avec stepAIC et leaps.” 2026. June 25. https://www.datanovia.com/learn/machine-learning/model-selection/stepwise-regression.