ML

Градиентный бустинг. Основы.

Градиентный бустинг (Gradient Boosting) – это ансамблевый метод, включающий ряд простых моделей (как правило, 100 и более деревьев решений небольшой глубины), обучаемых последовательно.

Особенности бустинга

Используется последовательность из простых моделей (обычно это деревья решений).

Каждая следующая модель обучается на ошибках предыдущей. В очередную модель подаются те же исходные данные, но в качестве таргета используются потери композиции всех предыдущих моделей. Текущая модель стремится к минимизации этих ошибок за счет градиентного спуска.

Минимизация потерь осуществляется за счет вычисления градиентов и гессианов от функции потерь и вычисления их численных значений перед запуском каждой модели ансамбля. Эти градиенты и гессианы применяются для вычисления оптимальных значений в листьях дерева.

Наибольший вклад в результат модели делает самое первое дерево. Все последующие деревья делают все менее значительный вклад в итоговый результат (но также повышают точность прогноза).

Механика алгоритма

Шаг 1 – расчет таргета для первого дерева

Сначала находится начальный прогноз (первое приближение). Это приближение используется для двух целей:

1. Итоговый прогноз ансамбля Fn(x) – на каждой итерации алгоритма (отработка каждого дерева) к начальному прогнозу Fo(x) добавляется результат работы текущего дерева h(x) (умноженный на Learning Rate – шаг обучения).

Fn(x) = Fo(x) + lr*h1(x) + lr*h2(x) + … + lr*hn(x)

2. Расчет потерь для подачи в каждое дерево – из исходного Y вычитается текущее значение прогноза ансамбля. Для самого первого дерева используется начальный прогноз – он вычитается из исходного Y, чтобы получить таргет для первого дерева.

Начальный прогноз обычно получают путем дифференцирования функции потерь и приравнивания ее к нулю (это условие минимума функции из математического анализа – производная равна нулю).

  • Для задачи регрессии в качестве первого приближения берется среднее арифметическое значение таргета из исходных данных. Затем для каждого примера находится значение потерь путем вычитания среднего значения таргета из Y.
  • Для задачи бинарной классификации в качестве первого приближения берется логарифм отношения долей классов (это производная от логистической функции потерь (LogLoss). Потери для каждого примера находятся путем вычитания полученных логарифмов из Y.
  • Для задачи многоклассовой классификации (один из нескольких классов) в качестве первого приближения берется логарифм доли объектов каждого класса. Потери для каждого примера находятся путем вычитания полученных логарифмов из Y.

Шаг 2 – построение первого дерева и обновление прогнозов

Признаки подаются в дерево решений. Таргетом служат потери, полученные на предыдущем шаге. Прогнозы первого дерева h(x) суммируются c начальным прогнозом Fo(x).

Шаг 3 – построение последующих деревьев и обновление прогнозов

Для обучения дерева используются те же исходные признаки. Но в качестве таргета используются обновленные значения потерь. Из исходных значений таргета Y вычитается текущий вектор прогноза Fn(x).

Fn(x) = Fo(x) + lr*h1(x) + lr*h2(x) + … + lr*hn(x)

Это повторяется многократно в каждом последующем дереве.

Шаг 4 – построение последнего дерева и получение итогового прогноза

Построение последнего дерева ничем не отличается от всех прочих. Его прогноз суммируется с текущим значением Fn(x). Это и является результатом работы ансамбля.

Популярные реализации градиентного бустинга

  • XGBoost
  • LightGBM – работает быстро с низким потреблением памяти. Использует подход leaf wise – рост деревьев по листьям, а не по уровням, что позволяет строить глубокие и точные деревья быстрее. Использует технику GOSS – gradient based one side sampling (см. ниже). Оптимален в работе с очень большими данными – миллионы строк и миллионы признаков.
  • CatBoost – имеет продвинутый механизм кодирования категориальных признаков – ordered target encoding. Очень устойчив к переобучению.
  • Sklearn (GradientBoostingClassifier, GradientBoostingRegressor)

Гиперпараметры – основные эвристики по подбору

Подбор гиперпараметров – это главная трудность в применении бустинга. Точность алгоритма можно значительно улучшить за счет их удачного подбора. В соревнованиях и на практике обычно используют кроссвалидацию и GridSearchCV.

Документация по параметрам XGBoost – https://xgboost.readthedocs.io/en/stable/parameter.html#parameters-for-tree-booster

Рассмотрим основные эвристики по подбору гиперпараметров.

Количество деревьев (n_estimators)

Определяет число деревьев в алгоритме. Обычно, чем больше деревьев, тем выше качество, но есть риск переобучения.

  • Для небольших датасетов (менее 10 тыс. строк) – 50-200 деревьев.
  • Для данных среднего размера (от 10 до 100 тыс. строк) – 100-500 деревьев.
  • Для больших датасетов (более 100 тыс. строк) – 500-2000 деревьев – рекомендуется использовать Early Stopping.

Глубина деревьев (max_depth)

Определяет глубину каждого дерева в ансамбле. Чем глубже деревья, тем сложнее модель и выше риск переобучения.

Много неглубоких деревьев обычно эффективнее, чем мало глубоких.

  • Для малых наборов данных – 3-6 уровней.
  • Для больших наборов – 4-8 уровней.

Скорость обучения (learning_rate)

Гиперпараметр определяет шаги градиентного спуска – в сущности, это коэффициент, определяющий вклад каждого дерева в ансамбле.

Чем ниже скорость обучения, тем больше деревьев нужно. Но низкое значение гиперпараметра делает ансамбль стабильнее и менее склонным к переобучению. Низкая скорость обучения замедляет работу алгоритма.

Распространенная практика – начинать со значения 0.1 и постепенно снижать.

  • Для небольших датасетов – 0.05-0.2
  • Для средних и больших датасетов – 0.01-0.1

Минимальное число объектов в листе (min_saples_leaf)

Чем больше значение гиперпараметра, тем меньше переобучение, но выше смещение (bias).

  • Для небольших датасетов – 1-5.
  • Для средних и больших датасетов – 5-20 и более.

Доля признаков для каждого дерева (max_features или colsample_bytree в XGBoost)

Определяет создание случайных подвыборок признаков – какой процент признаков участвует в обучении.

Помогает бороться с переобучением. Типичные значения гиперпараметра – от 0.4 до 1.0. Значение 1.0 означает, что в дерево подаются все признаки.

  • Если признаков много (более 50-100) – 0.3-0.7
  • Если признаков мало (менее 20-30) – 0.7-1.0

Регуляризация (lambda, alpha в XGBoost и т.д)

Следует отметить, что применение регуляризации в алгоритмах бустинга несколько отличается от стандартного применения в линейных моделях. Здесь используется другая формула, но суть регуляризации остается прежней – влияние на разреженность модели и штрафы за слишком большие значения (веса) в листьях дерева. Весами являются значения, получаемые в листьях (ведь таргетом в дереве решений является ошибка).

Стандартный подход – lambda=1.0 – и затем подгонка.

  • Для небольших или зашумленных данных – lambda = 1-10
  • Для больших данных – lambda = 0-1

Параметр booster/boosting_type

При использовании алгоритмов бустинга (XGBoosting, CatBoost, LightGBM, HGBC и других) есть параметр настройки типа бустинга – booster/boosting_type. Он может принимать значения вида gbdt, dart, goss, rf.

Что это означает?

gbdt – gradient boosting decision trees

Это стандартный бустинг, где каждое новое дерево обучается на ошибках предыдущих деревьев.

Может переобучаться на небольших данных.

Пример:

from xgboost import XGBClassifier 
model = XGBClassifier(booster="gbtree") # Стандартный GBDT

dart – dropout meets adaptive regularization of trees

Это тот же стандартный бустинг, но с исключением некоторых деревьев (они “отключаются” при бустинге). Этот прием является аналогом дропаута в нейросетях (“выключаются” некоторые случайные нейроны).

Работает лучше на небольших данных.

Пример:

import lightgbm as lgb 
model = lgb.LGBMClassifier(boosting_type='dart')

goss – gradient based one-side sampling

Вместо использования всех объектов берет только самые важные (с большим градиентом) + случайную часть остальных. Ускоряет обучение, не теряя качествоа. Хорошо работает на больших данных.

Пример:

import lightgbm as lgb
model = lgb.LGBMClassifier(boosting_type='goss')

rf – random forest mode

По сути – это аналог случайного леса. Вместо последовательного обучения, каждое дерево обучается независимо. Устойчив к шуму, просто в настройке. Может работать хуже на сложных данных, требует больше деревьев для хорошего качества.

Пример:

import lightgbm as lgb
model = lgb.LGBMClassifier(boosting_type='rf')

Выбор типа бустинга

  • Если данных мало и есть переобучение → DART.
  • Если данных очень много → GOSS.
  • Если много шума → RF. Если стандартная ML-задача → GBDT.

Общие рекомендации по подбору гиперпараметров

Использовать раннюю остановку на валидационном наборе.

Использовать автоматизированный подбор гиперпараметров (GridSearchCV, Optuna).

Начинать с простых моделей и постепенно увеличивать число деревьев и их глубину.

Пример кода LightGBM с подбором гиперпараметров

import numpy as np
import pandas as pd
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import mean_squared_error
import lightgbm as lgb

# Dowload data
data = fetch_california_housing(as_frame=True)
X = data.data
y = data.target

# Split data onto train and test parts
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.2, random_state=1)

# Make model
model = lgb.LGBMRegressor(random_state=1)

# Get hiperparameters via GridSearchCV
# Make param grid
param_grid = {
    'num_leaves': [15, 31, 63],
    'max_depth': [3, 5, 7],
    'learning_rate': [0.01, 0.05, 0.1],
    'n_estimators': [100, 200, 500]
}

# Run GridSearchCV for hiperparameters selection
grid_search = GridSearchCV(
    estimator=model, 
    param_grid=param_grid,
    cv=3, 
    scoring='neg_mean_squared_error',
    n_jobs=-1,
    verbose=1
)

grid_search.fit(X_train, y_train)

# Get the best parameters
print("The best parameters are: ", grid_search.best_params_)

# Get best model result and quality
best_model = grid_search.best_estimator_

y_pred = best_model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)

print(f"Test MSE: {mse:.4f}")

Вставить формулу как
Блок
Строка
Дополнительные настройки
Цвет формулы
Цвет текста
#333333
Используйте LaTeX для набора формулы
Предпросмотр
\({}\)
Формула не набрана
Вставить