Régression best subsets en R : sélection de variables avec leaps

Testez toutes les combinaisons de prédicteurs, comparez les modèles par R² ajusté, Cp et BIC — puis validez le gagnant par validation croisée

Un guide pratique de la régression best subsets (toutes les combinaisons) en R. Utilisez leaps::regsubsets() pour ajuster le meilleur modèle de chaque taille, comparez-les par R² ajusté, Cp de Mallows et BIC, lisez les graphiques critère-vs-taille pour choisir un modèle, puis confirmez honnêtement ce choix par validation croisée à k blocs au moyen d’un workflow tidymodels. Compare la recherche exhaustive à la sélection pas à pas gloutonne et explique son coût combinatoire. Illustré sur les données intégrées swiss.

Date de publication

25 juin 2026

Modifié

7 juillet 2026

AstucePoints clés
  • La régression best subsets ajuste toutes les combinaisons possibles de prédicteurs, puis ne garde que le meilleur modèle de chaque taille — une recherche exhaustive, par opposition à la sélection pas à pas gloutonne.
  • En R, c’est une seule fonction : leaps::regsubsets(y ~ ., data, nvmax = p). Son summary() renvoie le jeu de variables gagnant pour chaque taille, plus trois critères de comparaison : R² ajusté, Cp de Mallows, BIC.
  • Les critères se contredisent à dessein. Maximisez le R² ajusté ; minimisez le Cp et le BIC. Cp et BIC pénalisent plus durement les prédicteurs supplémentaires, donc ils choisissent en général un modèle plus petit que le R² ajusté.
  • Sur les données swiss, le R² ajusté privilégie les 5 prédicteurs alors que Cp et BIC choisissent tous deux 4 — un désaccord classique que vous tranchez par validation croisée.
  • Ne livrez pas sur la seule foi des critères calculés sur l’échantillon d’apprentissage. Le R² ajusté, le Cp et le BIC sont calculés sur les données sur lesquelles le modèle a été ajusté. Confirmez le choix par validation croisée à k blocs sur un workflow tidymodels.
  • C’est exhaustif, donc réservé à un p modeste. Avec p prédicteurs il y a 2ᵖ sous-ensembles — parfait pour une poignée de variables, irréalisable pour des dizaines. Au-delà de ~30–40, tournez-vous plutôt vers la régression pas à pas ou pénalisée.
Obtenez le livre — Machine Learning Essentials (PDF)

Introduction

Vous avez un problème de régression avec une poignée de prédicteurs candidats, et la question pratique que tout analyste rencontre : quelles variables faut-il vraiment mettre dans le modèle ? Les mettre toutes vous expose au surapprentissage — ajuster du bruit, gonfler la variance et dégrader la prédiction sur de nouvelles données. En garder trop peu et vous passez à côté d’un signal réel. Il vous faut une manière rigoureuse de choisir un sous-ensemble.

La régression best subsets — aussi appelée sélection de modèle toutes les combinaisons ou exhaustive — y répond par la force brute : ajuster toutes les combinaisons possibles de prédicteurs, puis comparer les candidats sur un critère qui récompense l’ajustement mais pénalise la complexité. Parce qu’elle considère tous les sous-ensembles, elle est garantie de trouver le meilleur modèle de chaque taille (contrairement à la sélection pas à pas, qui est gloutonne et peut le manquer). Le prix à payer est le coût combinatoire, c’est donc la méthode de choix lorsque le nombre de prédicteurs est modeste.

Cette leçon fait partie de la série Sélection de modèle. Nous ajusterons les sous-ensembles avec leaps::regsubsets(), les comparerons par R² ajusté, Cp et BIC, lirons les graphiques critère-vs-taille pour choisir un modèle, puis — l’étape que les critères seuls ne peuvent remplacer — validerons le modèle choisi par validation croisée au moyen d’un workflow tidymodels. Pour l’alternative gloutonne, voir la régression pas à pas ; quand p est grand ou que les prédicteurs sont corrélés, préférez la régression pénalisée.

Les données

Nous utiliserons le jeu de données intégré swiss : indicateurs standardisés de fertilité et socio-économiques pour 47 provinces francophones de Suisse vers 1888. L’objectif est de prédire Fertility à partir des cinq indicateurs socio-économiques (Agriculture, Examination, Education, Catholic, Infant.Mortality).

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, cela fait 2⁵ = 32 sous-ensembles possibles (31 non vides) — assez peu pour énumérer exhaustivement, ce qui est exactement ce que la régression best subsets va faire.

Calculer la régression best subsets

La fonction de référence est regsubsets() du paquet leaps. Vous lui donnez une formule et data, plus nvmax — la plus grande taille de modèle à considérer. Avec nvmax = 5 elle renvoie le meilleur modèle à 1 variable, le meilleur modèle à 2 variables, … jusqu’au meilleur modèle à 5 variables. Nous avons exactement cinq prédicteurs, donc nvmax = 5 explore l’espace complet.

library(leaps)
data("swiss")

# Fit the best model of every size, 1 through 5 predictors
models <- regsubsets(Fertility ~ ., data = swiss, nvmax = 5)
summary(models)
Subset selection object
Call: regsubsets.formula(Fertility ~ ., data = swiss, nvmax = 5)
5 Variables  (and intercept)
                 Forced in Forced out
Agriculture          FALSE      FALSE
Examination          FALSE      FALSE
Education            FALSE      FALSE
Catholic             FALSE      FALSE
Infant.Mortality     FALSE      FALSE
1 subsets of each size up to 5
Selection Algorithm: exhaustive
         Agriculture Examination Education Catholic Infant.Mortality
1  ( 1 ) " "         " "         "*"       " "      " "             
2  ( 1 ) " "         " "         "*"       "*"      " "             
3  ( 1 ) " "         " "         "*"       "*"      "*"             
4  ( 1 ) "*"         " "         "*"       "*"      "*"             
5  ( 1 ) "*"         "*"         "*"       "*"      "*"             

Lisez le tableau d’astérisques de haut en bas — une ligne par taille de modèle. Un * marque une variable incluse dans le meilleur modèle de cette taille :

  • Le meilleur modèle à 1 variable utilise Education seul.
  • Le meilleur modèle à 2 variables est Fertility ~ Education + Catholic.
  • Le meilleur modèle à 3 variables ajoute Infant.Mortality.
  • Le meilleur modèle à 4 variables est Fertility ~ Agriculture + Education + Catholic + Infant.Mortality (il abandonne Examination).
  • Le meilleur modèle à 5 variables utilise tous les prédicteurs.

Remarquez que Examination est le prédicteur laissé de côté dans le modèle à 4 variables — un indice qu’une fois Education dans le modèle, Examination apporte peu. La question naturelle suivante : lequel de ces cinq « meilleurs » modèles livrons-nous ?

Choisir le modèle optimal

Chaque ligne est le meilleur modèle de sa taille, mais un modèle plus grand ajuste toujours les données d’apprentissage au moins aussi bien — plus de prédicteurs ne peuvent que réduire la somme des carrés des résidus. On ne peut donc pas simplement prendre le R² le plus élevé. Il nous faut des critères qui récompensent l’ajustement mais pénalisent la complexité, de sorte qu’ajouter un prédicteur ne « gagne » que s’il mérite sa place.

R² ajusté, Cp et BIC

summary(regsubsets) vous fournit trois de ces critères pour chaque taille de modèle. Extrayez-les de l’objet summary :

library(leaps)
data("swiss")
models <- regsubsets(Fertility ~ ., data = swiss, nvmax = 5)

res.sum <- summary(models)
data.frame(
  n_pred = 1:5,
  Adj.R2 = round(res.sum$adjr2, 3),   # higher is better
  Cp     = round(res.sum$cp, 3),      # lower is better
  BIC    = round(res.sum$bic, 3)      # lower is better
)
  n_pred Adj.R2     Cp     BIC
1      1  0.428 35.205 -19.603
2      2  0.555 18.486 -28.611
3      3  0.639  8.178 -35.656
4      4  0.671  5.033 -37.234
5      5  0.671  6.000 -34.553

Trois quantités, trois règles empiriques :

  • Le R² ajusté est la proportion de variance de Fertility expliquée par le modèle, ajustée pour le nombre de prédicteurs afin qu’elle n’augmente pas automatiquement avec la taille du modèle. Plus c’est haut, mieux c’est. Ici il grimpe jusqu’à 0.671 et est quasiment plat de 4 à 5 prédicteurs (0.6707 → 0.6710) — la cinquième variable n’apporte presque rien.
  • Le Cp de Mallows estime l’erreur de prédiction du modèle ; un modèle bien ajusté a un Cp proche de son nombre de paramètres. Plus c’est bas, mieux c’est. Il atteint son minimum au modèle à 4 variables (Cp ≈ 5.03), puis remonte pour le modèle à 5 variables — le Cp nous dit que le cinquième prédicteur nuit.
  • Le BIC (critère d’information bayésien) arbitre entre ajustement et complexité avec une forte pénalité sur les paramètres supplémentaires. Plus c’est bas (plus négatif), mieux c’est. Lui aussi est le plus négatif au modèle à 4 variables (−37.2).

Demandez maintenant à chaque critère son unique favori — la taille qui l’optimise :

library(leaps)
data("swiss")
models <- regsubsets(Fertility ~ ., data = swiss, nvmax = 5)
res.sum <- summary(models)

data.frame(
  Adj.R2 = which.max(res.sum$adjr2),  # size with the highest adjusted R²
  Cp     = which.min(res.sum$cp),     # size with the lowest Cp
  BIC    = which.min(res.sum$bic)     # size with the lowest BIC
)
  Adj.R2 Cp BIC
1      5  4   4

Les critères se contredisent — et c’est attendu. Le R² ajusté pointe vers le modèle à 5 variables (il pénalise le plus doucement la complexité, donc il tolère le cinquième prédicteur quasi inutile), tandis que les plus stricts Cp et BIC choisissent tous deux le modèle à 4 variables. « Il n’existe pas de solution unique correcte à la sélection de modèle » — chaque critère encode une préférence ajustement-vs-simplicité différente. Quand deux des trois s’accordent sur 4, et que la cinquième variable bouge à peine le R² ajusté, le modèle à 4 variables est le candidat fort. Mais voyons-le avant de décider.

Le lire sur le graphique

Le moyen le plus rapide de repérer la taille optimale est de tracer chaque critère en fonction du nombre de prédicteurs et de marquer son meilleur point. Ces courbes critère-vs-taille sont la figure emblématique de la régression best subsets :

library(ggplot2)
library(leaps)
data("swiss")
models <- regsubsets(Fertility ~ ., data = swiss, nvmax = 5)
res.sum <- summary(models)

# One tidy long table: criterion value at each model size
crit <- data.frame(
  n_pred    = rep(1:5, 3),
  criterion = rep(c("Adjusted R² (higher = better)",
                    "Cp (lower = better)",
                    "BIC (lower = better)"), each = 5),
  value     = c(res.sum$adjr2, res.sum$cp, res.sum$bic)
)
crit$criterion <- factor(crit$criterion, levels = unique(crit$criterion))

# The optimal size for each criterion (max for adj R², min for Cp & BIC)
best <- data.frame(
  criterion = levels(crit$criterion),
  n_pred    = c(which.max(res.sum$adjr2),
                which.min(res.sum$cp),
                which.min(res.sum$bic))
)
best$criterion <- factor(best$criterion, levels = levels(crit$criterion))
best <- merge(best, crit, by = c("criterion", "n_pred"))

ggplot(crit, aes(n_pred, value)) +
  geom_line(color = "gray60") +
  geom_point(color = "gray40", size = 1.8) +
  geom_point(data = best, color = "#3a86d4", size = 4.5) +   # the optimum
  facet_wrap(~ criterion, scales = "free_y") +
  labs(x = "Number of predictors", y = NULL,
       title = "Best subsets: each criterion vs model size",
       subtitle = "Azure dot = optimal size (Cp and BIC both pick 4 predictors)") +
  scale_x_continuous(breaks = 1:5) +
  theme_minimal()

Three side-by-side line plots versus number of predictors (1 to 5) for the swiss data: adjusted R-squared rises and plateaus, peaking at five predictors; Mallows' Cp falls to a minimum at four predictors then rises; BIC reaches its lowest point at four predictors. Each plot marks its optimum with a large azure dot.

Le graphique rend le compromis évident. Le R² ajusté monte fortement puis plafonne — son pic est à 5, mais la courbe est plate au-delà de 4, donc il est indifférent. Le Cp et le BIC creusent chacun un minimum net à 4 prédicteurs puis remontent : tous deux pénalisent cette cinquième variable. Le verdict visuel correspond aux chiffres — 4 prédicteurs est le point idéal, mais seule la validation croisée peut confirmer qu’il prédit mieux.

ImportantLe piège : ces critères ne voient que les données d’apprentissage

Le R² ajusté, le Cp et le BIC sont tous calculés sur les mêmes données sur lesquelles le modèle a été ajusté. Ils pénalisent la complexité, mais ne peuvent pas protéger totalement contre le surapprentissage — un modèle qui paraît le meilleur sur les données d’apprentissage peut ne pas généraliser. Pour choisir sur une performance honnête hors échantillon, estimez l’erreur de prédiction sur des données que le modèle n’a pas vues, par validation croisée à k blocs.

Valider le choix par validation croisée

La régression best subsets nous a remis une courte liste de modèles candidats — le meilleur de chaque taille. La manière rigoureuse de choisir parmi eux est de demander lequel prédit le mieux sur de nouvelles données, estimé par validation croisée à k blocs (voir la validation croisée pour le traitement complet). Nous allons valider par validation croisée chaque taille de modèle et garder celle dont l’erreur est la plus basse.

Le plan est mécanique :

  1. Extraire les prédicteurs du meilleur modèle de chaque taille de l’objet regsubsets.
  2. Construire un workflow tidymodels pour ce modèle et estimer son erreur de prédiction par validation croisée à 5 blocs.
  3. Comparer les erreurs validées par validation croisée et choisir la plus petite.

D’abord, un petit utilitaire qui lit le jeu de variables gagnant pour une taille donnée dans la matrice which du summary et renvoie la formule du modèle :

library(leaps)
data("swiss")
models <- regsubsets(Fertility ~ ., data = swiss, nvmax = 5)

# Build the formula of the best `id`-variable model
get_model_formula <- function(id, object, outcome = "Fertility") {
  vars <- summary(object)$which[id, -1]          # drop the intercept column
  predictors <- names(which(vars))               # the included predictors
  as.formula(paste(outcome, "~", paste(predictors, collapse = " + ")))
}

# Check it on the best 4-variable model
get_model_formula(4, models)
Fertility ~ Agriculture + Education + Catholic + Infant.Mortality
<environment: 0x12655f498>

Cela confirme que le modèle à 4 variables est Fertility ~ Agriculture + Education + Catholic + Infant.Mortality. Validons maintenant chaque taille par validation croisée. Nous enveloppons le modèle dans un workflow (un recipe + une spécification parsnip de régression linéaire) et le passons dans fit_resamples() sur des découpages partagés à 5 blocs, de sorte que chaque modèle est jugé sur les mêmes blocs :

library(leaps)
library(rsample)
library(parsnip)
library(workflows)
library(recipes)
library(tune)
library(yardstick)
data("swiss")
models <- regsubsets(Fertility ~ ., data = swiss, nvmax = 5)

get_model_formula <- function(id, object, outcome = "Fertility") {
  vars <- summary(object)$which[id, -1]
  predictors <- names(which(vars))
  as.formula(paste(outcome, "~", paste(predictors, collapse = " + ")))
}

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

# Cross-validated RMSE for the best model of a given size
cv_rmse <- function(id) {
  wf <- workflow() |>
    add_recipe(recipe(get_model_formula(id, models), data = swiss)) |>
    add_model(lm_spec)
  set.seed(123)                                  # same folds for every model
  res <- fit_resamples(wf, resamples = vfold_cv(swiss, v = 5),
                       metrics = metric_set(rmse))
  collect_metrics(res)$mean
}

# Compare model sizes 1 through 5
cv_errors <- sapply(1:5, cv_rmse)
data.frame(n_pred = 1:5, CV_RMSE = round(cv_errors, 3))
  n_pred CV_RMSE
1      1   9.461
2      2   8.521
3      3   8.394
4      4   8.043
5      5   8.222
# The size with the lowest cross-validated error
which.min(cv_errors)
[1] 4

La validation croisée tranche : le modèle à 4 variables a l’erreur de prédiction la plus basse (CV RMSE ≈ 8.04), devançant le modèle complet à 5 variables — exactement ce que Cp et BIC prédisaient, désormais confirmé sur des données mises de côté. La préférence du R² ajusté pour les cinq prédicteurs était un mirage d’ajustement sur l’échantillon d’apprentissage. C’est tout l’intérêt de la validation : les critères ont réduit le champ, la validation croisée a choisi le gagnant.

Le modèle choisi

Fixez le modèle à 4 variables et lisez ses coefficients directement depuis l’objet regsubsets :

library(leaps)
data("swiss")
models <- regsubsets(Fertility ~ ., data = swiss, nvmax = 5)

# Coefficients of the best 4-variable model
coef(models, 4)
     (Intercept)      Agriculture        Education         Catholic 
      62.1013116       -0.1546175       -0.9802638        0.1246664 
Infant.Mortality 
       1.0784422 

Un modèle final propre et interprétable :

\[ \widehat{Fertility} = 62.10 - 0.155 \cdot Agriculture - 0.980 \cdot Education + 0.125 \cdot Catholic + 1.078 \cdot Infant.Mortality \]

Une éducation plus poussée et davantage d’agriculture sont associées à une fertilité plus faible, tandis qu’une part catholique plus grande et une mortalité infantile plus élevée vont de pair avec une fertilité plus élevée — et Examination a été abandonné comme redondant une fois Education présent. Pour ajuster ce modèle final de bout en bout au moyen d’un workflow tidymodels (et prédire sur de nouvelles provinces), passez sa formule au workflow exactement comme dans construire des modèles avec tidymodels.

AstuceÀ retenir, prêt à coller

« La régression best subsets sur les données swiss a privilégié un modèle à quatre prédicteurs (Agriculture, Education, Catholic, Infant.Mortality) : Cp et BIC ont tous deux atteint leur minimum à quatre variables, et la validation croisée à 5 blocs a confirmé qu’il prédit le mieux (CV RMSE ≈ 8.0), battant le modèle complet à cinq prédicteurs. »

Best subsets vs pas à pas : exhaustif vs glouton

La régression best subsets et la régression pas à pas résolvent le même problème — choisir un sous-ensemble — mais explorent l’espace différemment :

Best subsets Pas à pas
Recherche Exhaustive — chacun des 2ᵖ sous-ensembles Gloutonne — ajoute/retire une variable à la fois
Garantie Trouve le meilleur modèle de chaque taille Peut le manquer (dépend du chemin)
Coût 2ᵖ ajustements — explose avec p Environ ajustements — passe à l’échelle
À utiliser quand p est modeste (≲ 30–40) p est grand

La sélection pas à pas est plus rapide parce qu’elle ne revient jamais en arrière sur l’espace combinatoire complet — mais c’est aussi sa faiblesse : en s’engageant sur une variable à la fois, elle peut passer à côté du sous-ensemble globalement optimal. La best subsets ne le manque jamais, au prix de l’ajustement de 2ᵖ modèles. Avec nos 5 prédicteurs cela fait 32 ajustements — trivial. Avec 30 prédicteurs c’est plus d’un milliard, et avec 50 c’est sans espoir. C’est précisément ce mur combinatoire qui explique l’existence de la régression pas à pas et de la régression pénalisée pour les problèmes en grande dimension.

Tous trois partent de la somme des carrés des résidus (\(RSS\)) et ajoutent une pénalité pour la taille du modèle \(d\) (le nombre de prédicteurs), mais ils pénalisent différemment — ce qui explique pourquoi ils se contredisent.

Le R² ajusté met à l’échelle le \(R^2\) ordinaire par les degrés de liberté, de sorte qu’il peut baisser quand un prédicteur inutile est ajouté :

\[ R^2_{adj} = 1 - \frac{RSS / (n - d - 1)}{TSS / (n - 1)} . \]

Le Cp de Mallows estime l’erreur de test à partir du \(RSS\) d’apprentissage, en ajoutant \(2 d \hat{\sigma}^2\) — une pénalité de 2 par paramètre supplémentaire (avec \(\hat{\sigma}^2\) la variance d’erreur du modèle complet) :

\[ C_p = \frac{1}{n}\left( RSS + 2 d \, \hat{\sigma}^2 \right) . \]

Le BIC utilise une pénalité plus lourde de \(\log(n)\) par paramètre — pour tout échantillon avec \(n > 7\), \(\log(n) > 2\), donc le BIC pénalise plus la complexité que le Cp et tend par conséquent à sélectionner des modèles plus petits :

\[ BIC = \frac{1}{n}\left( RSS + \log(n)\, d \, \hat{\sigma}^2 \right) . \]

Le schéma est général : le R² ajusté est le plus permissif, le Cp est modéré, et le BIC est le plus strict — donc lorsqu’ils se contredisent, le BIC privilégie le modèle le plus dépouillé et le R² ajusté le plus complet. Aucun d’eux ne voit de nouvelles données, c’est pourquoi la validation croisée (erreur mesurée sur des blocs mis de côté) est l’arbitre.

Quelle méthode et quand

Un repère de décision rapide pour choisir des variables dans un modèle linéaire :

  • Une poignée de prédicteurs (≲ ~30), vous voulez le sous-ensemble prouvé optimal de chaque taillebest subsets (regsubsets), cette leçon.
  • Beaucoup de prédicteurs, vous voulez un modèle rapide et raisonnablela régression pas à pas.
  • Beaucoup de prédicteurs ou des prédicteurs corrélés, vous voulez une rétraction automatique / une sélection intégréela régression pénalisée (lasso / ridge / elastic net).
  • Vous avez choisi un modèle et voulez rapporter sa précision honnêtevalidation croisée + métriques de précision.
🟢 Avec un agent IA

Vous ne savez pas quels prédicteurs garder ? Demandez à Prova « lance une régression best subsets sur mes données et dis-moi quelle taille de modèle choisir » — elle répond avec du code leaps + tidymodels que vous pouvez exécuter sur vos propres données, ajuste chaque sous-ensemble, lit les critères Cp/BIC/R²-ajusté, et valide par validation croisée les finalistes pour que vous choisissiez le modèle qui prédit réellement le mieux. The runtime is the judge. Ask Prova →

Problèmes courants

  • regsubsets() ne renvoie que jusqu’à 8 variables. La valeur par défaut est nvmax = 8. Pour explorer des modèles plus grands, réglez nvmax sur votre nombre de prédicteurs (par ex. nvmax = ncol(data) - 1). Pour un p bien supérieur à ~30, la recherche exhaustive devient irréalisable — passez à la régression pas à pas ou la régression pénalisée.
  • Vos trois critères choisissent des modèles différents. C’est normal, pas un bug — le R² ajusté, le Cp et le BIC encodent des compromis ajustement-vs-complexité différents (BIC le plus strict, R² ajusté le plus permissif). Ne vous tracassez pas sur le désaccord ; validez les candidats par validation croisée et laissez l’erreur hors échantillon décider.
  • Vous avez choisi le modèle au R² le plus élevé et il prédit mal. Le R² brut monte toujours avec plus de prédicteurs, donc il choisira toujours le plus gros modèle — c’est du surapprentissage. Utilisez le R² ajusté (ou le Cp / le BIC), et validez par validation croisée, jamais le R² brut.
  • coef(models, id) renvoie les mauvaises variables. L’id est la taille du modèle, pas un indice de variable — coef(models, 4) donne le meilleur modèle à 4 variables. Confirmez quelles variables cette taille inclut avec summary(models)$which[4, ].

Questions fréquentes

La sélection best subset (régression best subsets) ajuste toutes les combinaisons possibles de vos prédicteurs et garde le meilleur modèle de chaque taille, puis compare ces modèles sur un critère comme le R² ajusté, le Cp ou le BIC. En R, cela se fait avec leaps::regsubsets(y ~ ., data, nvmax = p), où nvmax est la plus grande taille de modèle à considérer. Parce qu’elle est exhaustive, elle trouve le sous-ensemble prouvé optimal de chaque taille — mais seulement pour un nombre modeste de prédicteurs.

Appelez models <- regsubsets(Fertility ~ ., data = swiss, nvmax = 5) pour ajuster le meilleur modèle de chaque taille jusqu’à nvmax, puis summary(models) pour voir quelles variables chaque meilleur modèle inclut (marquées d’un *) plus les critères adjr2, cp et bic. Utilisez which.max(summary(models)$adjr2) et which.min(summary(models)$cp) / $bic pour trouver la taille préférée de chaque critère, et coef(models, id) pour lire les coefficients du meilleur modèle à id variables.

Ne vous fiez pas à un seul nombre. Utilisez les critères pénalisés de summary(regsubsets()) pour réduire le champ — maximisez le R² ajusté, minimisez le Cp et le BIC — et quand ils se contredisent (souvent), tranchez le débat par validation croisée à k blocs : validez par validation croisée le meilleur modèle de chaque taille et choisissez celui dont l’erreur de prédiction est la plus basse, car elle est mesurée sur des données sur lesquelles le modèle ne s’est pas entraîné.

La best subsets explore exhaustivement — elle ajuste les 2ᵖ combinaisons de prédicteurs et est garantie de trouver le meilleur modèle de chaque taille, mais le coût explose avec le nombre de prédicteurs p. La pas à pas est gloutonne — elle ajoute ou retire une variable à la fois, ce qui est bien moins coûteux (≈ p² ajustements) et passe à l’échelle pour de nombreux prédicteurs, mais elle peut manquer le sous-ensemble globalement optimal. Utilisez la best subsets pour un p modeste ; passez à la pas à pas ou à la régression pénalisée quand p est grand.

Parce qu’elle est exhaustive : avec p prédicteurs il y a 2ᵖ sous-ensembles possibles à ajuster. Cinq prédicteurs font 32 modèles (trivial), mais 30 prédicteurs font plus d’un milliard et 50 est sans espoir sur le plan calculatoire. Pour les problèmes en grande dimension, utilisez une méthode qui n’énumère pas tous les sous-ensembles — la régression pas à pas (gloutonne) ou la régression pénalisée (lasso / ridge, qui rétractent les coefficients et sélectionnent les variables automatiquement).

Testez vos connaissances

Utilisez le jeu de données mtcars, en prédisant mpg à partir des 10 autres variables. Ajustez la best subsets avec regsubsets(mpg ~ ., data = mtcars, nvmax = 10), puis trouvez quelle taille de modèle minimise le BIC et lisez les coefficients de ce modèle. Combien de prédicteurs le BIC garde-t-il ?

Vous avez besoin du paquet leaps. Après l’ajustement, récupérez res <- summary(models), puis which.min(res$bic) pour la meilleure taille et coef(models, <cette taille>) pour les coefficients.

library(leaps)
data("mtcars")

models <- regsubsets(mpg ~ ., data = mtcars, nvmax = 10)
res    <- summary(models)

# Size that minimizes BIC, and its coefficients
best_size <- which.min(res$bic)
best_size
coef(models, best_size)

La forte pénalité de complexité du BIC garde un petit modèle — typiquement juste wt, qsec et am (un modèle à trois prédicteurs). Un critère plus permissif comme le R² ajusté (which.max(res$adjr2)) garderait plus de variables. Comme dans la leçon, validez les finalistes par validation croisée avant de vous décider.

Vérification rapide. Votre exécution de regsubsets rapporte que le R² ajusté est maximisé à 6 prédicteurs mais que le BIC est minimisé à 3. Quel modèle est « le meilleur », et comment décidez-vous ?

Aucun critère n’est automatiquement juste — ils se contredisent parce que le BIC pénalise les prédicteurs supplémentaires bien plus lourdement que le R² ajusté, donc il privilégie le modèle plus dépouillé à 3 variables tandis que le R² ajusté tolère le plus gros. Le désaccord est votre signal pour valider par validation croisée : estimez l’erreur de prédiction de chaque candidat sur des blocs mis de côté (vfold_cv() + fit_resamples()) et choisissez le modèle dont l’erreur validée par validation croisée est la plus basse — l’arbitre honnête, hors échantillon.

Conclusion

Vous avez exécuté le workflow best subsets complet sur les données swiss : leaps::regsubsets(nvmax = 5) a ajusté le meilleur modèle de chaque taille, vous les avez comparés par R² ajusté, Cp et BIC — en lisant les graphiques critère-vs-taille pour voir Cp et BIC atteindre tous deux leur minimum à 4 prédicteurs tandis que le R² ajusté plafonnait — puis vous avez validé par validation croisée les candidats pour que le choix repose sur une erreur honnête hors échantillon, et non sur l’ajustement à l’échantillon d’apprentissage. Le modèle à 4 variables (Agriculture + Education + Catholic + Infant.Mortality) l’a emporté. La seule limite de la méthode est sa force : elle est exhaustive, donc parfaite pour un nombre modeste de prédicteurs et irréalisable pour beaucoup.

Ensuite, découvrez l’alternative gloutonne qui passe à l’échelle dans la régression pas à pas, ou l’approche par rétraction qui sélectionne et régularise à la fois dans la 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 résultat 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.)
  • Kuhn, M., & Silge, J. Tidy Modeling with R. (Rééchantillonnage et comparaison de modèles.) En ligne, gratuit (CC BY-NC-SA).

Réutilisation

Citation

BibTeX
@online{2026,
  author = {},
  title = {Régression best subsets en R : sélection de variables avec
    leaps},
  date = {2026-06-25},
  url = {https://www.datanovia.com/learn/machine-learning/model-selection/best-subsets-regression},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
“Régression best subsets en R : sélection de variables avec leaps.” 2026. June 25. https://www.datanovia.com/learn/machine-learning/model-selection/best-subsets-regression.