看起来你误解了xgb.cv
,它不是一个参数搜索函数。它只是进行了k折交叉验证,仅此而已。
在你的代码中,它没有改变param
的值。
要在R的XGBoost中找到最佳参数,有一些方法。以下是两种方法:
(1) 使用mlr
包,http://mlr-org.github.io/mlr-tutorial/release/html/
Kaggle的Prudential挑战赛中有一个XGBoost + mlr 示例代码,但该代码是用于回归问题而非分类问题。据我所知,mlr
包中还没有mlogloss
指标,因此你必须自己从头编写mlogloss度量。如有错误请指出。
(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_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 = 840
min_logloss = 2.2293, min_logloss_index = 920
min_logloss = 1.9745, min_logloss_index = 780
然后您必须使用第三个参数(它具有全局最小值min_logloss
为1.9745
)。 您的最佳指数(nrounds)为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。顺便说一下,这是随机方法的示例,您可以通过贝叶斯优化等方式进行调整以获得更好的方法。如果您有XGBoost的Python版本,则可以使用
https://github.com/mpearmain/BayesBoost进行良好的超参数脚本搜索以获取最佳参数设置。
编辑:我想在 Kaggle论坛上添加第三种手动方法,由 Kaggle 大师“Davut Polat”发布。
编辑:如果您了解 Python 和 sklearn,您还可以使用 GridSearchCV 与 xgboost.XGBClassifier 或 xgboost.XGBRegressor。
mdcv <- xgb.cv(data=dtrain, params = param, nthread=6, nfold=cv.nfold, nrounds=cv.nround, verbose = T, early.stop.round=8, maximize=FALSE)
,CV在测试日志损失增加了10多轮后仍未停止,对此有什么想法吗?谢谢! - snowneji