Ответ 1
Похоже, вы неправильно поняли xgb.cv
, это не функция поиска параметров. Это делает k-folds cross validation, не более того.
В вашем коде он не изменяет значение param
.
Чтобы найти лучшие параметры в R XGBoost, есть некоторые методы. Это 2 метода,
(1) Используйте пакет mlr
, http://mlr-org.github.io/mlr-tutorial/release/html/
В запросе Kaggle Prudential есть пример кода XGBoost + mlr,
Но этот код предназначен для регрессии, а не для классификации. Насколько я знаю, нет mlogloss
метрики еще в mlr
пакета, так что вы должны кодировать 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
- индекс (round).
Вы должны повторить процесс выше нескольких раз, каждый раз меняйте параметры вручную (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, есть хороший гиперпараметрический скрипт для XGBoost, https://github.com/mpearmain/BayesBoost для поиска лучших параметров, заданных с помощью байесовской оптимизации.
Изменение: я хочу добавить третий ручной метод, размещенный "Давут Полат" мастером Kaggle на форуме Kaggle.
Изменение: если вы знаете Python и sklearn, вы также можете использовать GridSearchCV вместе с xgboost.XGBClassifier или xgboost.XGBRegressor