XGBoost早期停止cv与GridSearchCV

时间:2017-04-21 12:06:58

标签: python random-forest xgboost

我正在尝试XGBoost来解决回归问题。在超参数调整的过程中, XGBoost的早期停止cv永远不会停止我的代码/数据,无论参数num_boost_round被设置为。此外,它产生比GridSearchCV更差的RMSE分数。 我在这里做错了什么?  而且,如果我没有做错任何事情,那么早期停止cv对GridSearchCV的优势是什么?

GridSearchCV:

import math
def RMSE(y_true, y_pred):
    rmse = math.sqrt(mean_squared_error(y_true, y_pred))
    print 'RMSE: %2.3f' % rmse
    return rmse
scorer = make_scorer(RMSE, greater_is_better=False)

cv_params = {'max_depth': [2,8], 'min_child_weight': [1,5]}
ind_params = {'learning_rate': 0.01, 'n_estimators': 1000, 
              'seed':0, 'subsample': 0.8, 'colsample_bytree': 0.8,
             'reg_alpha':0, 'reg_lambda':1} #regularization => L1 : alpha, L2 : lambda
optimized_GBM = GridSearchCV(xgb.XGBRegressor(**ind_params), 
                             cv_params, 
                             scoring = scorer, 
                             cv = 5, verbose=1,
                             n_jobs = 1)
optimized_GBM.fit(train_X, train_Y)
optimized_GBM.grid_scores_

输出:

[mean: -62.42736, std: 5.18004, params: {'max_depth': 2, 'min_child_weight': 1},
 mean: -62.42736, std: 5.18004, params: {'max_depth': 2, 'min_child_weight': 5},
 mean: -57.11358, std: 3.62918, params: {'max_depth': 8, 'min_child_weight': 1},
 mean: -57.12148, std: 3.64145, params: {'max_depth': 8, 'min_child_weight': 5}]

XGBoost简历:

our_params = {'eta': 0.01, 'max_depth':8, 'min_child_weight':1,
              'seed':0, 'subsample': 0.8, 'colsample_bytree': 0.8, 
             'objective': 'reg:linear', 'booster':'gblinear', 
              'eval_metric':'rmse',
             'silent':False}
num_rounds=1000

cv_xgb = xgb.cv(params = our_params, 
                dtrain = train_mat, 
                num_boost_round = num_rounds, 
                nfold = 5,
                metrics = ['rmse'], # Make sure you enter metrics inside a list or you may encounter issues!
                early_stopping_rounds = 100, # Look for early stopping that minimizes error
               verbose_eval = True) 

print cv_xgb.shape
print cv_xgb.tail(5)

输出:

(1000, 4)
     test-rmse-mean  test-rmse-std  train-rmse-mean  train-rmse-std
995       89.937926       0.263546        89.932823        0.062540
996       89.937773       0.263537        89.932671        0.062537
997       89.937622       0.263526        89.932517        0.062535
998       89.937470       0.263516        89.932364        0.062532
999       89.937317       0.263510        89.932210        0.062525

1 个答案:

答案 0 :(得分:0)

我有同样的问题XGboost忽略num_boost_rounds(当指定提前停止时)并继续适合。我打赌这是一个错误。

至于早期停止GridSearchCV的优势:

优势在于您不必为num_boost_rounds尝试一系列值,但您会自动停止在最佳位置。

提前停止旨在找到最佳的增强迭代次数。如果为num_boost_round(即10000)指定一个非常大的数字,并且最佳树数为5261,它将停在5261 + early_stopping_rounds,为您提供一个非常接近最佳值的模型。

如果你想在没有早期停止回合的情况下使用GridSearchCV找到相同的最佳值,你将不得不尝试许多不同的num_boost_rounds值(即100,200,300,...,5000,5100,5200,5300,......等... )。这将花费更长的时间。

早期停止利用的属性是有一个最佳数量的提升步骤,之后验证错误开始增加。所以......

为什么它对您的案件不起作用?

如果没有数据,

无法准确说出,但可能是因为以下各项的结合:

  • num_boost_round太小了(你遇到了xgboost重置并重新开始的bug,造成了一个无休止的循环)
  • early_stopping_rounds太大(也许你的数据有一个强烈振荡的收敛行为。尝试一个较小的值,看看CV错误是否足够好)
  • 您的验证数据可能有些奇怪

为什么您在GridSearchCV和xgboost.cv之间看到不同的结果?

如果没有完整的工作示例很难分辨,但是您已经检查了仅在两个接口之一中指定的变量的所有默认值(例如' reg_alpha':0,&#39 ; reg_lambda':1,' objective':' reg:linear',' booster':' gblinear')以及您的定义RMSE与xgboost的定义完全匹配?