Метрика оценки в наборе проверки в Python xgboost отличается от той, которую я получаю при прогнозировании - PullRequest
0 голосов
/ 22 февраля 2019

Я использую оценочный набор для реализации ранней остановки с помощью xgboost в Python.Меня озадачивает то, что показатель оценки, указанный во время обучения как оптимальный, намного лучше, чем тот, который я получаю, когда делаю прогнозы с той же моделью на наборе, который я использовал для целей оценки.

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

Код следующий:

import xgboost as xgb

import seaborn as sns

def xgb_mape(preds, dtrain):
   labels = dtrain.get_label()
   return('mape', np.mean(np.abs((labels - preds) / (labels+1))))

mpg = sns.load_dataset('mpg')

mpg = mpg.sample(frac = 1)

n = int(mpg.shape[0] * 0.7)

mpg_train = mpg.iloc[:n, :7]

mpg_test = mpg.iloc[n:, :7]

mpg_train_y = mpg_train.iloc[:, 0].values

mpg_test_y = mpg_test.iloc[:, 0].values

mpg_train_X = mpg_train.iloc[:, 1:].values

mpg_test_X = mpg_test.iloc[:, 1:].values

xgb_model_mpg = xgb.XGBRegressor(max_depth= 10, learning_rate=0.1, n_estimators=1000, silent=True, \
                                 objective='reg:linear',\
                 booster='gbtree', subsample= 0.6, colsample_bytree= 0.9, colsample_bylevel= 1, reg_lambda= 20 ,\
                 random_state=1 , seed= 1, importance_type='gain')

xgb_model_mpg.fit(mpg_train_X ,mpg_train_y , eval_set= [(mpg_test_X , mpg_test_y )], eval_metric= xgb_mape,\
              early_stopping_rounds= 20)
[...]
82] validation_0-rmse:3.41167   validation_0-mape:0.085761
[83]    validation_0-rmse:3.40828   validation_0-mape:0.085618
[84]    validation_0-rmse:3.40087   validation_0-mape:0.085519
[85]    validation_0-rmse:3.403 validation_0-mape:0.085631
[86]    validation_0-rmse:3.39977   validation_0-mape:0.085711
[87]    validation_0-rmse:3.39626   validation_0-mape:0.085739
[88]    validation_0-rmse:3.40048   validation_0-mape:0.085727
[89]    validation_0-rmse:3.40356   validation_0-mape:0.085883
[90]    validation_0-rmse:3.40341   validation_0-mape:0.085664
Stopping. Best iteration:
[70]    validation_0-rmse:3.42186   validation_0-mape:0.085076

XGBRegressor(base_score=0.5, booster='gbtree', colsample_bylevel=1,
       colsample_bytree=0.9, gamma=0, importance_type='gain',
       learning_rate=0.1, max_delta_step=0, max_depth=10,
       min_child_weight=1, missing=None, n_estimators=1000, n_jobs=1,
       nthread=None, objective='reg:linear', random_state=1, reg_alpha=0,
       reg_lambda=20, scale_pos_weight=1, seed=1, silent=True,
       subsample=0.6)

y_pred = xgb_model_mpg.predict(mpg_test_X)

results = pd.DataFrame({'actual':mpg_test_y, 'predictions' : y_pred})

results['Absolute_Percent_Error'] = 100 * np.abs(results['actual'] - results['predictions'])/results['actual']

MAPE = results['Absolute_Percent_Error'].mean()

MAPE
8.982732737486339

Так что в этом случае во время обучения я получаюMAPE 8,5% и при применении модели к тому же набору тестов, я получаю MAPE около 9%.

Как я уже говорил в других примерах с более крупными и сложными наборами данных, различия могут быть намного больше, например, 41% против 58%.

1 Ответ

0 голосов
/ 25 февраля 2019

Здесь есть две разные проблемы.Один маленький: у вас есть немного другое определение функции оценки в обучении xgb и за его пределами (в знаменателе в оценке xgb есть +1).Еще одна важная проблема: xgboost (в отличие от lightgbm) по умолчанию вычисляет прогнозы, используя все обученные деревья вместо лучшего количества деревьев .Для получения оптимального количества деревьев в прогнозе используйте y_pred = xgb_model_mpg.predict(mpg_test_X, ntree_limit=xgb_model_mpg.best_ntree_limit)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...