R中的xgboost:xgb.cv如何将最佳参数传递给xgb.train
machine-learning
r
xgboost
9
0

我一直在探索R中的xgboost软件包,并进行了一些演示和教程,但这仍然使我感到困惑:使用xgb.cv进行交叉验证后,如何将最佳参数传递给xgb.train ?或者我应该计算理想的参数(如nroundmax.depth基础上的输出) xgb.cv

param <- list("objective" = "multi:softprob",
              "eval_metric" = "mlogloss",
              "num_class" = 12)
cv.nround <- 11
cv.nfold <- 5
mdcv <-xgb.cv(data=dtrain,params = param,nthread=6,nfold = cv.nfold,nrounds = cv.nround,verbose = T)

md <-xgb.train(data=dtrain,params = param,nround = 80,watchlist = list(train=dtrain,test=dtest),nthread=6)
参考资料:
Stack Overflow
收藏
评论
共 2 个回答
高赞 时间 活跃

这是一个很好的问题,来自筒仓的详细答复非常多!我发现这对像我这样的xgboost很有帮助。谢谢。随机化并与边界进行比较的方法很有启发性。很好使用和知道。现在在2018年需要稍作修改,例如, early.stop.round应该是early_stopping_rounds 。输出mdcv的组织方式略有不同:

  min_rmse_index  <-  mdcv$best_iteration
  min_rmse <-  mdcv$evaluation_log[min_rmse_index]$test_rmse_mean

并取决于应用程序(线性,逻辑等), objectiveeval_metric和参数应相应调整。

为了方便运行回归的人员,这是经过稍微调整的代码版本(大多数与上面的代码相同)。

library(xgboost)
# Matrix for xgb: dtrain and dtest, "label" is the dependent variable
dtrain <- xgb.DMatrix(X_train, label = Y_train)
dtest <- xgb.DMatrix(X_test, label = Y_test)

best_param <- list()
best_seednumber <- 1234
best_rmse <- Inf
best_rmse_index <- 0

set.seed(123)
for (iter in 1:100) {
  param <- list(objective = "reg:linear",
                eval_metric = "rmse",
                max_depth = sample(6:10, 1),
                eta = runif(1, .01, .3), # Learning rate, default: 0.3
                subsample = runif(1, .6, .9),
                colsample_bytree = runif(1, .5, .8), 
                min_child_weight = sample(1:40, 1),
                max_delta_step = sample(1:10, 1)
  )
  cv.nround <-  1000
  cv.nfold <-  5 # 5-fold cross-validation
  seed.number  <-  sample.int(10000, 1) # set seed for the cv
  set.seed(seed.number)
  mdcv <- xgb.cv(data = dtrain, params = param,  
                 nfold = cv.nfold, nrounds = cv.nround,
                 verbose = F, early_stopping_rounds = 8, maximize = FALSE)

  min_rmse_index  <-  mdcv$best_iteration
  min_rmse <-  mdcv$evaluation_log[min_rmse_index]$test_rmse_mean

  if (min_rmse < best_rmse) {
    best_rmse <- min_rmse
    best_rmse_index <- min_rmse_index
    best_seednumber <- seed.number
    best_param <- param
  }
}

# The best index (min_rmse_index) is the best "nround" in the model
nround = best_rmse_index
set.seed(best_seednumber)
xg_mod <- xgboost(data = dtest, params = best_param, nround = nround, verbose = F)

# Check error in testing data
yhat_xg <- predict(xg_mod, dtest)
(MSE_xgb <- mean((yhat_xg - Y_test)^2))
收藏
评论

看起来您误解了xgb.cv ,它不是参数搜索功能。它做k折交叉验证,仅此而已。

在您的代码中,它不会更改param的值。

为了在R的XGBoost中找到最佳参数,有一些方法。这是两种方法,

(1)使用mlr软件包, http: mlr

Kaggle的审慎挑战赛中有一个XGBoost + mlr 示例代码

但是该代码用于回归,而不是分类。据我所知, mlr包中还没有mlogloss度量标准,因此您必须自己重新编写mlogloss测量值。 CMIIW。

(2)第二种方法,通过手动设置参数然后重复,例如

param <- list(objective = "multi:softprob",
      eval_metric = "mlogloss",
      num_class = 12,
      max_depth = 8,
      eta = 0.05,
      gamma = 0.01, 
      subsample = 0.9,
      colsample_bytree = 0.8, 
      min_child_weight = 4,
      max_delta_step = 1
      )
cv.nround = 1000
cv.nfold = 5
mdcv <- xgb.cv(data=dtrain, params = param, nthread=6, 
                nfold=cv.nfold, nrounds=cv.nround,
                verbose = T)

然后,您找到最好的(最小)mlogloss,

min_logloss = min(mdcv[, test.mlogloss.mean])
min_logloss_index = which.min(mdcv[, test.mlogloss.mean])

min_loglossmin_logloss的最小值,而min_logloss_index是索引( min_logloss_index )。

您必须多次重复上述过程,每次手动更改参数( mlr会为您重复一次)。最终,您将获得最佳的全局最小值min_logloss

注意:您可以循环执行100或200次迭代,在该循环中,您可以为每个迭代随机设置参数值。这样,您必须将最佳的[parameters_list, min_logloss, min_logloss_index]在变量或文件中。

注意:最好通过set.seed()设置随机种子以获得可重现的结果。不同的随机种子产生不同的结果。因此,必须将[parameters_list, min_logloss, min_logloss_index, seednumber]在变量或文件中。

假设您最终在3次迭代/重复中获得3个结果:

min_logloss = 2.1457, min_logloss_index = 840
min_logloss = 2.2293, min_logloss_index = 920
min_logloss = 1.9745, min_logloss_index = 780

然后,您必须使用第三个参数(全局最小min_logloss1.9745 )。您的最佳指数(大约)是780

获得最佳参数后,请在训练中使用它,

# best_param is global best param with minimum min_logloss
# best_min_logloss_index is the global minimum logloss index
nround = 780
md <- xgb.train(data=dtrain, params=best_param, nrounds=nround, nthread=6)

我认为您在培训中不需要watchlist ,因为您已经进行了交叉验证。但是,如果您仍然想使用watchlist ,那就可以了。

更好的是,您可以在xgb.cv使用早期停止。

mdcv <- xgb.cv(data=dtrain, params=param, nthread=6, 
                nfold=cv.nfold, nrounds=cv.nround,
                verbose = T, early.stop.round=8, maximize=FALSE)

使用此代码,当mlogloss值未以8步减少时, xgb.cv将停止。您可以节省时间。您必须将maximize设置为FALSE ,因为您期望最小的mlogloss。

这是一个示例代码,具有100次迭代循环和随机选择的参数。

best_param = list()
best_seednumber = 1234
best_logloss = Inf
best_logloss_index = 0

for (iter in 1:100) {
    param <- list(objective = "multi:softprob",
          eval_metric = "mlogloss",
          num_class = 12,
          max_depth = sample(6:10, 1),
          eta = runif(1, .01, .3),
          gamma = runif(1, 0.0, 0.2), 
          subsample = runif(1, .6, .9),
          colsample_bytree = runif(1, .5, .8), 
          min_child_weight = sample(1:40, 1),
          max_delta_step = sample(1:10, 1)
          )
    cv.nround = 1000
    cv.nfold = 5
    seed.number = sample.int(10000, 1)[[1]]
    set.seed(seed.number)
    mdcv <- xgb.cv(data=dtrain, params = param, nthread=6, 
                    nfold=cv.nfold, nrounds=cv.nround,
                    verbose = T, early.stop.round=8, maximize=FALSE)

    min_logloss = min(mdcv[, test.mlogloss.mean])
    min_logloss_index = which.min(mdcv[, test.mlogloss.mean])

    if (min_logloss < best_logloss) {
        best_logloss = min_logloss
        best_logloss_index = min_logloss_index
        best_seednumber = seed.number
        best_param = param
    }
}

nround = best_logloss_index
set.seed(best_seednumber)
md <- xgb.train(data=dtrain, params=best_param, nrounds=nround, nthread=6)

使用此代码,您可以使用随机参数运行交叉验证100次。然后,您将获得最佳的参数集,即在最小min_logloss的迭代中。

如果发现它太小(太早停止),请增加early.stop.round的值。您还需要根据数据特征更改随机参数值的限制。

而且,对于100或200次迭代,我想您希望将verbose更改为FALSE。

旁注:这是随机方法的示例,您可以通过贝叶斯优化对其进行调整,以获得更好的方法。如果您具有Python版本的XGBoost,则有一个适用于XGBoost的很好的超参数脚本, https://github.com/mpearmain/BayesBoost可以搜索使用贝叶斯优化设置的最佳参数。

编辑:我想在Kaggle论坛中添加第三种手动方法,由Kaggle大师“ Davut Polat”发布。

编辑:如果您知道Python和sklearn,还可以将GridSearchCV与xgboost.XGBClassifier或xgboost.XGBRegressor一起使用

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题