Bagaimana cara menyetel hyperparameter pohon xgboost?

69

Saya memiliki data yang tidak seimbang kelas & saya ingin menyetel hyperparameter dari tress yang ditingkatkan menggunakan xgboost.

Pertanyaan

  1. Apakah ada yang setara dengan gridsearchcv atau randomsearchcv untuk xgboost?
  2. Jika tidak, apa pendekatan yang disarankan untuk menyesuaikan parameter xgboost?
GeorgeOfTheRF
sumber
Terima kasih tetapi tautan itu membahas masalah yang berbeda & tidak menjawab pertanyaan saya.
GeorgeOfTheRF
Apakah penamaan parameter yang tepat xgboost(max.depth)atau xgb.train(max_depth)? Apakah xgboost tidak konsisten menggunakan dot vs garis bawah untuk parameter di tempat yang berbeda? Atau apakah mereka bertobat?
smci
1
@smci, periksa "help (" xgboost-deprecated ")"
Hemant Rupani

Jawaban:

82

Karena antarmuka ke xgboostdalam caretbaru-baru ini berubah, berikut ini adalah skrip yang memberikan langkah-langkah penggunaan komentar sepenuhnya caretuntuk menyetel xgboostparameter-hyper.

Untuk ini, saya akan menggunakan data pelatihan dari kompetisi Kaggle "Give Me Some Credit" .

1. Pas xgboostmodel

Di bagian ini, kami:

  • cocok dengan xgboostmodel dengan hiperparameter acak
  • mengevaluasi kerugian (AUC-ROC) menggunakan cross-validation ( xgb.cv)
  • merencanakan pelatihan versus metrik evaluasi evaluasi

Berikut ini beberapa kode untuk melakukannya.

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()

Di sini adalah seperti apa pengujian versus pelatihan AUC:

masukkan deskripsi gambar di sini

2. Pencarian menggunakan Hyperparameter train

Untuk pencarian hyperparameter, kami melakukan langkah-langkah berikut:

  • buat data.framedengan kombinasi parameter unik yang kami inginkan untuk model yang terlatih.
  • Tentukan parameter kontrol yang berlaku untuk setiap pelatihan model, termasuk parameter validasi silang, dan tentukan bahwa probabilitas dihitung sehingga AUC dapat dihitung
  • validasi silang & latih model untuk setiap kombinasi parameter, simpan AUC untuk setiap model.

Berikut adalah beberapa kode yang menunjukkan cara melakukan ini.

# 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")

Terakhir, Anda dapat membuat bubbleplot untuk AUC atas variasi etadan max_depth:

masukkan deskripsi gambar di sini

tchakravarty
sumber
Apakah caret masih hanya mendukung eta, gamma, dan kedalaman maksimum untuk pencarian kisi, bagaimana dengan subsampel dan parameter xgboost lainnya?
GeorgeOfTheRF
2
@ML_Pro Dukungan untuk sebagian besar xgboostparameter sekarang ada, khususnya dukungan untuk gammabaru. Berikut adalah daftar lengkap parameter yang didukung.
tchakravarty
Itu didukung oleh xgboost kan? Pertanyaan saya adalah tentang semua parameter yang mendukung caret untuk pencarian grid
GeorgeOfTheRF
1
Apa yang akan menjadi perubahan yang diperlukan untuk klasifikasi multi-kelas. Juga dokumentasi mengatakan digunakan scale_pose_weightuntuk klasifikasi yang tidak seimbang. Bisakah Anda memberikan detail bagaimana caranya? Terima kasih!
Disiplin
1
Untuk masalah kelas yang tidak seimbang, scale_pos_weightsekarang didokumentasikan dalam dokumentasi parameter . scale_pos_weightbukan parameter penyetelan tanda sisipan, tetapi Anda dapat membandingkannya secara manual. Dalam kasus saya, menggunakan bobot kebetulan memiliki sedikit efek (klasifikasi biner,> 20% positif)
geneorama
24

Paket caret telah memasukkan 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
    )

Output sampel

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

Satu kekurangan yang saya lihat adalah bahwa parameter xgboost lainnya seperti subsample dll tidak didukung oleh caret saat ini.

Sunting

Gamma, colsample_bytree, min_child_weight dan subsample dll sekarang (Juni 2017) dapat disetel langsung menggunakan Caret. Cukup tambahkan mereka di bagian grid dari kode di atas untuk membuatnya berfungsi. Terima kasih usεr11852 karena telah menyorotnya di komentar.

GeorgeOfTheRF
sumber
4
Pembaruan kecil tentang kelemahan yang disebutkan. caretsekarang (Februari-2017) mendukung parameter tambahan untuk gamma, colsample_bytree, min_child_weightdan subsample. (Jadi secara efektif Anda dapat menyetel hampir semua hal - diberikan waktu)
usεr11852 mengatakan Reinstate Monic
10

Saya tahu ini adalah pertanyaan lama, tetapi saya menggunakan metode yang berbeda dari yang di atas. Saya menggunakan fungsi BayesianOptimization dari paket Bayesian Optimization untuk menemukan parameter optimal. Untuk melakukan ini, pertama-tama Anda membuat lipatan validasi silang, lalu buat fungsi xgb.cv.bayesyang memiliki parameter parameter peningkatan boosting yang ingin Anda ubah. Dalam contoh ini saya menyetel max.depth, min_child_weight, subsample, colsample_bytree, gamma. Anda kemudian memanggil xgb.cvfungsi itu dengan parameter hiper diatur ke dalam parameter input xgb.cv.bayes. Kemudian Anda menelepon BayesianOptimizationdengan xgb.cv.bayesdan kisaran yang diinginkan dari parameter hiper penambah. init_pointsadalah jumlah model awal dengan parameter hiper yang diambil secara acak dari rentang yang ditentukan, dann_iteradalah jumlah putaran model setelah poin awal. Fungsi ini mengeluarkan semua parameter penguat dan tes 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
)
Bryan Schwimmer
sumber
1
Ini adalah pendekatan yang baik, tetapi ada peringatan : paket R rBayesianOptimization, pada CRAN versi terbaru 1.1.0 (yang belum diperbarui dalam lebih dari 2 tahun), tidak memiliki tes dan lisensi yang lebih ketat daripada Python paket oleh penulis asli metode ini, yang memiliki tes. Lihat github.com/fmfn/BayesianOptimization .
egnha
8

Ini adalah pertanyaan yang lebih lama tetapi saya pikir saya akan membagikan bagaimana saya menyetel parameter xgboost. Saya awalnya berpikir saya akan menggunakan tanda sisipan untuk ini, tetapi baru-baru ini menemukan masalah menangani semua parameter serta nilai-nilai yang hilang. Saya juga mempertimbangkan untuk menulis loop berulang melalui kombinasi parameter yang berbeda tetapi ingin itu berjalan secara paralel dan akan membutuhkan terlalu banyak waktu. Menggunakan gridSearch dari paket NMOF memberikan yang terbaik dari kedua dunia (semua parameter serta pemrosesan paralel). Berikut adalah contoh kode untuk klasifikasi biner (berfungsi di windows dan 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)
John Richardson
sumber