Условие
Объясните Gradient Boosting на пальцах: что минимизируем, как обновляем, почему «градиентный».
Решение
Подход
GBM строит ансамбль F_M(x) = Σ_{m=1}^M γ_m·h_m(x), где h_m — слабые учители (обычно деревья). Минимизирует L(y, F(x)) методом stage-wise: каждое следующее дерево обучается предсказывать отрицательный градиент loss относительно текущего F.
Алгоритм
- Инициализация:
F_0(x) = argmin_γ Σ L(y_i, γ)(для MSE — среднее, для logloss — log-odds). - Для m = 1...M:
- residual / pseudo-residual:
r_im = −∂L(y_i, F)/∂FatF = F_{m-1}(x_i). - Обучаем дерево
h_m(x)на(x_i, r_im). - Находим step γ:
γ_m = argmin_γ Σ L(y_i, F_{m-1}(x_i) + γ·h_m(x_i)). - Update:
F_m = F_{m-1} + ν·γ_m·h_m(ν — learning rate).
- residual / pseudo-residual:
- Финал:
F_M(x).
Loss → pseudo-residuals
| Loss | pseudo-residual |
|---|---|
MSE: (y − F)²/2 |
r = y − F |
| MAE: ` | y − F |
LogLoss бин: −y·log(p) − (1−y)·log(1−p) где p = σ(F) |
r = y − σ(F) |
| Poisson | r = y − exp(F) |
Реализация (упрощённо)
import numpy as np
from sklearn.tree import DecisionTreeRegressor
class SimpleGBM:
def __init__(self, n_est=100, lr=0.1, max_depth=3):
self.n_est = n_est
self.lr = lr
self.max_depth = max_depth
self.trees = []
def fit(self, X, y):
self.F0 = y.mean() # для MSE
F = np.full(len(y), self.F0)
for _ in range(self.n_est):
r = y - F # pseudo-residual MSE
tree = DecisionTreeRegressor(max_depth=self.max_depth)
tree.fit(X, r)
self.trees.append(tree)
F += self.lr * tree.predict(X)
return self
def predict(self, X):
F = np.full(X.shape[0], self.F0)
for tree in self.trees:
F += self.lr * tree.predict(X)
return FРегуляризация
lr(shrinkage): меньше → больше деревьев, лучшая generalization.max_depth,min_samples_leaf— capacity дерева.- Subsample / colsample (Stochastic GB): row/col bagging.
- L1/L2 на листьях (XGBoost: gamma, reg_alpha, reg_lambda).
Подводные камни
- GBM vs RF: RF — independent bagging, можно параллелить; GB — sequential, зависит от предыдущих.
- Learning rate / n_estimators trade-off: классика lr=0.05, n_est=500-2000 с early stopping.
- Выход на logloss: F(x) — это log-odds, не вероятность. Predict_proba делает
σ(F). - Категориальные: CART-деревья требуют numeric. CatBoost / LightGBM имеют нативную обработку.
- Без shrinkage (lr=1) GBM быстро overfit.
Эталонный ответ
GBM = stage-wise аддитивная модель: F_m = F_{m-1} + ν·h_m, где h_m обучен на pseudo-residual = −∂L/∂F. Для MSE residual = y − F, для logloss = y − σ(F). Регуляризация через lr, max_depth, subsample, leaf-L2.