วิธีการปรับค่าพารามิเตอร์ไฮเปอร์ของต้น xgboost


68

ฉันมีข้อมูลที่ไม่สมดุลในชั้นเรียน & ฉันต้องการปรับแต่งพารามิเตอร์หลายมิติของปอยผมที่เพิ่มขึ้นโดยใช้ xgboost

คำถาม

  1. มีเทียบเท่าของ gridsearchcv หรือ randomsearchcv สำหรับ xgboost?
  2. หากไม่ใช่วิธีการที่แนะนำให้ปรับพารามิเตอร์ของ xgboost คืออะไร?


ขอบคุณ แต่ลิงค์นั้นพูดถึงปัญหาอื่น & ไม่ตอบคำถามของฉัน
GeorgeOfTheRF

การตั้งชื่อที่แน่นอนของพารามิเตอร์xgboost(max.depth)หรือxgb.train(max_depth)? xgboost ไม่สอดคล้องกันใช้ dot vs underscore สำหรับพารามิเตอร์ในที่ต่าง ๆ หรือไม่? หรือว่าพวกเขาเปลี่ยนใจ
smci

1
@ smci ตรวจสอบ "help (" xgboost-deprecated ")"
Hemant Rupani

คำตอบ:


82

ตั้งแต่อินเตอร์เฟซxgboostในcaretมีการเปลี่ยนแปลงเมื่อเร็ว ๆ นี้ที่นี่เป็นสคริปต์ที่ให้คำแนะนำให้ความเห็นอย่างเต็มที่ของการใช้caretการปรับแต่งxgboostHyper-พารามิเตอร์

สำหรับเรื่องนี้ผมจะใช้ข้อมูลการฝึกอบรมจากการแข่งขัน Kaggle "Give Me บางเครดิต"

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

สำหรับการค้นหาพารามิเตอร์หลายค่าเราดำเนินขั้นตอนต่อไปนี้:

  • สร้าง a 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")

สุดท้ายคุณสามารถสร้าง bubbleplot สำหรับ AUC ในรูปแบบต่างๆetaและmax_depth:

ป้อนคำอธิบายรูปภาพที่นี่


เครื่องหมายรูปหมวกยังคงสนับสนุนเฉพาะกทพ. แกมม่าและความลึกสูงสุดสำหรับการค้นหากริดเท่านั้น
GeorgeOfTheRF

2
xgboostตอนนี้@ML_Pro สนับสนุนพารามิเตอร์ส่วนใหญ่โดยเฉพาะอย่างยิ่งการสนับสนุนสำหรับgammaใหม่ นี่คือรายการทั้งหมดของพารามิเตอร์ที่รองรับ
tchakravarty

นั่นคือการสนับสนุนโดย xgboost ใช่มั้ย คำถามของฉันเกี่ยวกับพารามิเตอร์ทั้งหมดที่
คาเร็ต

1
การเปลี่ยนแปลงที่จำเป็นสำหรับการจำแนกประเภทหลายคลาสคืออะไร นอกจากนี้เอกสารกล่าวว่าใช้scale_pose_weightสำหรับการจัดหมวดหมู่ที่ไม่สมดุล คุณสามารถให้รายละเอียดเกี่ยวกับวิธีการได้หรือไม่? ขอบคุณ!
ลูกโซ่

1
สำหรับปัญหาคลาสที่ไม่สมดุลได้scale_pos_weightรับการบันทึกไว้ในเอกสารพารามิเตอร์แล้ว scale_pos_weightไม่ใช่พารามิเตอร์การปรับ Caret แต่คุณสามารถเปรียบเทียบได้ด้วยตนเอง ในกรณีของฉันการใช้น้ำหนักที่เกิดขึ้นมีผลเพียงเล็กน้อย (การจำแนกแบบไบนารี,> 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

ข้อเสียเปรียบอย่างหนึ่งที่ฉันเห็นคือ caret ปัจจุบันไม่รองรับพารามิเตอร์อื่น ๆ ของ xgboost

แก้ไข

Gamma, colsample_bytree, min_child_weight และกลุ่มย่อยอื่น ๆ สามารถปรับได้ทันที (2017 มิถุนายน) โดยใช้ Caret เพียงเพิ่มเข้าไปในส่วนกริดของโค้ดด้านบนเพื่อให้มันทำงานได้ ขอบคุณusεr11852สำหรับการไฮไลต์มันในความคิดเห็น


4
การอัปเดตเล็กน้อยเกี่ยวกับข้อเสียเปรียบที่กล่าวถึง caretตอนนี้ ( ก.พ. 2017) สนับสนุนพารามิเตอร์เพิ่มเติมสำหรับgamma, colsample_bytree, และmin_child_weight subsample(อย่างมีประสิทธิภาพคุณสามารถปรับเกือบทุกอย่าง - เวลาที่กำหนด)
usεr11852พูดว่า Reinstate Monic

10

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ฉันใช้วิธีการอื่นจากวิธีข้างต้น ฉันใช้ฟังก์ชัน BayesianOptimization จากแพ็คเกจการปรับให้เหมาะสมของ Bayesian เพื่อค้นหาพารามิเตอร์ที่ดีที่สุด ในการทำเช่นนี้คุณจะสร้างการตรวจสอบความถูกต้องข้ามก่อนจากนั้นสร้างฟังก์ชัน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
นี่เป็นวิธีการที่ดี แต่มีข้อแม้ : แพ็คเกจ 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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.