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