Как настроить гиперпараметры деревьев xgboost?


69

У меня есть несбалансированные данные класса, и я хочу настроить гиперпараметры усиленного тресса с помощью xgboost.

Вопросов

  1. Есть ли эквивалент для gridsearchcv или randomsearchcv для xgboost?
  2. Если нет, то каков рекомендуемый подход для настройки параметров xgboost?


Спасибо, но эта ссылка обсуждает другую проблему и не отвечает на мой вопрос.
GeorgeOfTheRF

Это точное наименование параметра xgboost(max.depth)или xgb.train(max_depth)? Использует ли xgboost непоследовательное использование точки и подчеркивания для параметра в разных местах? Или они обращены?
smci

1
@smci, проверьте "help (" xgboost-deprecated ")"
Hemant Rupani

Ответы:


82

Так как интерфейс к xgboostin in caretнедавно изменился, вот скрипт, который предоставляет полностью прокомментированное пошаговое руководство по использованию caretдля настройки xgboostгиперпараметров.

Для этого я буду использовать данные тренировок из конкурса Kaggle «Дай мне кредит» .

1. Подгонка xgboostмодели

В этом разделе мы:

  • подобрать xgboostмодель с произвольными гиперпараметрами
  • оценить потери (AUC-ROC) с помощью перекрестной проверки ( xgb.cv)
  • построить график обучения по сравнению с тестированием

Вот код для этого.

library(caret)
library(xgboost)
library(readr)
library(dplyr)
library(tidyr)

# load in the training data
df_train = read_csv("04-GiveMeSomeCredit/Data/cs-training.csv") %>%
  na.omit() %>%                                                                # listwise deletion 
  select(-`[EMPTY]`) %>%
  mutate(SeriousDlqin2yrs = factor(SeriousDlqin2yrs,                           # factor variable for classification
                                   labels = c("Failure", "Success")))

# xgboost fitting with arbitrary parameters
xgb_params_1 = list(
  objective = "binary:logistic",                                               # binary classification
  eta = 0.01,                                                                  # learning rate
  max.depth = 3,                                                               # max tree depth
  eval_metric = "auc"                                                          # evaluation/loss metric
)

# fit the model with the arbitrary parameters specified above
xgb_1 = xgboost(data = as.matrix(df_train %>%
                                   select(-SeriousDlqin2yrs)),
                label = df_train$SeriousDlqin2yrs,
                params = xgb_params_1,
                nrounds = 100,                                                 # max number of trees to build
                verbose = TRUE,                                         
                print.every.n = 1,
                early.stop.round = 10                                          # stop if no improvement within 10 trees
)

# cross-validate xgboost to get the accurate measure of error
xgb_cv_1 = xgb.cv(params = xgb_params_1,
                  data = as.matrix(df_train %>%
                                     select(-SeriousDlqin2yrs)),
                  label = df_train$SeriousDlqin2yrs,
                  nrounds = 100, 
                  nfold = 5,                                                   # number of folds in K-fold
                  prediction = TRUE,                                           # return the prediction using the final model 
                  showsd = TRUE,                                               # standard deviation of loss across folds
                  stratified = TRUE,                                           # sample is unbalanced; use stratified sampling
                  verbose = TRUE,
                  print.every.n = 1, 
                  early.stop.round = 10
)

# plot the AUC for the training and testing samples
xgb_cv_1$dt %>%
  select(-contains("std")) %>%
  mutate(IterationNum = 1:n()) %>%
  gather(TestOrTrain, AUC, -IterationNum) %>%
  ggplot(aes(x = IterationNum, y = AUC, group = TestOrTrain, color = TestOrTrain)) + 
  geom_line() + 
  theme_bw()

Вот как выглядит тестирование и обучение AUC:

введите описание изображения здесь

2. Поиск гиперпараметра с использованием train

Для поиска гиперпараметра мы выполняем следующие шаги:

  • создать data.frameс уникальными комбинациями параметров, для которых мы хотим обученные модели.
  • Укажите параметры управления, которые применяются к обучению каждой модели, включая параметры перекрестной проверки, и укажите, что вероятности должны быть рассчитаны так, чтобы можно было вычислить AUC
  • перекрестная проверка и обучение моделей для каждой комбинации параметров, сохраняя AUC для каждой модели.

Вот код, который показывает, как это сделать.

# set up the cross-validated hyper-parameter search
xgb_grid_1 = expand.grid(
  nrounds = 1000,
  eta = c(0.01, 0.001, 0.0001),
  max_depth = c(2, 4, 6, 8, 10),
  gamma = 1
)

# pack the training control parameters
xgb_trcontrol_1 = trainControl(
  method = "cv",
  number = 5,
  verboseIter = TRUE,
  returnData = FALSE,
  returnResamp = "all",                                                        # save losses across all models
  classProbs = TRUE,                                                           # set to TRUE for AUC to be computed
  summaryFunction = twoClassSummary,
  allowParallel = TRUE
)

# train the model for each parameter combination in the grid, 
#   using CV to evaluate
xgb_train_1 = train(
  x = as.matrix(df_train %>%
                  select(-SeriousDlqin2yrs)),
  y = as.factor(df_train$SeriousDlqin2yrs),
  trControl = xgb_trcontrol_1,
  tuneGrid = xgb_grid_1,
  method = "xgbTree"
)

# scatter plot of the AUC against max_depth and eta
ggplot(xgb_train_1$results, aes(x = as.factor(eta), y = max_depth, size = ROC, color = ROC)) + 
  geom_point() + 
  theme_bw() + 
  scale_size_continuous(guide = "none")

Наконец, вы можете создать пузырьковую диаграмму для AUC по вариантам etaи max_depth:

введите описание изображения здесь


Поддерживает ли Caret только ETA, гамму и максимальную глубину для поиска по сетке, как насчет подвыборки и других параметров xgboost?
GeorgeOfTheRF

2
@ML_Pro Поддержка большинства xgboostпараметров в настоящее время существует, в частности, поддержка gammaявляется новой. Вот полный список поддерживаемых параметров.
Чакраварти

Это поддержка xgboost, верно? Мой вопрос о том, какие параметры поддерживаются для поиска по сетке
GeorgeOfTheRF

1
Какие бы изменения потребовались для мультиклассовой классификации. Также документация говорит, что использование scale_pose_weightдля несбалансированной классификации. Можете ли вы предоставить подробную информацию о том, как? Спасибо!
ученик

1
Для несбалансированной проблемы класса, scale_pos_weightтеперь задокументировано в документации параметров . scale_pos_weightне является параметром настройки каретки, но вы можете сравнить вручную. В моем случае использование веса оказало незначительный эффект (бинарная классификация,> 20% положительных результатов)
geneorama

24

Пакет Caret включает в себя xgboost.

cv.ctrl <- trainControl(method = "repeatedcv", repeats = 1,number = 3, 
                        #summaryFunction = twoClassSummary,
                        classProbs = TRUE,
                        allowParallel=T)

    xgb.grid <- expand.grid(nrounds = 1000,
                            eta = c(0.01,0.05,0.1),
                            max_depth = c(2,4,6,8,10,14)
    )
    set.seed(45)
    xgb_tune <-train(formula,
                     data=train,
                     method="xgbTree",
                     trControl=cv.ctrl,
                     tuneGrid=xgb.grid,
                     verbose=T,
                     metric="Kappa",
                     nthread =3
    )

Образец вывода

eXtreme Gradient Boosting 

32218 samples
   41 predictor
    2 classes: 'N', 'Y' 

No pre-processing
Resampling: Cross-Validated (3 fold, repeated 1 times) 
Summary of sample sizes: 21479, 21479, 21478 
Resampling results

  Accuracy   Kappa      Accuracy SD   Kappa SD   
  0.9324911  0.1094426  0.0009742774  0.008972911

Один недостаток, который я вижу, заключается в том, что другие параметры xgboost, такие как subsample и т. Д., В настоящее время не поддерживаются кареткой.

редактировать

Gamma, colsample_bytree, min_child_weight, subsample и т. Д. Теперь (июнь 2017 г.) могут быть настроены напрямую с помощью Caret. Просто добавьте их в часть сетки приведенного выше кода, чтобы он заработал. Спасибо usεr11852 за выделение в комментарии.


4
Незначительное обновление относительно упомянутого недостатка. caretсейчас (февраль-2017) поддерживает дополнительные параметры gamma, colsample_bytree, min_child_weightи subsample. (Таким образом, вы можете эффективно настроить практически все - учитывая время)
usεr11852 говорит Reinstate Monic

10

Я знаю, что это старый вопрос, но я использую метод, отличный от приведенного выше. Я использую функцию BayesianOptimization из пакета Bayesian Optimization, чтобы найти оптимальные параметры. Для этого вы сначала создаете перекрестные проверки, а затем создаете функцию xgb.cv.bayes, имеющую в качестве параметров повышающие гиперпараметры, которые вы хотите изменить. В этом примере я настраиваюсь max.depth, min_child_weight, subsample, colsample_bytree, gamma. Затем вы вызываете xgb.cvэту функцию с гиперпараметрами, установленными во входные параметры xgb.cv.bayes. Затем вы звоните BayesianOptimizationс xgb.cv.bayesжелаемыми диапазонами повышающих гиперпараметров. init_pointsчисло исходных моделей с гиперпараметрами, взятых случайным образом из указанных диапазонов, иn_iterколичество раундов моделей после начальных очков. Функция выводит все параметры усиления и тест AUC.

cv_folds <- KFold(as.matrix(df.train[,target.var]), nfolds = 5, 
                  stratified = TRUE, seed = 50)
xgb.cv.bayes <- function(max.depth, min_child_weight, subsample, colsample_bytree, gamma){
  cv <- xgv.cv(params = list(booster = 'gbtree', eta = 0.05,
                             max_depth = max.depth,
                             min_child_weight = min_child_weight,
                             subsample = subsample,
                             colsample_bytree = colsample_bytree,
                             gamma = gamma,
                             lambda = 1, alpha = 0,
                             objective = 'binary:logistic',
                             eval_metric = 'auc'),
                 data = data.matrix(df.train[,-target.var]),
                 label = as.matrix(df.train[, target.var]),
                 nround = 500, folds = cv_folds, prediction = TRUE,
                 showsd = TRUE, early.stop.round = 5, maximize = TRUE,
                 verbose = 0
  )
  list(Score = cv$dt[, max(test.auc.mean)],
       Pred = cv$pred)
}

xgb.bayes.model <- BayesianOptimization(
  xgb.cv.bayes,
  bounds = list(max.depth = c(2L, 12L),
                min_child_weight = c(1L, 10L),
                subsample = c(0.5, 1),
                colsample_bytree = c(0.1, 0.4),
                gamma = c(0, 10)
  ),
  init_grid_dt = NULL,
  init_points = 10,  # number of random points to start search
  n_iter = 20, # number of iterations after initial random points are set
  acq = 'ucb', kappa = 2.576, eps = 0.0, verbose = TRUE
)

1
Это хороший подход, но есть предостережение : R-пакет rBayesianOptimization, начиная с последней версии CRAN 1.1.0 (который не обновлялся более 2 лет), не имеет тестов и более ограничительной лицензии, чем Python. Пакет оригинальных авторов метода, который имеет тесты. См. Github.com/fmfn/BayesianOptimization .
Egnha

8

Это старый вопрос, но я подумаю, что поделюсь настройкой параметров xgboost. Первоначально я думал, что буду использовать каретку для этого, но недавно обнаружил проблему с обработкой всех параметров, а также пропущенных значений. Я также рассматривал возможность написания итерационного цикла для различных комбинаций параметров, но хотел, чтобы он работал параллельно и потребовал слишком много времени. Использование gridSearch из пакета NMOF дало лучшее из обоих миров (все параметры, а также параллельная обработка). Вот пример кода для двоичной классификации (работает на Windows и Linux):

# xgboost task parameters
nrounds <- 1000
folds <- 10
obj <- 'binary:logistic'
eval <- 'logloss'

# Parameter grid to search
params <- list(
  eval_metric = eval,
  objective = obj,
  eta = c(0.1,0.01),
  max_depth = c(4,6,8,10),
  max_delta_step = c(0,1),
  subsample = 1,
  scale_pos_weight = 1
)

# Table to track performance from each worker node
res <- data.frame()

# Simple cross validated xgboost training function (returning minimum error for grid search)
xgbCV <- function (params) {
  fit <- xgb.cv(
    data = data.matrix(train), 
    label = trainLabel, 
    param =params, 
    missing = NA, 
    nfold = folds, 
    prediction = FALSE,
    early.stop.round = 50,
    maximize = FALSE,
    nrounds = nrounds
  )
  rounds <- nrow(fit)
  metric = paste('test.',eval,'.mean',sep='')
  idx <- which.min(fit[,fit[[metric]]]) 
  val <- fit[idx,][[metric]]
  res <<- rbind(res,c(idx,val,rounds))
  colnames(res) <<- c('idx','val','rounds')
  return(val)
}

# Find minimal testing error in parallel
cl <- makeCluster(round(detectCores()/2)) 
clusterExport(cl, c("xgb.cv",'train','trainLabel','nrounds','res','eval','folds'))
sol <- gridSearch(
  fun = xgbCV,
  levels = params,
  method = 'snow',
  cl = cl,
  keepNames = TRUE,
  asList = TRUE
)

# Combine all model results
comb=clusterEvalQ(cl,res)
results <- ldply(comb,data.frame)
stopCluster(cl)

# Train model given solution above
params <- c(sol$minlevels,objective = obj, eval_metric = eval)
xgbModel <- xgboost(
  data = xgb.DMatrix(data.matrix(train),missing=NaN, label = trainLabel),
  param = params,
  nrounds = results[which.min(results[,2]),1]
)

print(params)
print(results)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.