Что такое градиентный бустинг на деревьях (Gradient Boosting Trees)?

«Что такое градиентный бустинг на деревьях (Gradient Boosting Trees)?» — вопрос из категории Деревья и ансамбли, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Gradient Boosting Trees (GBT) — это мощный ансамблевый метод машинного обучения для задач регрессии и классификации. Основная идея — последовательное построение множества простых моделей (обычно неглубоких деревьев решений), где каждая следующая модель обучается предсказывать ошибки (остатки) предыдущих моделей.

Как это работает (интуитивно):

  1. Обучается первое дерево на исходных данных.
  2. Вычисляются ошибки его предсказаний (разница между предсказанием и истинным значением).
  3. Второе дерево обучается предсказывать эти ошибки.
  4. Предсказание итоговой модели становится суммой предсказаний первого дерева и предсказания ошибок вторым деревьем, умноженным на небольшой коэффициент (learning rate).
  5. Процесс повторяется для многих деревьев. Каждое новое дерево «фокусируется» на ошибках, которые не смогли исправить предыдущие.

Практический пример с XGBoost (библиотека, реализующая GBT):

import xgboost as xgb
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# Генерируем синтетические данные
X, y = make_regression(n_samples=1000, n_features=20, noise=0.1)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Создаем и обучаем модель XGBoost
model = xgb.XGBRegressor(
    n_estimators=150,      # Количество деревьев в ансамбле
    max_depth=4,           # Максимальная глубина каждого дерева
    learning_rate=0.05,    # Скорость обучения (шаг, с которым каждое дерево вносит поправку)
    subsample=0.8,         # Доля случайных строк данных для обучения каждого дерева
    colsample_bytree=0.8,  # Доля случайных признаков для обучения каждого дерева
    random_state=42
)
model.fit(X_train, y_train)

# Делаем предсказания и оцениваем качество
y_pred = model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
print(f"Mean Squared Error: {mse:.4f}")
print(f"Feature importance:n{dict(zip([f'F{i}' for i in range(20)], model.feature_importances_))}")
Преимущества и недостатки: Преимущества Недостатки
Высокая прогнозная точность, часто лучшая среди «классических» методов. Требует тщательной настройки гиперпараметров (n_estimators, learning_rate, max_depth).
Гибкость: может работать с разнородными данными, пропусками. Может быть медленным при обучении на очень больших данных (по сравнению с линейными моделями).
Встроенные механизмы регуляризации для борьбы с переобучением (в XGBoost, LightGBM). Менее интерпретируем, чем одно дерево решения.
Позволяет оценивать важность признаков.