W3docs

Bootstrap Aggregation (Bagging) em Python

Aprenda como o bagging reduz a variância em modelos de ML e como implementar BaggingClassifier em Python com scikit-learn.

Bootstrap aggregation — comumente chamado de bagging — é uma técnica de ensemble que treina múltiplos modelos em amostras aleatórias diferentes dos seus dados e, em seguida, combina suas previsões. O resultado é um modelo menos sensível a ruído e valores discrepantes, e que generaliza melhor para dados não vistos do que qualquer modelo individual treinado no conjunto de dados completo.

Este capítulo aborda:

  • O que é amostragem bootstrap e por que ela ajuda
  • O tradeoff entre viés e variância que o bagging resolve
  • Como implementar BaggingClassifier e BaggingRegressor com scikit-learn
  • Principais hiperparâmetros e como ajustá-los
  • Erro out-of-bag (OOB) como estimativa gratuita de validação
  • Quando o bagging ajuda e quando preferir outros métodos

Como funciona a amostragem bootstrap

A palavra bootstrap refere-se à amostragem com reposição. Dado um conjunto de dados com n exemplos, uma amostra bootstrap é criada sorteando n exemplos aleatoriamente, onde cada sorteio é independente e o mesmo exemplo pode aparecer mais de uma vez.

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)

Saída:

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]

Em média, uma amostra bootstrap contém cerca de 63 % dos exemplos únicos originais; os 37 % restantes ficam de fora. Esses exemplos out-of-bag (OOB) podem ser usados como um conjunto de validação integrado, sem necessidade de uma divisão separada de hold-out.

O tradeoff entre viés e variância

Todo modelo faz previsões com alguma combinação de viés (erro sistemático decorrente de suposições incorretas) e variância (sensibilidade a flutuações nos dados de treinamento). O bagging tem como alvo modelos com alta variância e baixo viés — especialmente árvores de decisão profundas.

Uma única árvore de decisão não podada pode memorizar perfeitamente o conjunto de treinamento, mas falha muito em dados novos. Ao calcular a média das previsões de muitas árvores, cada uma treinada em uma amostra bootstrap ligeiramente diferente, as flutuações aleatórias se cancelam e a variância cai — sem aumentar significativamente o viés.

O bagging não ajuda modelos que já têm alto viés (por exemplo, modelos lineares rasos), porque a média de muitos modelos enviesados ainda produz uma resposta enviesada. Para esses casos, métodos de boosting como Gradient Boosting são mais adequados.

Implementando BaggingClassifier

O scikit-learn fornece BaggingClassifier para tarefas de classificação. O exemplo abaixo compara uma única árvore de decisão com um ensemble de bagging no conjunto de dados de câncer de mama.

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}")

Saída:

Single tree accuracy:  0.95
Bagging accuracy:      0.96

O modelo com bagging supera a árvore individual. Em conjuntos de dados mais ruidosos ou menores, a margem costuma ser maior.

Principais parâmetros do construtor

ParâmetroPadrãoO que controla
estimatorDecisionTreeClassifier()O aprendiz base a ser agrupado
n_estimators10Número de modelos a treinar
max_samples1.0Fração (ou quantidade) de linhas de treinamento por amostra bootstrap
max_features1.0Fração (ou quantidade) de features sorteadas para cada aprendiz base
bootstrapTrueAmostra linhas com reposição; defina False para pasting
bootstrap_featuresFalseTambém amostra features com reposição
oob_scoreFalseEstima a generalização usando exemplos out-of-bag

Erro out-of-bag (OOB)

Como cada aprendiz base vê apenas cerca de 63 % dos dados de treinamento, os 37 % restantes podem ser usados para avaliar esse aprendiz sem tocar no conjunto de teste. A média dessas avaliações OOB em todos os estimadores fornece o OOB score — uma estimativa quase gratuita da acurácia no teste.

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}")

Saída:

OOB score: 0.96

O OOB score é próximo da acurácia no teste reservado, tornando-o útil como uma verificação rápida de sanidade — especialmente quando seu conjunto de dados é pequeno demais para ter uma divisão de validação separada. Para uma estimativa mais rigorosa, combine o bagging com validação cruzada.

BaggingRegressor

O bagging é igualmente útil para regressão. Substitua BaggingClassifier por BaggingRegressor e escolha um aprendiz base de regressão.

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}")

Saída:

BaggingRegressor RMSE: 0.5080

Avaliando com validação cruzada

Uma única divisão treino-teste pode fornecer uma imagem excessivamente otimista ou pessimista, dependendo de quais exemplos caem em cada partição. Executar a validação cruzada calcula a média do resultado em múltiplas divisões para uma pontuação mais confiável.

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}")

Saída:

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

Um desvio padrão baixo entre as dobras significa que o modelo generaliza de forma consistente. Um desvio padrão alto sugere que o modelo é sensível a quais dados acabam em cada dobra.

Bagging vs. Random Forest

Random Forest é o algoritmo baseado em bagging mais popular. Ele estende o bagging simples ao também selecionar aleatoriamente um subconjunto de features em cada decisão de divisão — não apenas um subconjunto de linhas — o que descorrelaciona ainda mais as árvores e geralmente produz melhor acurácia.

BaggingRandom Forest
Amostragem de linhasBootstrap (com reposição)Bootstrap (com reposição)
Amostragem de featuresOpcional (max_features)Sempre, em cada divisão
Aprendiz baseQualquer estimadorSomente árvore de decisão
InterpretabilidadeBaixaBaixa
Uso típicoQuando se quer aplicar bagging a um modelo não-árvoreMelhor baseline de ensemble geral

Quando você estiver aplicando bagging em árvores de decisão, RandomForestClassifier é quase sempre a melhor escolha. Use BaggingClassifier quando quiser aplicar bagging a um aprendiz base diferente — por exemplo, um KNeighborsClassifier do K-Nearest Neighbors ou uma regressão logística da Regressão Logística.

Quando usar bagging

O bagging é mais eficaz quando:

  • Seu modelo base tem alta variância (árvores de decisão profundas, modelos polinomiais de alto grau).
  • Você tem dados suficientes para tornar as amostras bootstrap diversas e significativas.
  • Você pode usar treinamento paralelo, pois cada aprendiz base treina de forma independente e a carga de trabalho pode ser distribuída entre núcleos de CPU (n_jobs=-1).

É menos útil quando:

  • O modelo base já tem baixa variância (por exemplo, modelos lineares com regularização forte).
  • Você precisa de um modelo único e interpretável — um ensemble de 50 árvores não é fácil de explicar a um stakeholder.
  • O custo computacional importa mais do que a acurácia — treinar 50 modelos é 50 vezes mais lento do que treinar um.

Para modelos com alto viés, considere o Grid Search para ajustar hiperparâmetros, ou troque para um método de boosting. Para avaliação, sempre verifique seu modelo em uma divisão reservada criada com divisão treino-teste ou com validação cruzada.

Resumo

  • Bootstrap aggregation treina muitos aprendizes base em amostras aleatórias dos dados (sorteadas com reposição) e calcula a média de suas previsões.
  • Reduz a variância sem aumentar significativamente o viés, tornando-o ideal para modelos de alta variância, como árvores de decisão profundas.
  • O scikit-learn fornece BaggingClassifier e BaggingRegressor; os principais parâmetros são n_estimators, max_samples e max_features.
  • Ative oob_score=True para obter uma estimativa gratuita de generalização que não exige um conjunto de validação separado.
  • Ao aplicar bagging em árvores, RandomForestClassifier geralmente é preferível; use BaggingClassifier para aplicar bagging em outros tipos de modelos.
Was this page helpful?