看起來像你誤解了xgb.cv
,它不是一個參數搜索功能。它做了k-fold交叉驗證,僅此而已。
在您的代碼中,它不會更改param
的值。
要找到R的XGBoost中的最佳參數,有一些方法。這2種方法,
(1)使用mlr
包,http://mlr-org.github.io/mlr-tutorial/release/html/
有一個XGBoost + MLR example code在Kaggle保誠的挑戰,
但是,代碼是迴歸,而不是分類。據我所知,在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_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
然後,你必須使用第三個參數(它有全球最小的1.9745
min_logloss
)。你最好的索引(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。
附註:這是隨機方法的例子,您可以調整它,例如通過貝葉斯優化獲得更好的方法。如果您有Python版本的XGBoost,則XGBoost有一個很好的超參數腳本,https://github.com/mpearmain/BayesBoost可以使用貝葉斯優化搜索最佳參數集。
編輯:我想在Kaggle forum中添加第三種手動方法,由「Davut Polat」一位Kaggle大師發佈。
編輯:如果你知道Python和sklearn,你也可以使用GridSearchCV與xgboost.XGBClassifier或xgboost.XGBRegressor
沿
謝謝你的詳細解答,就像讀一本教科書!所以在這種情況下,cv的唯一目的是爲你選擇nrounds,這是否正確? – snowneji
@snowneji,是的,它可以這樣說,根據設定的某些參數選擇最佳的結果。因爲太小的缺陷是不合適的,太大的合適的過度配合。順便說一句,如果你發現我的答案是有用的,請接受它,謝謝。 – silo
好的,謝謝! – snowneji