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

«Что произойдет, если в градиентном бустинге использовать линейную модель (например, линейную регрессию) в качестве базового алгоритма вместо дерева?» — вопрос из категории Деревья и ансамбли, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Использование линейной модели в качестве базового алгоритма (слабого ученика) в градиентном бустинге превращает его в модель, которая строит ансамбль линейных функций. Это реализовано, например, в 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 будет значительно выше

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