Модуль 6. Градиентный бустинг: XGBoost, LightGBM, CatBoost

Цель модуля: понять, как бустинг строит ансамбль последовательно, обучая каждую следующую модель на остатках предыдущих; увидеть в этом тот же градиентный спуск, что в модуле 2, но в пространстве функций; запомнить гиперпараметры XGBoost/LightGBM/CatBoost и то, чем бустинг отличается от леса.

Перед началом: модули 2 (градиентный спуск) и 5 (случайный лес). Инструменты: песочница сайта (чистый Python), сниппет ниже. Трудоёмкость: ~1.5 ч (чтение 45 мин · сниппет и практика 30 мин).

🔥 Король табличных данных

Откройте любую табличную задачу на Kaggle — оттока, скоринга, прогноза спроса — и посмотрите в топ решений. Почти всегда там XGBoost, LightGBM или CatBoost. В проде та же картина: там, где данные — строки и столбцы, бустинг почти всегда обыгрывает и линейные модели, и нейросети.

Идея бустинга при этом старше всех вокруг: не подбирать одну идеальную модель, а собрать цепочку из слабых. Первая модель грубая и почти ничего не умеет. Вторая учится не с нуля, а на её ошибках. Третья — на ошибках исправленной версии. Сумма десятков таких шагов рисует кривую, которую не нарисует ни один из них поодиночке.

Разберём это на игрушечном сниппете, где бустинг собран на салфетке, а потом спроецируем на реальные библиотеки.

📖 6.1. Бустинг на салфетке: каждая модель исправляет остатки

Сниппет toy-boosting.py: 13 точек кривой y = 2x + 3·sin(x), а модель — «ступенька»: слева от порога одно число, справа другое. Начинаем с самого тупого предсказания — константы, среднего по данным (5.20, MSE = 3.989).

Дальше цикл:

  1. Считаем остатки (residuals) — где текущий ансамбль ошибается: остаток = истина − предсказание.
  2. Обучаем новую ступеньку предсказывать эти остатки.
  3. Добавляем ступеньку к ансамблю с коэффициентом learning rate (шаг).

И повторяем. Каждая новая модель решает не исходную задачу, а задачу «чего не хватает уже собранному ансамблю». Это принципиально последовательная конструкция: без шага 1–2 предыдущего нет смысла для следующего, поэтому, в отличие от леса (модуль 5), бустинг нельзя распараллелить по моделям.

Запомните метафору: черновик → правки по черновику → правки по правкам. Каждая правка маленькая, но вместе они дают текст.

📖 6.2. Тот же градиентный спуск, но в пространстве функций

В модуле 2 мы считали градиент MSE по коэффициентам и шагали против него. Здесь происходит то же самое, только «параметров» бесконечно много: мы меняем не числа, а саму функцию-предсказатель.

Небольшой фокус: если предсказание обозначить p, а истину y, то остаток y − p — это в точности минус градиент MSE по предсказанию (с точностью до множителя 2). То есть шаг 2 из 6.1 «обучить ступеньку на остатках» — это шаг против градиента в пространстве функций. Отсюда и название: gradient boosting.

Всё остальное знакомо по модулю 2: есть шаг обучения (learning rate) и есть баланс «шаг побольше и побыстрее — или поменьше и поточнее». Разница только в том, что в линейной регрессии мы спускались по двум коэффициентам, а тут на каждом шаге добавляем целую новую функцию. «Бустинг» и значит «усиление»: каждая итерация усиливает слабый ансамбль.

📖 6.3. Разбор сниппета: MSE тает с 3.99 до 0.16

Читаем вывод toy-boosting.py. Старт: Предсказание №0 — константа: 5.20, MSE = 3.989. Дальше шесть итераций, каждый раз новая ступенька и новый MSE:

Итерация 1: «x ≤ 0.8 ? -3.30 : +0.99», MSE = 1.021
Итерация 2: «x ≤ 0.0 ? -2.90 : +0.24», MSE = 0.385
Итерация 3: «x ≤ 0.4 ? -0.98 : +0.18», MSE = 0.225
Итерация 4: «x ≤ 1.2 ? -0.26 : +0.11», MSE = 0.198
Итерация 5: «x ≤ 3.2 ? +0.10 : -0.23», MSE = 0.177
Итерация 6: «x ≤ 4.4 ? -0.04 : +0.50», MSE = 0.158

Три наблюдения по этим числам. Первое: основной эффект даёт первая итерация — MSE падает с 3.989 до 1.021. Это естественно: она снимает самую грубую ошибку — что кривая в среднем «где-то около пяти». Следующие шаги отвечают за детали: шестая итерация улучшает уже только 0.177 → 0.158. Каждая следующая добавляет всё меньше — типичная картина сходимости.

Второе: пороги ступенек движутся по оси (0.8 → 0.0 → 0.4 → 1.2 → 3.2 → 4.4). Ансамбль строится не вокруг одной точки, а «прокатывает» форму кривой слева направо и обратно, уточняя её на каждом участке.

Третье: финальная таблица. Предсказания ансамбля против истины: при x = 0.0 ошибка −0.04, при x = 1.2 — −0.86, при x = 2.4 — 0.51, при x = 3.6 — −0.21, при x = 4.8 — 0.15. Худшее место — изгиб кривой в начале, где ступенькам труднее всего; но ошибка −0.86 при размахе значений до 6.8 — уже рабочее качество. Ни одна из шести ступенек поодиночке такую кривую не нарисовала бы.

📖 6.4. Реальные бустинги: XGBoost, LightGBM, CatBoost

В сниппете роль слабой модели играет ступенька из двух чисел. В реальности на эту роль ставят решающее дерево глубины 3–8 (модуль 4): оно умеет ловить взаимодействия признаков, а его нестабильность (модуль 5) тут не страшна — её гасит последовательная коррекция.

Ансамбли деревьев: дерево, баггинг (параллельно), бустинг (последовательно)

Диаграмма подводит итог блоку 2. Слева — одно дерево (модуль 4): жадные вопросы по порогам, энтропия ↓ → выигрыш ↑; маленькое недоучилось, большое запомнило шум. От него две дороги. Баггинг (модуль 5) — параллельная: много копий на разных bootstrap-выборках и подмножествах признаков, деревья получаются разными, голосование большинства усредняет шум и снижает разброс. Бустинг — последовательный: первая модель грубая, каждая следующая учится на остатках предыдущих, а сумма снижает систематическую ошибку и повышает точность. Обе дороги ведут в узел «ансамбль», но лечат разные болезни: лес — разболтанность, бустинг — недообученность. Отсюда и разные стили обучения: лес распараллеливается целиком, бустинг — только внутри одной итерации.

Библиотеки, которые вы встретите в проде:

  • XGBoost — классика жанра, вывела бустинг в мейнстрим; сильна регуляризацией и стабильностью на средних данных.
  • LightGBM — строит деревья быстрее за счёт гистограмм; часто выбор на больших таблицах.
  • CatBoost — умеет категориальные признаки практически из коробки (без ручного one-hot) и славится аккуратной работой с ними.
  • В sklearn есть HistGradientBoosting — хороший стартовый вариант, если не хочется третьей зависимости.

Гиперпараметры, с которых начинают (подробный подбор — модуль 11):

  • n_estimators — число деревьев: сотни (100–1000+). Чем меньше learning rate, тем больше нужно деревьев.
  • learning_rate — шаг: 0.01–0.1. Маленький шаг учится плавнее и точнее, но требует больше итераций; в сниппете шаг 0.7 намеренно большой, чтобы эффект был виден за шесть шагов.
  • max_depth — глубина деревьев: 3–8. Слабые деревья — принцип бустинга: силу даёт сумма, а не отдельная модель.
  • early_stopping — остановка, когда метрика на валидации перестала улучшаться: страховка от лишних итераций и от переобучения (модуль 1).

📖 6.5. Компромиссы

  • Бустинг vs случайный лес. Бустинг обычно точнее на табличных данных и снижает смещение; лес прощает грубые гиперпараметры, распараллеливается проще и реже переобучается «на ровном месте». Первый выстрел — бустинг с early stopping, второй — лес как надёжный контроль.
  • Маленький learning rate vs большой. 0.01–0.1 учится медленнее (сотни деревьев), но глаже и точнее; большой шаг быстро снижает ошибку, но рискует перескочить оптимум. Правило: уменьшаете lr — увеличивайте n_estimators.
  • Глубина 3–8 vs глубокие деревья. Мелкие «ступеньки» складываются в сложную функцию безопаснее; глубокие деревья и без бустинга переобучаются (модуль 4), а последовательная коррекция только усилит их шум.
  • Бустинг vs линейная модель. Линейная (модуль 2) быстрее, проще объясняется и хороша при малых данных; бустинг выигрывает при тысячах строк и выше, но требует подбора гиперпараметров и контроля валидации.
  • Точность vs интерпретируемость. Бустинг объясняется через важности признаков и SHAP-вклады, но это не «регламент» из модуля 4. Если аудит требует правил построчно — начните с дерева, а бустинг держите как эталон качества.

💻 Практика

  1. (20 мин) Эксперимент в сниппете. Запустите toy-boosting.py и поменяйте LR = 0.7 на 0.2, затем на 1.0. Сколько MSE после шести итераций в каждом случае? Объясните через «размер шага» из модуля 2.
  2. (15 мин) Худшая точка. Возьмите таблицу предсказаний из вывода: максимальная ошибка −0.86 при x = 1.2. Посмотрите на true_y: почему именно в начале кривой ступенькам тяжело? Что могло бы исправить следующая итерация?
  3. (15 мин) Гиперпараметры для своей задачи. Для вашей табличной задачи выпишите стартовый набор: n_estimators = 500, learning_rate = 0.05, max_depth = 6, early stopping по валидации. От чего зависит каждый выбор?
  4. (10 мин) Выбор модели. Возьмите диаграмму из 6.4 и вслух объясните коллеге, почему бустинг строится последовательно, а лес параллельно, и какую ошибку лечит каждый из них.

🧩 Quiz "Проверь себя"

1. В сниппете MSE упал с 3.989 до 0.158. Что сделало основную работу?
2. Зачем нужен early stopping?
3. На чём обучается каждая следующая модель в бустинге?
4. Чем бустинг отличается от баггинга?
5. Почему learning rate бустинга берут маленьким (0.01–0.1)?

✅ Итоги модуля

  • Объяснить идею бустинга: последовательное исправление остатков.
  • Связать бустинг с градиентным спуском из модуля 2.
  • Пересказать вывод сниппета: MSE 3.989 → 0.158 за шесть итераций.
  • Назвать XGBoost, LightGBM, CatBoost и чем они различаются.
  • Подобрать стартовые гиперпараметры: lr, n_estimators, max_depth, early stopping.
  • Отличить баггинг от бустинга по двум признакам: параллельно/ последовательно и разброс/смещение.

🔗 Мостик к Модулю 7

Бустинг выдаёт вероятность — «гулять 0.87». Но решение принимать надо бинарное: гулять или нет, отправить алерт или нет. Значит, нужен порог, а вместе с ним — честные метрики: как считать ошибки при дисбалансе, что такое precision и recall, как оценить качество по всем порогам сразу. Дальше — модуль 7 «Метрики классификации: от confusion matrix до ROC-AUC».