Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое bagging?
Bagging (Bootstrap Aggregating) — это метод ансамбля, который создаёт несколько подвыборок из исходного датасета с повторениями (bootstrap), обучает на каждой отдельную модель, а затем усредняет предсказания. Цель — снизить дисперсию и улучшить обобщаемость.
Основная идея
1. Берём исходный датасет (n примеров)
2. Создаём k подвыборок размером n с повторениями (sampling with replacement)
3. На каждой подвыборке обучаем модель (обычно одного типа)
4. Предсказания усредняются или комбинируются
Математическое объяснение
Исходная дисперсия модели:
Var(y) = σ²
Дисперсия ансамбля из k независимых моделей:
Var(ансамбль) = σ²/k (если модели идеально некоррелированы)
На практике:
Var(ансамбль) ≈ σ² × (ρ + (1-ρ)/k)
где:
- ρ — средняя корреляция между моделями
- k — количество моделей в ансамбле
When k → ∞, дисперсия стремится к σ² × ρ (остаётся корреляция ошибок)
Практическая реализация (с нуля)
import numpy as np
from sklearn.datasets import make_classification
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
def bagging_manual(X, y, n_models=10, sample_size=None):
"""Простой bagging с нуля"""
if sample_size is None:
sample_size = len(X)
n_samples = len(X)
models = []
for _ in range(n_models):
# Bootstrap: случайная выборка с повторениями
indices = np.random.choice(n_samples, size=sample_size, replace=True)
X_bootstrap = X[indices]
y_bootstrap = y[indices]
# Обучаем модель на bootstrap выборке
model = DecisionTreeClassifier(max_depth=5, random_state=None)
model.fit(X_bootstrap, y_bootstrap)
models.append(model)
return models
def bagging_predict(models, X):
"""Усреднение предсказаний"""
predictions = np.array([model.predict(X) for model in models])
# Voting классификатор — берём режим (самый частый класс)
y_pred = np.apply_along_axis(lambda x: np.bincount(x).argmax(), 0, predictions)
return y_pred
def bagging_predict_proba(models, X):
"""Усреднение вероятностей"""
predictions = np.array([model.predict_proba(X) for model in models])
# Усреднение вероятностей по моделям
return np.mean(predictions, axis=0)
# Использование
X, y = make_classification(n_samples=200, n_features=20, n_classes=2, random_state=42)
models = bagging_manual(X, y, n_models=10)
y_pred = bagging_predict(models, X)
accuracy = accuracy_score(y, y_pred)
print(f"Accuracy (Bagging): {accuracy:.4f}")
Встроенная реализация (scikit-learn)
from sklearn.ensemble import BaggingClassifier, BaggingRegressor
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LinearRegression
# Классификация
bagging_clf = BaggingClassifier(
estimator=DecisionTreeClassifier(max_depth=5),
n_estimators=100, # Количество базовых моделей
max_samples=0.8, # 80% примеров в каждой выборке
max_features=0.8, # 80% признаков в каждой выборке
bootstrap=True, # С повторениями
random_state=42
)
bagging_clf.fit(X_train, y_train)
y_pred = bagging_clf.predict(X_test)
y_pred_proba = bagging_clf.predict_proba(X_test)
# Регрессия
bagging_reg = BaggingRegressor(
estimator=LinearRegression(),
n_estimators=50,
max_samples=1.0,
max_features=1.0,
random_state=42
)
bagging_reg.fit(X_train, y_train)
y_pred = bagging_reg.predict(X_test)
Сравнение: Баггинг vs Бустинг
from sklearn.ensemble import (
BaggingClassifier,
AdaBoostClassifier,
GradientBoostingClassifier
)
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
X, y = make_classification(n_samples=300, n_features=20, random_state=42)
# Bagging (параллельное обучение)
bagging = BaggingClassifier(
DecisionTreeClassifier(max_depth=5),
n_estimators=50
)
# Boosting (последовательное обучение)
adaboost = AdaBoostClassifier(
DecisionTreeClassifier(max_depth=3),
n_estimators=50
)
gradboost = GradientBoostingClassifier(
n_estimators=50,
learning_rate=0.1
)
# Сравнение
for name, model in [("Bagging", bagging), ("AdaBoost", adaboost), ("GradBoost", gradboost)]:
scores = cross_val_score(model, X, y, cv=5)
print(f"{name}: {scores.mean():.4f} (+/- {scores.std():.4f})")
# Output обычно показывает:
# Bagging: 0.85 (+/- 0.03)
# AdaBoost: 0.88 (+/- 0.02) — лучше (фокусируется на ошибках)
# GradBoost: 0.92 (+/- 0.01) — лучше всех (более сложный)
Случайные леса (Random Forest) — это специальный случай Bagging
from sklearn.ensemble import RandomForestClassifier
# Random Forest = Bagging + Random Feature Selection
rf = RandomForestClassifier(
n_estimators=100,
max_features='sqrt', # √k случайных признаков
max_samples=1.0, # 100% примеров (bootstrap по умолчанию)
max_depth=None,
random_state=42
)
rf.fit(X_train, y_train)
feature_importance = rf.feature_importances_
print(f"Важность признаков: {feature_importance}")
print(f"Топ-5 признаков: {np.argsort(feature_importance)[-5:]}")
Когда использовать Bagging
Плюсы:
- Снижает дисперсию (уменьшает overfitting)
- Параллельное обучение (быстро)
- Простая реализация
- Работает со сложными моделями (деревья, нейросети)
- Позволяет оценить важность признаков
Минусы:
- Не снижает смещение (bias), только дисперсию
- Может быть медленнее чем одна большая модель
- Требует больше памяти (k моделей вместо одной)
Bagging vs Pojedental моделей
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
# Одно дерево (high variance, low bias)
tree = DecisionTreeClassifier(max_depth=5)
scores_tree = cross_val_score(tree, X, y, cv=5)
# Bagging из 50 деревьев (low variance)
bagging = BaggingClassifier(DecisionTreeClassifier(max_depth=5), n_estimators=50)
scores_bagging = cross_val_score(bagging, X, y, cv=5)
print(f"Одно дерево: {scores_tree.mean():.4f} (дисперсия: {scores_tree.std():.4f})")
print(f"Bagging: {scores_bagging.mean():.4f} (дисперсия: {scores_bagging.std():.4f})")
# Bagging обычно имеет МЕНЬШУЮ дисперсию (std)
Оценка неопределённости (Out-Of-Bag, OOB)
# Для каждого примера в bootstrap есть примеры, которые НЕ вошли в выборку
# Это называется Out-Of-Bag (OOB)
# Можем использовать их для оценки ошибок на валидации БЕЗ отдельного hold-out
bagging = BaggingClassifier(
DecisionTreeClassifier(max_depth=5),
n_estimators=100,
oob_score=True # Включить OOB оценку
)
bagging.fit(X_train, y_train)
print(f"OOB Score: {bagging.oob_score_:.4f}")
# OOB Score часто близка к cross-validation score
Bagging — простой и эффективный способ улучшить модели за счёт уменьшения дисперсии!