Неверный вывод линейной регрессии XGBoost


10

Я новичок в XGBoost, так что простите мое невежество. Вот код Python:

import pandas as pd
import xgboost as xgb

df = pd.DataFrame({'x':[1,2,3], 'y':[10,20,30]})
X_train = df.drop('y',axis=1)
Y_train = df['y']
T_train_xgb = xgb.DMatrix(X_train, Y_train)

params = {"objective": "reg:linear"}
gbm = xgb.train(dtrain=T_train_xgb,params=params)
Y_pred = gbm.predict(xgb.DMatrix(pd.DataFrame({'x':[4,5]})))
print Y_pred

Выход:

[ 24.126194  24.126194]

Как видите, входные данные представляют собой просто прямую линию. Таким образом, я ожидаю на выходе [40,50]. Что я здесь не так делаю?


1
Пожалуйста, не кросс-пост
Dawny33

2
@ Dawny33 удалено из SO.
simpfuzz

Ответы:


21

Похоже, что XGBoost использует деревья регрессии в качестве базовых учащихся по умолчанию. XGBoost (или Gradient Boosting в целом) работают путем объединения нескольких из этих базовых учеников. Деревья регрессии не могут экстраполировать шаблоны в обучающих данных, поэтому любой ввод выше 3 или ниже 1 не будет правильно предсказан в вашем случае. Ваша модель обучена прогнозированию выходов для входных данных в интервале [1,3], вход больше 3 будет иметь тот же выход, что и 3, а вход меньше 1 будет иметь тот же выход, что и 1.

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

Это в отличие от параметрических регрессоров (таких как линейная регрессия ), которые на самом деле ищут лучшие параметры гиперплоскости (прямой в вашем случае), чтобы соответствовать вашим данным. Линейная регрессия действительно видит ваши данные как прямую линию с наклоном и пересечением.

Вы можете изменить базового ученика вашей модели XGBoost на GLM (обобщенную линейную модель), добавив "booster":"gblinear"к своей модели params:

import pandas as pd
import xgboost as xgb

df = pd.DataFrame({'x':[1,2,3], 'y':[10,20,30]})
X_train = df.drop('y',axis=1)
Y_train = df['y']
T_train_xgb = xgb.DMatrix(X_train, Y_train)

params = {"objective": "reg:linear", "booster":"gblinear"}
gbm = xgb.train(dtrain=T_train_xgb,params=params)
Y_pred = gbm.predict(xgb.DMatrix(pd.DataFrame({'x':[4,5]})))
print Y_pred

В общем, чтобы выяснить, почему ваша модель XGBoost ведет себя определенным образом, посмотрите параметры модели:

gbm.get_dump()

Если ваш базовый ученик - линейная модель, вывод get_dump:

['bias:\n4.49469\nweight:\n7.85942\n']

В приведенном выше коде, поскольку у вас есть древовидные базы учеников, результат будет:

['0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=2.85\n\t\t4:leaf=5.85\n\t2:leaf=8.85\n',
 '0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=1.995\n\t\t4:leaf=4.095\n\t2:leaf=6.195\n',
 '0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=1.3965\n\t\t4:leaf=2.8665\n\t2:leaf=4.3365\n',
 '0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=0.97755\n\t\t4:leaf=2.00655\n\t2:leaf=3.03555\n',
 '0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=0.684285\n\t\t4:leaf=1.40458\n\t2:leaf=2.12489\n',
 '0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=0.478999\n\t\t4:leaf=0.983209\n\t2:leaf=1.48742\n',
 '0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=0.3353\n\t\t4:leaf=0.688247\n\t2:leaf=1.04119\n',
 '0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=0.23471\n\t\t4:leaf=0.481773\n\t2:leaf=0.728836\n',
 '0:[x<3] yes=1,no=2,missing=1\n\t1:[x<2] yes=3,no=4,missing=3\n\t\t3:leaf=0.164297\n\t\t4:leaf=0.337241\n\t2:leaf=0.510185\n',
 '0:[x<2] yes=1,no=2,missing=1\n\t1:leaf=0.115008\n\t2:[x<3] yes=3,no=4,missing=3\n\t\t3:leaf=0.236069\n\t\t4:leaf=0.357129\n']

Совет: я на самом деле предпочитаю использовать классы xgb.XGBRegressor или xgb.XGBClassifier, так как они следуют API обучения sci-kit . А поскольку sci-kit learn имеет так много реализаций алгоритма машинного обучения, использование XGB в качестве дополнительной библиотеки не мешает моему рабочему процессу, только когда я использую интерфейс sci-kit XGBoost.


Как установить с "booster":"gblinear"помощьюxgb.XGBRegressor
yosemite_k

Лучше ли запускать функцию нормализации при использовании gblinearбустера?
поперчил
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.