Что произойдет, если в градиентном бустинге использовать линейную модель (например, линейную регрессию) в качестве базового алгоритма вместо дерева?

Ответ

Использование линейной модели в качестве базового алгоритма (слабого ученика) в градиентном бустинге превращает его в модель, которая строит ансамбль линейных функций. Это реализовано, например, в XGBoost с параметром booster='gblinear'. Результат существенно отличается от классического бустинга на деревьях.

Ключевые последствия и сравнение:

Аспект Бустинг на деревьях (gbtree) Бустинг на линейных моделях (gblinear)
Гибкость Высокая. Может улавливать сложные нелинейные зависимости и взаимодействия признаков. Низкая. Модель остается аддитивной комбинацией линейных функций, способна аппроксимировать только линейные или слабо нелинейные зависимости.
Интерпретируемость Низкая (ансамбль многих деревьев). Высокая. Можно проанализировать итоговые веса признаков в линейной комбинации.
Скорость обучения Медленнее, особенно при глубоких деревьях. Значительно быстрее, так как оптимизация линейных моделей вычислительно дешевле.
Обработка признаков Автоматически обрабатывает взаимодействия, не требует масштабирования. Требует тщательной предобработки: масштабирования, обработки выбросов, может потребовать ручного создания взаимодействий (полиномиальных признаков).

Пример кода и вывод:

import xgboost as xgb
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split

# Создадим данные с нелинейной зависимостью
X, y = make_regression(n_samples=1000, n_features=10, noise=0.2, random_state=42)
y = y ** 2  # Добавляем нелинейность

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# 1. Классический XGBoost на деревьях
model_tree = xgb.XGBRegressor(objective='reg:squarederror', n_estimators=100, random_state=42)
model_tree.fit(X_train, y_train)
score_tree = model_tree.score(X_test, y_test)

# 2. XGBoost с линейными базовыми моделями
model_linear = xgb.XGBRegressor(booster='gblinear', n_estimators=100, random_state=42)
model_linear.fit(X_train, y_train)
score_linear = model_linear.score(X_test, y_test)

print(f"R² score (деревья): {score_tree:.4f}")
print(f"R² score (линейные модели): {score_linear:.4f}")
# На нелинейных данных score_tree будет значительно выше

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

Ответ 18+ 🔞

А, ну ты смотри, какие извращения придумали! Взяли градиентный бустинг, который все привыкли на деревьях гонять, и сунули туда линейные модели вместо них. Это как вместо внедорожника поставить тележку из супермаркета — едет, конечно, но ощущения, бля, совсем другие.

Вот смотри, в чём прикол. Берёшь XGBoost, ставишь параметр booster='gblinear', и он вместо кучи решающих деревьев начинает строить ансамбль из линейных функций. Получается такая адская аддитивная модель, где каждый следующий слабый ученик — это просто ещё одна линейная регрессия, которая пытается исправить ошибки предыдущих. Ёпта, звучит как какая-то академическая шутка, но оно реально работает, хоть и не везде.

И что в итоге получается? Давай сравним с классикой жанра:

Что сравниваем Бустинг на деревьях (gbtree) Бустинг на линейных моделях (gblinear)
Гибкость Высокая, пиздец. Деревья могут выловить любую нелинейную зависимость и взаимодействия признаков, хоть узор на ковре расшифровывай. Низкая, как у доски. Это же просто сумма линейных моделей, ебать мои старые костыли. Если данные кривые — будет хуйня, а не предсказания.
Понятность Нулевая. Ты попробуй объясни бизнесу, как там 500 деревьев приняли решение. Высокая. Всё сводится к итоговым весам признаков. Можно посмотреть и сказать: "Вот этот признак — пидарас шерстяной, он всё портит".
Скорость Медленнее, особенно если деревья глубокие. Значительно быстрее. Оптимизировать линейные модели — это не в пример проще, чем растить лес.
Что делать с признаками Можно хоть сырые данные кидать, ему похуй. Сам разберётся. Тут надо попотеть: масштабировать, выбросы убирать, а если нужны нелинейности — то самому полиномы лепить, хитрая жопа.

Вот, смотри, на практике как это выглядит:

import xgboost as xgb
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split

# Нагенерим данных, да ещё нелинейность добавим
X, y = make_regression(n_samples=1000, n_features=10, noise=0.2, random_state=42)
y = y ** 2  # Вот тебе и нелинейность, ёклмн

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# 1. Классический XGBoost на деревьях
model_tree = xgb.XGBRegressor(objective='reg:squarederror', n_estimators=100, random_state=42)
model_tree.fit(X_train, y_train)
score_tree = model_tree.score(X_test, y_test)

# 2. XGBoost на линейных моделях
model_linear = xgb.XGBRegressor(booster='gblinear', n_estimators=100, random_state=42)
model_linear.fit(X_train, y_train)
score_linear = model_linear.score(X_test, y_test)

print(f"R² score (деревья): {score_tree:.4f}")
print(f"R² score (линейные модели): {score_linear:.4f}")
# На кривых данных у деревьев результат будет овердохуища лучше

Так когда эту штуку использовать-то? Да когда задача простая, почти линейная, или когда начальник орет: "Объясни мне, почему модель так решила, а то я тебе вманжу!". Или как быстрый бейзлайн, чтобы понять, а стоит ли вообще городить сложные модели. Но если данные — пизда рулю, то это как пытаться гвоздь микроскопом забить.