Прямой ответ
Градиентный бустинг строит ансамбль деревьев последовательно: каждое следующее дерево приближает антиградиент функции потерь по текущему предсказанию. На табличных данных это до сих пор самый сильный «дефолтный» подход: он не требует масштабирования признаков, терпим к пропускам и нелинейностям и быстро обучается.
Ключевые различия реализаций:
- XGBoost. Классический уровень за уровнем; исторически точнее на небольших данных, хорошо регуляризуется. Поддерживает гистограммный метод (
tree_method="hist"), который заметно ускоряет обучение. - LightGBM. Растит деревья leaf-wise (по лучшему листу, а не по уровню), использует гистограммы и GOSS/EFB. Обычно быстрее на больших выборках и даёт сопоставимое качество, но склонен к переобучению на малых данных без ограничения глубины.
Параметры, которые действительно влияют:
| Параметр | XGBoost | LightGBM | Что делает |
|---|---|---|---|
| Число деревьев | n_estimators |
num_iterations |
Ёмкость ансамбля |
| Скорость обучения | learning_rate |
learning_rate |
Шаг; меньше — стабильнее, но нужно больше деревьев |
| Глубина / листья | max_depth |
num_leaves, max_depth |
Сложность дерева |
| Доля данных | subsample |
bagging_fraction |
Регуляризация через подвыборку строк |
| Доля признаков | colsample_bytree |
feature_fraction |
Регуляризация через подвыборку колонок |
| Регуляризация | reg_lambda, reg_alpha |
lambda_l2, lambda_l1 |
Штраф на веса листьев |
Базовый рецепт: learning_rate 0.03–0.1, число деревьев подбирается ранней остановкой, глубина 4–8 (или num_leaves 15–63), доли 0.7–0.9.
import lightgbm as lgb
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
X_tr, X_va, y_tr, y_va = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)
model = lgb.LGBMClassifier(
learning_rate=0.05, num_iterations=2000, num_leaves=31,
subsample=0.8, colsample_bytree=0.8, random_state=42, n_jobs=-1,
)
model.fit(X_tr, y_tr, eval_set=[(X_va, y_va)], eval_metric="auc",
callbacks=[lgb.early_stopping(100, verbose=False)])
print(roc_auc_score(y_va, model.predict_proba(X_va)[:, 1]), model.best_iteration_)
Практика: что делать по шагам
- Начните с baseline.
learning_rate=0.05, ранняя остановка, остальные параметры по умолчанию. Это точка отсчёта, без которой подбор параметров бессмыслен. - Ранняя остановка обязательна. Она заменяет ручной подбор числа деревьев и защищает от переобучения. Важно: валидационный набор не должен участвовать в подборе других параметров повторно — иначе оценка оптимистична.
- Затем глубина/листья и доли. Это самые влиятельные параметры после скорости обучения.
- Проверяйте важность признаков. Высокая важность одного признака при слабом качестве — повод проверить утечку данных.
- На дисбалансе настройте веса. Механика и метрики — в статье про дисбаланс классов.
- Корректно оценивайте качество. Одна валидационная выборка даёт шумную оценку; надёжнее кросс-валидация — см. кросс-валидацию и подбор гиперпараметров.
Практические замечания:
- Пропуски. Обе библиотеки обрабатывают
NaNнативно, но поведение обученной модели на пропусках стоит проверить: если в проде пропусков больше, качество может отличаться. - Категориальные признаки. LightGBM поддерживает их напрямую (
categorical_feature), XGBoost — начиная с 2.x черезenable_categorical. В остальных случаях нужно кодирование. - Число потоков.
n_jobs=-1не всегда оптимален: на ноутбуке с троттлингом иногда быстрее ограничение числа потоков. Контекст работы без GPU — в статье про sklearn без GPU. - Воспроизводимость. Фиксируйте
random_stateи версии библиотек; разные версии могут давать разные результаты на тех же данных.
Диагностика переобучения по кривым. Стройте кривые обучения: метрика на обучении и на валидации по числу деревьев. Расхождение, которое растёт после определённого момента, указывает на точку, где стоит остановить обучение. Если кривая валидации выходит на плато рано, увеличивать ёмкость бессмысленно — ограничение в данных или признаках, а не в модели.
Работа с категориальными признаками. Прямая поддержка категорий удобна, но требует аккуратности: категории с малым числом наблюдений дают неустойчивые разбиения. Практика — объединять редкие категории в «прочие» до обучения и фиксировать этот список как часть пайплайна, иначе в проде появится неизвестная модель категория.
Практический сценарий: качество на тесте 0.94, в проде 0.76
Контекст: модель скоринга обращений; после выкатки качество заметно ниже ожидаемого.
- Проверка утечки. Важность признака
resolved_at_hoursоказалась максимальной. Этот признак появляется только после закрытия обращения, то есть в момент предсказания его ещё нет. - Вторая причина. Обучающая выборка была собрана по состоянию на конец месяца, а часть признаков (например, число повторных обращений) рассчитана «на будущее» относительно события.
- Исправление. Удалили признаки, недоступные в момент предсказания; пересобрали выборку с учётом времени события; добавили проверку списка признаков на доступность.
- Результат. Офлайн-качество снизилось до 0.85, но совпало с онлайн-результатом. Разрыв исчез — это и есть признак корректной модели.
- Профилактика. Список признаков проходит ревью на «доступность в момент запроса»; процедура включена в пайплайн обучения.
Вывод: бустинг легко «выучивает» утечку данных и показывает выдающиеся офлайн-метрики. Проверка доступности признаков важнее подбора параметров.
FAQ
Что выбрать: XGBoost или LightGBM? На больших таблицах LightGBM обычно быстрее при сопоставимом качестве. На малых данных XGBoost с ограниченной глубиной устойчивее к переобучению. Решение стоит принимать по замеру на своих данных, а не по общим рекомендациям.
Почему LightGBM переобучается на малых выборках?
Из-за leaf-wise роста: дерево углубляется в наиболее выигрышный лист, что даёт сложные деревья при малом объёме данных. Лечится ограничением num_leaves, min_data_in_leaf и увеличением регуляризации.
Нужно ли масштабировать признаки? Нет: деревья работают с порядком значений, а не с их масштабом. Масштабирование нужно для линейных моделей и нейросетей, но не для бустинга.
Когда бустинг проигрывает другим подходам? На очень малых выборках (сотни строк) часто лучше регуляризованная линейная модель, на изображениях и текстах — специализированные архитектуры, на задачах с сильной временной структурой — модели, учитывающие порядок наблюдений.
Источники: XGBoost docs, LightGBM docs, scikit-learn ensemble — ссылки в шапке.