R语言中的xgboost:xgb.cv如何将最优参数传递给xgb.train

我在探索R语言中的xgboost包,并查看了几个演示和教程,但这仍然让我感到困惑:在使用xgb.cv进行交叉验证后,最优参数是如何传递给xgb.train的?或者我应该根据xgb.cv的输出计算理想参数(如nroundmax.depth)吗?

param <- list("objective" = "multi:softprob",              "eval_metric" = "mlogloss",              "num_class" = 12)cv.nround <- 11cv.nfold <- 5mdcv <-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)

回答:

看起来你误解了xgb.cv,它不是一个参数搜索函数。它只是进行k折交叉验证,仅此而已。

在你的代码中,它不会改变param的值。

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

(1) 使用mlr包,http://mlr-org.github.io/mlr-tutorial/release/html/

在Kaggle的Prudential挑战中,有一个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 = 1000cv.nfold = 5mdcv <- 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_logloss是mlogloss的最小值,而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 = 840min_logloss = 2.2293, min_logloss_index = 920min_logloss = 1.9745, min_logloss_index = 780

那么你必须使用第三组参数(它具有全局最小min_logloss1.9745)。你最佳的索引(nrounds)是780

一旦你得到最佳参数,就在训练中使用它,

# best_param 是具有最小 min_logloss 的全局最佳参数# best_min_logloss_index 是全局最小 logloss 索引nround = 780md <- 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 = 1234best_logloss = Infbest_logloss_index = 0for (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_indexset.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大师”Davut Polat”在Kaggle论坛中发布。

编辑:如果你熟悉Python和sklearn,你也可以使用GridSearchCV以及xgboost.XGBClassifier或xgboost.XGBRegressor

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注