Ответ
Использование ансамбля многих (сотни-тысячи) неглубоких деревьев (часто называемых "пнями" при глубине 1, или деревьями глубиной 3-6) является ключевым принципом градиентного бустинга (GBM), на котором построены XGBoost и LightGBM. Это не просто эвристика, а следствие математической формулировки метода.
Основные причины:
- Каждое дерево исправляет ошибки предыдущих: GBM обучается последовательно. Каждое новое дерево обучается не на исходных метках
y, а на градиенте (антиградиенте) функции потерь относительно предсказаний текущего ансамбля. По сути, оно учится предсказывать, в какую сторону и насколько нужно скорректировать текущее предсказание, чтобы уменьшить ошибку. Неглубокое дерево делает это небольшой, простой коррекцией, что предотвращает резкие, шумные изменения. - Контроль переобучения и улучшение обобщения: Глубокое дерево — сильный ученик, который может идеально подогнаться под обучающие данные, включая шум. В бустинге нам нужны слабые ученики (high bias, low variance), которые лишь немного лучше случайного угадывания. Ансамбль из тысяч таких слабых моделей, корректирующих ошибки друг друга, дает сильную модель с низкой дисперсией (меньшим риском переобучения).
- Вычислительная эффективность и интерпретируемость: Обучение неглубокого дерева намного быстрее. Кроме того, ограничение глубины (например,
max_depth=3) действует как мощный регуляризатор, упрощая настройку гиперпараметров.
Практический пример настройки в XGBoost:
from xgboost import XGBRegressor
# Типичная конфигурация: много неглубоких деревьев
model = XGBRegressor(
n_estimators=1000, # Большое количество деревьев
max_depth=4, # Небольшая глубина
learning_rate=0.05, # Небольшой шаг обучения (shrinkage)
subsample=0.8 # Стрижка строк для дополнительной регуляризации
)
# learning_rate и n_estimators связаны: уменьшая шаг, нужно увеличивать количество деревьев. Ответ 18+ 🔞
А, ну это же классика, ёпта! Слушай, сейчас объясню на пальцах, почему в этих ваших бустингах деревья — как карлики в саду, а не как секвойи в лесу. Это не потому что лень глубокие гонять, а потому что так правильно, блядь.
Вот смотри, вся фишка в том, что каждое новое деревце — это не самостоятельный мужик, а такой подмастерье, который приходит и чинит косяки за предыдущими. Представь: у тебя есть общее предсказание, и оно немного косячное. Новое дерево смотрит на это и говорит: «Э, сабака сука, тут вот в этих случаях надо на 0.1 прибавить, а тут на 0.05 убавить». Оно учится не на исходных данных, а на градиенте — то есть на том, куда и насколько текущий ответ промазал. И если это дерево будет глубоким и умным, оно начнет выебываться и исправлять не только общую ошибку, но и случайный шум, как последний заучка. А нам это не надо. Нам нужны простые, туповатые коррекции, чтобы ансамбль из тысяч таких поправок дал гладкий и точный результат. Иначе будет переобучение пиздец.
Поэтому глубина 3-6 — это золотая середина. Дерево уже не пень (глубина 1), который может скорректировать только по одному признаку, но и не монстр с десятью уровнями, который начнет запоминать идиотские выбросы. Это как слабый ученик, который чуть лучше случайности. А когда ты таких слабаков собираешь овердохуища, и они дружно толкают в одну сторону, получается сила — умная, обобщающая модель, которая не переобучается.
Ну и по деньгам, то есть по вычислениям, это выгоднее. Неглубокое дерево обучается в разы быстрее. Да и настраивать проще: выставил max_depth=4, learning_rate=0.05 и гони n_estimators до упора, пока ошибка на валидации падает. Сама ограниченная глубина — уже хуевый такой регуляризатор.
Вот, смотри, как это в коде выглядит, тут всё честно:
from xgboost import XGBRegressor
# Классический рецепт: много карликов, маленький шаг
model = XGBRegressor(
n_estimators=1000, # Тысяча деревьев, да, много
max_depth=4, # Глубина 4 — уже не пень, но и не гигант
learning_rate=0.05, # Маленький шаг, чтобы не скакать как угорелый
subsample=0.8 # И ещё строки случайно прореживаем, для надёжности
)
# learning_rate и n_estimators связаны обратной хуйней: шаг уменьшил — деревьев добавь, иначе не дойдёшь.
Короче, философия простая: один умный — хорошо, а толпа туповатых, но упорных — лучше. Они ошибку предыдущего товарища по чуть-чуть исправляют, и в итоге вся бригада выдаёт результат, от которого просто удивление пиздец.