W3docs

Agrégation Bootstrap (Bagging) en Python

Apprenez comment le bagging réduit la variance des modèles ML, quand l'utiliser et comment implémenter BaggingClassifier en Python.

L'agrégation Bootstrap — communément appelée bagging — est une technique d'ensemble qui entraîne plusieurs modèles sur différents échantillons aléatoires de vos données, puis combine leurs prédictions. Le résultat est un modèle moins sensible au bruit et aux valeurs aberrantes, qui généralise mieux sur des données inconnues qu'un seul modèle entraîné sur l'intégralité du jeu de données.

Ce chapitre aborde :

  • Ce qu'est l'échantillonnage Bootstrap et pourquoi il est utile
  • Le compromis biais–variance que le bagging résout
  • Comment implémenter BaggingClassifier et BaggingRegressor avec scikit-learn
  • Les hyperparamètres clés et comment les ajuster
  • L'erreur hors-sac (OOB) comme estimation de validation gratuite
  • Quand le bagging est utile et quand préférer d'autres méthodes

Comment fonctionne l'échantillonnage Bootstrap

Le mot bootstrap désigne un échantillonnage avec remise. Pour un jeu de données de n exemples, un échantillon Bootstrap est créé en tirant n exemples au hasard, chaque tirage étant indépendant et le même exemple pouvant apparaître plus d'une fois.

import numpy as np

rng = np.random.default_rng(42)
data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

bootstrap_sample = rng.choice(data, size=len(data), replace=True)
out_of_bag = np.setdiff1d(data, bootstrap_sample)

print("Original data:   ", data)
print("Bootstrap sample:", bootstrap_sample)
print("Out-of-bag:      ", out_of_bag)

Sortie :

Original data:    [ 1  2  3  4  5  6  7  8  9 10]
Bootstrap sample: [1 8 7 5 5 9 1 7 3 1]
Out-of-bag:       [ 2  4  6 10]

En moyenne, un échantillon Bootstrap contient environ 63 % des exemples originaux uniques ; les 37 % restants sont exclus. Ces exemples hors-sac (OOB) peuvent être utilisés comme ensemble de validation intégré sans avoir besoin d'une division de validation séparée.

Le compromis biais–variance

Chaque modèle effectue des prédictions avec une combinaison de biais (erreur systématique due à des hypothèses incorrectes) et de variance (sensibilité aux fluctuations des données d'entraînement). Le bagging cible les modèles à haute variance et faible biais — en particulier les arbres de décision profonds.

Un seul arbre de décision non élagué peut mémoriser parfaitement l'ensemble d'entraînement, mais échoue sur de nouvelles données. En moyennant les prédictions de nombreux arbres, chacun entraîné sur un échantillon Bootstrap légèrement différent, les fluctuations aléatoires s'annulent et la variance diminue — sans augmenter significativement le biais.

Le bagging n'aide pas les modèles qui ont déjà un biais élevé (par exemple, les modèles linéaires peu profonds), car moyenner de nombreux modèles biaisés donne toujours une réponse biaisée. Dans ces cas, des méthodes de boosting comme le Gradient Boosting sont plus appropriées.

Implémentation de BaggingClassifier

scikit-learn fournit BaggingClassifier pour les tâches de classification. L'exemple ci-dessous compare un seul arbre de décision à un ensemble de bagging sur le jeu de données du cancer du sein.

from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn.metrics import accuracy_score

# Load dataset
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# Baseline: single decision tree
single_tree = DecisionTreeClassifier(random_state=42)
single_tree.fit(X_train, y_train)
single_acc = accuracy_score(y_test, single_tree.predict(X_test))

# Bagging ensemble of 50 decision trees
bagging_model = BaggingClassifier(
    estimator=DecisionTreeClassifier(),
    n_estimators=50,
    random_state=42,
)
bagging_model.fit(X_train, y_train)
bagging_acc = accuracy_score(y_test, bagging_model.predict(X_test))

print(f"Single tree accuracy:  {single_acc:.2f}")
print(f"Bagging accuracy:      {bagging_acc:.2f}")

Sortie :

Single tree accuracy:  0.95
Bagging accuracy:      0.96

Le modèle avec bagging surpasse l'arbre unique. Sur des jeux de données plus bruités ou plus petits, la marge est généralement plus grande.

Paramètres clés du constructeur

ParamètreDéfautCe qu'il contrôle
estimatorDecisionTreeClassifier()L'apprenant de base à agréger
n_estimators10Nombre de modèles à entraîner
max_samples1.0Fraction (ou nombre) de lignes d'entraînement par échantillon Bootstrap
max_features1.0Fraction (ou nombre) de caractéristiques tirées pour chaque apprenant de base
bootstrapTrueÉchantillonnage de lignes avec remise ; mettre False pour le collage
bootstrap_featuresFalseÉgalement échantillonner les caractéristiques avec remise
oob_scoreFalseEstimer la généralisation en utilisant les exemples hors-sac

Erreur hors-sac (OOB)

Comme chaque apprenant de base ne voit qu'environ 63 % des données d'entraînement, les 37 % restants peuvent être utilisés pour évaluer cet apprenant sans toucher à l'ensemble de test. La moyenne de ces évaluations OOB sur tous les estimateurs donne le score OOB — une estimation presque gratuite de la précision de test.

from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer

X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

bagging_oob = BaggingClassifier(
    estimator=DecisionTreeClassifier(),
    n_estimators=50,
    oob_score=True,      # enable OOB evaluation
    random_state=42,
)
bagging_oob.fit(X_train, y_train)

print(f"OOB score: {bagging_oob.oob_score_:.2f}")

Sortie :

OOB score: 0.96

Le score OOB est proche de la précision sur l'ensemble de test retenu, ce qui le rend utile comme vérification rapide — surtout quand votre jeu de données est trop petit pour se permettre une division de validation séparée. Pour une estimation plus rigoureuse, combinez le bagging avec la validation croisée.

BaggingRegressor

Le bagging est tout aussi utile pour la régression. Remplacez BaggingClassifier par BaggingRegressor et choisissez un apprenant de base pour la régression.

from sklearn.ensemble import BaggingRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.model_selection import train_test_split
from sklearn.datasets import fetch_california_housing
from sklearn.metrics import mean_squared_error
import numpy as np

X, y = fetch_california_housing(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

bagging_reg = BaggingRegressor(
    estimator=DecisionTreeRegressor(),
    n_estimators=50,
    random_state=42,
)
bagging_reg.fit(X_train, y_train)

rmse = np.sqrt(mean_squared_error(y_test, bagging_reg.predict(X_test)))
print(f"BaggingRegressor RMSE: {rmse:.4f}")

Sortie :

BaggingRegressor RMSE: 0.5080

Évaluation avec la validation croisée

Une seule division entraînement-test peut donner une image trop optimiste ou trop pessimiste selon les exemples qui se retrouvent dans chaque partition. L'utilisation de la validation croisée moyenne le résultat sur plusieurs divisions pour un score plus fiable.

from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_breast_cancer
import numpy as np

X, y = load_breast_cancer(return_X_y=True)

clf = BaggingClassifier(
    estimator=DecisionTreeClassifier(),
    n_estimators=50,
    random_state=42,
)

scores = cross_val_score(clf, X, y, cv=5)
print(f"CV scores: {scores.round(4)}")
print(f"Mean: {scores.mean():.4f}, Std: {scores.std():.4f}")

Sortie :

CV scores: [0.9123 0.9211 0.9825 0.9561 1.    ]
Mean: 0.9544, Std: 0.0339

Un faible écart-type entre les plis signifie que le modèle généralise de manière cohérente. Un écart-type élevé suggère que le modèle est sensible aux données qui se retrouvent dans chaque pli.

Bagging vs. Random Forest

Random Forest est l'algorithme basé sur le bagging le plus populaire. Il étend le bagging simple en sélectionnant aléatoirement un sous-ensemble de caractéristiques à chaque décision de division — pas seulement un sous-ensemble de lignes — ce qui décorrèle davantage les arbres et donne souvent une meilleure précision.

BaggingRandom Forest
Échantillonnage de lignesBootstrap (avec remise)Bootstrap (avec remise)
Échantillonnage de caractéristiquesOptionnel (max_features)Toujours, à chaque division
Apprenant de baseN'importe quel estimateurArbre de décision uniquement
InterprétabilitéFaibleFaible
Utilisation typiqueQuand vous voulez agréger un modèle non arborescentMeilleure base d'ensemble polyvalente

Lorsque vous agrégez des arbres de décision, RandomForestClassifier est presque toujours le meilleur choix. Utilisez BaggingClassifier quand vous souhaitez agréger un apprenant de base différent — par exemple, un KNeighborsClassifier issu de K-Nearest Neighbors ou une régression logistique issue de Logistic Regression.

Quand utiliser le bagging

Le bagging est le plus efficace quand :

  • Votre modèle de base a une haute variance (arbres de décision profonds, modèles polynomiaux de haut degré).
  • Vous disposez de suffisamment de données pour que des échantillons Bootstrap diversifiés soient significatifs.
  • Vous pouvez vous permettre un entraînement parallèle, car chaque apprenant de base s'entraîne indépendamment et la charge de travail peut être distribuée sur les cœurs CPU (n_jobs=-1).

Il est moins utile quand :

  • Le modèle de base a déjà une faible variance (par exemple, des modèles linéaires avec une forte régularisation).
  • Vous avez besoin d'un modèle unique et interprétable — un ensemble de 50 arbres n'est pas facile à expliquer à un décideur.
  • Le coût de calcul importe plus que la précision — entraîner 50 modèles est 50 fois plus lent qu'en entraîner un seul.

Pour les modèles à fort biais, envisagez la recherche en grille pour ajuster les hyperparamètres, ou passez à une méthode de boosting. Pour l'évaluation, vérifiez toujours votre modèle sur une division retenue créée avec train-test split ou avec la validation croisée.

Résumé

  • L'agrégation Bootstrap entraîne de nombreux apprenants de base sur des échantillons aléatoires de données (tirés avec remise) et moyenne leurs prédictions.
  • Elle réduit la variance sans augmenter significativement le biais, ce qui la rend idéale pour les modèles à haute variance comme les arbres de décision profonds.
  • scikit-learn fournit BaggingClassifier et BaggingRegressor ; les paramètres clés sont n_estimators, max_samples et max_features.
  • Activez oob_score=True pour une estimation de généralisation gratuite qui ne nécessite pas d'ensemble de validation séparé.
  • Lors de l'agrégation d'arbres, RandomForestClassifier est généralement préférable ; utilisez BaggingClassifier pour agréger d'autres types de modèles.
Was this page helpful?