W3docs

Agregación Bootstrap (Bagging) en Python

Aprende cómo el bagging reduce la varianza en modelos ML y cómo implementar BaggingClassifier en Python con scikit-learn.

La agregación Bootstrap — comúnmente llamada bagging — es una técnica de conjunto que entrena múltiples modelos sobre distintas muestras aleatorias de los datos y luego combina sus predicciones. El resultado es un modelo menos sensible al ruido y a los valores atípicos, que generaliza mejor ante datos no vistos que cualquier modelo individual entrenado con el conjunto completo.

Este capítulo abarca:

  • Qué es el muestreo bootstrap y por qué resulta útil
  • El compromiso sesgo–varianza que el bagging aborda
  • Cómo implementar BaggingClassifier y BaggingRegressor con scikit-learn
  • Los hiperparámetros clave y cómo ajustarlos
  • El error fuera de bolsa (OOB) como estimación gratuita de validación
  • Cuándo conviene usar bagging y cuándo preferir otros métodos

Cómo funciona el muestreo bootstrap

La palabra bootstrap hace referencia al muestreo con reemplazo. Dado un conjunto de datos de n ejemplos, una muestra bootstrap se crea extrayendo n ejemplos al azar, donde cada extracción es independiente y el mismo ejemplo puede aparecer más de una 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)

Salida:

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 promedio, una muestra bootstrap contiene alrededor del 63 % de los ejemplos originales únicos; el 37 % restante queda fuera. Estos ejemplos fuera de bolsa (OOB) pueden usarse como conjunto de validación integrado sin necesidad de una partición de retención separada.

El compromiso sesgo–varianza

Todo modelo realiza predicciones con alguna combinación de sesgo (error sistemático derivado de suposiciones incorrectas) y varianza (sensibilidad a las fluctuaciones en los datos de entrenamiento). El bagging apunta a modelos con alta varianza y bajo sesgo — en particular, árboles de decisión profundos.

Un único árbol de decisión sin poda puede memorizar perfectamente el conjunto de entrenamiento, pero falla notablemente con datos nuevos. Al promediar las predicciones de muchos árboles, cada uno entrenado con una muestra bootstrap ligeramente distinta, las fluctuaciones aleatorias se cancelan y la varianza disminuye — sin incrementar el sesgo de manera significativa.

El bagging no ayuda a modelos que ya tienen alto sesgo (por ejemplo, modelos lineales poco profundos), porque promediar muchos modelos sesgados sigue produciendo una respuesta sesgada. Para esos casos, los métodos de boosting como Gradient Boosting son más apropiados.

Implementando BaggingClassifier

scikit-learn proporciona BaggingClassifier para tareas de clasificación. El ejemplo a continuación compara un único árbol de decisión contra un conjunto basado en bagging sobre el conjunto de datos 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}")

Salida:

Single tree accuracy:  0.95
Bagging accuracy:      0.96

El modelo con bagging supera al árbol individual. En conjuntos de datos más ruidosos o pequeños, la diferencia suele ser mayor.

Parámetros clave del constructor

ParámetroValor por defectoLo que controla
estimatorDecisionTreeClassifier()El aprendiz base a agregar
n_estimators10Número de modelos a entrenar
max_samples1.0Fracción (o cantidad) de filas de entrenamiento por muestra bootstrap
max_features1.0Fracción (o cantidad) de características para cada aprendiz base
bootstrapTrueMuestrea filas con reemplazo; usa False para pegado (pasting)
bootstrap_featuresFalseTambién muestrea características con reemplazo
oob_scoreFalseEstima la generalización usando ejemplos fuera de bolsa

Error fuera de bolsa (OOB)

Como cada aprendiz base solo ve aproximadamente el 63 % de los datos de entrenamiento, el 37 % restante puede usarse para evaluar ese aprendiz sin tocar el conjunto de prueba. Promediar estas evaluaciones OOB entre todos los estimadores produce la puntuación OOB — una estimación casi gratuita de la precisión en prueba.

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

Salida:

OOB score: 0.96

La puntuación OOB es cercana a la precisión del conjunto de prueba retenido, lo que la hace útil como verificación rápida — especialmente cuando el conjunto de datos es demasiado pequeño para dedicar una partición de validación separada. Para una estimación más rigurosa, combina el bagging con validación cruzada.

BaggingRegressor

El bagging es igualmente útil para regresión. Reemplaza BaggingClassifier con BaggingRegressor y elige un aprendiz base de regresión.

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

Salida:

BaggingRegressor RMSE: 0.5080

Evaluación con validación cruzada

Una sola partición entrenamiento-prueba puede ofrecer una imagen demasiado optimista o pesimista dependiendo de qué ejemplos caen en cada partición. Ejecutar validación cruzada promedia el resultado entre múltiples particiones para obtener una puntuación más confiable.

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

Salida:

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

Una desviación estándar baja entre los pliegues indica que el modelo generaliza de forma consistente. Una desviación estándar alta sugiere que el modelo es sensible a qué datos terminan en cada pliegue.

Bagging vs. Random Forest

Random Forest es el algoritmo basado en bagging más popular. Extiende el bagging simple seleccionando también aleatoriamente un subconjunto de características en cada decisión de división — no solo un subconjunto de filas —, lo que descorrelaciona aún más los árboles y generalmente produce mejor precisión.

BaggingRandom Forest
Muestreo de filasBootstrap (con reemplazo)Bootstrap (con reemplazo)
Muestreo de característicasOpcional (max_features)Siempre, en cada división
Aprendiz baseCualquier estimadorSolo árbol de decisión
InterpretabilidadBajaBaja
Uso típicoCuando deseas agregar un modelo no basado en árbolesMejor línea base de conjunto general

Cuando se agregan árboles de decisión con bagging, RandomForestClassifier es casi siempre la mejor opción. Usa BaggingClassifier cuando quieras agregar un aprendiz base distinto — por ejemplo, un KNeighborsClassifier de K-Nearest Neighbors o una regresión logística de Logistic Regression.

Cuándo usar bagging

El bagging es más efectivo cuando:

  • Tu modelo base tiene alta varianza (árboles de decisión profundos, modelos polinomiales de alto grado).
  • Tienes suficientes datos para que las muestras bootstrap diversas sean significativas.
  • Puedes costear el entrenamiento en paralelo, porque cada aprendiz base se entrena de forma independiente y la carga de trabajo puede distribuirse entre núcleos de CPU (n_jobs=-1).

Es menos útil cuando:

  • El modelo base ya tiene baja varianza (por ejemplo, modelos lineales con regularización fuerte).
  • Necesitas un modelo único e interpretable — un conjunto de 50 árboles no es fácil de explicar a un interesado.
  • El costo computacional importa más que la precisión — entrenar 50 modelos es 50 veces más lento que entrenar uno.

Para modelos con alto sesgo, considera Grid Search para ajustar hiperparámetros, o cambia a un método de boosting. Para la evaluación, verifica siempre tu modelo en una partición retenida creada con train-test split o con validación cruzada.

Resumen

  • La agregación Bootstrap entrena muchos aprendices base sobre muestras aleatorias de los datos (extraídas con reemplazo) y promedia sus predicciones.
  • Reduce la varianza sin incrementar significativamente el sesgo, lo que la hace ideal para modelos con alta varianza como los árboles de decisión profundos.
  • scikit-learn proporciona BaggingClassifier y BaggingRegressor; los parámetros clave son n_estimators, max_samples y max_features.
  • Activa oob_score=True para obtener una estimación gratuita de generalización que no requiere un conjunto de validación separado.
  • Cuando se agregan árboles con bagging, RandomForestClassifier suele ser preferible; usa BaggingClassifier para agregar otros tipos de modelos.
Was this page helpful?