Làm thế nào để điều chỉnh siêu âm của cây xgboost?


68

Tôi có một dữ liệu mất cân bằng lớp và tôi muốn điều chỉnh các siêu đường kính của tress được tăng cường bằng xgboost.

Câu hỏi

  1. Có tương đương với gridsearchcv hoặc randomsearchcv cho xgboost không?
  2. Nếu không, cách tiếp cận được đề xuất để điều chỉnh các tham số của xgboost là gì?


Cảm ơn nhưng liên kết đó thảo luận về một vấn đề khác và không trả lời câu hỏi của tôi.
GeorgeOfTheRF

Là đặt tên chính xác của tham số xgboost(max.depth)hay xgb.train(max_depth)? Xgboost có nhất quán sử dụng dấu chấm so với dấu gạch dưới cho tham số ở các vị trí khác nhau không? Hay chúng được chuyển đổi?
smci

1
@smci, kiểm tra "trợ giúp (" xgboost-deprecated ")"
Hemant Rupani

Câu trả lời:


82

Do giao diện xgboosttrong caretgần đây đã thay đổi, đây là tập lệnh cung cấp hướng dẫn được nhận xét đầy đủ về việc sử dụng caretđể điều chỉnh xgboostsiêu tham số.

Đối với điều này, tôi sẽ sử dụng dữ liệu đào tạo từ cuộc thi Kaggle "Cho tôi một số tín dụng" .

1. Lắp một xgboostmô hình

Trong phần này, chúng tôi:

  • phù hợp với một xgboostmô hình với siêu đường kính tùy ý
  • đánh giá tổn thất (AUC-ROC) bằng cách sử dụng xác thực chéo ( xgb.cv)
  • vẽ sơ đồ so với kiểm tra đánh giá số liệu

Đây là một số mã để làm điều này.

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

Đây là những gì kiểm tra so với đào tạo AUC trông giống như:

nhập mô tả hình ảnh ở đây

2. Tìm kiếm siêu tham số bằng cách sử dụng train

Đối với tìm kiếm siêu tham số, chúng tôi thực hiện các bước sau:

  • tạo ra một data.framesự kết hợp độc đáo của các tham số mà chúng tôi muốn các mô hình được đào tạo.
  • Chỉ định các tham số điều khiển áp dụng cho đào tạo của từng mô hình, bao gồm các tham số xác thực chéo và chỉ định rằng các xác suất được tính toán để AUC có thể được tính toán
  • xác nhận chéo & huấn luyện các mô hình cho từng kết hợp tham số, lưu AUC cho từng mô hình.

Đây là một số mã cho thấy làm thế nào để làm điều này.

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

Cuối cùng, bạn có thể tạo một bong bóng cho AUC qua các biến thể của etamax_depth:

nhập mô tả hình ảnh ở đây


Có caret vẫn chỉ hỗ trợ eta, gamma và độ sâu tối đa cho tìm kiếm lưới, còn mẫu phụ và các thông số khác của xgboost thì sao?
GeorgeOfTheRF

2
@ML_Pro Hỗ trợ cho hầu hết xgboostcác tham số hiện tồn tại, đặc biệt là hỗ trợ gammamới. Dưới đây là danh sách đầy đủ các tham số được hỗ trợ.
tchakravarty

Đó là hỗ trợ của xgboost phải không? Câu hỏi của tôi là về tất cả các tham số hỗ trợ caret cho tìm kiếm lưới
GeorgeOfTheRF

1
Điều gì sẽ là những thay đổi cần thiết cho phân loại đa lớp. Ngoài ra tài liệu nói rằng sử dụng scale_pose_weightđể phân loại mất cân bằng. Bạn có thể cung cấp chi tiết về làm thế nào để? Cảm ơn!
discipulus

1
Đối với vấn đề lớp không cân bằng, scale_pos_weighthiện được ghi lại trong tài liệu tham số . scale_pos_weightkhông phải là một tham số điều chỉnh dấu mũ, nhưng bạn có thể so sánh bằng tay. Trong trường hợp của tôi, việc sử dụng trọng lượng xảy ra ít ảnh hưởng (phân loại nhị phân,> 20% dương tính)
genorama

24

Gói caret đã kết hợp 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
    )

Sản lượng mẫu

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

Một nhược điểm tôi thấy là các thông số khác của xgboost như mẫu phụ, v.v. hiện không được caret hỗ trợ.

Biên tập

Gamma, colsample_bytree, min_child_ weight và mẫu phụ v.v ... giờ đây có thể được điều chỉnh trực tiếp bằng Caret. Chỉ cần thêm chúng vào phần lưới của đoạn mã trên để làm cho nó hoạt động. Cảm ơn chúng tôiεr11852 vì đã đánh dấu nó trong bình luận.


4
Một cập nhật nhỏ liên quan đến nhược điểm được đề cập. caretbây giờ (Feb-2017) hỗ trợ tham số bổ sung cho gamma, colsample_bytree, min_child_weightsubsample. (Rất hiệu quả, bạn có thể điều chỉnh hầu hết mọi thứ - thời gian nhất định)
usεr11852 nói Rebstate Monic

10

Tôi biết đây là một câu hỏi cũ, nhưng tôi sử dụng một phương pháp khác với những câu hỏi trên. Tôi sử dụng chức năng BayesianOptimization từ gói Tối ưu hóa Bayes để tìm các tham số tối ưu. Để thực hiện việc này, trước tiên, bạn tạo các nếp gấp xác thực chéo, sau đó tạo một hàm xgb.cv.bayescó tham số tăng các tham số bạn muốn thay đổi. Trong ví dụ này tôi đang điều chỉnh max.depth, min_child_weight, subsample, colsample_bytree, gamma. Sau đó, bạn gọi xgb.cvhàm đó với các tham số siêu được đặt thành trong các tham số đầu vào của xgb.cv.bayes. Sau đó, bạn gọi BayesianOptimizationvới xgb.cv.bayesvà các phạm vi mong muốn của các tham số siêu tăng. init_pointslà số lượng mô hình ban đầu với các tham số siêu được lấy ngẫu nhiên từ các phạm vi được chỉ định vàn_iterlà số vòng của các mô hình sau các điểm ban đầu. Hàm này xuất ra tất cả các tham số tăng cường và AUC thử nghiệm.

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
Đây là một cách tiếp cận tốt, nhưng có một cảnh báo : gói R rBayesianOptimization, kể từ phiên bản CRAN mới nhất 1.1.0 (chưa được cập nhật trong hơn 2 năm), không có thử nghiệm và giấy phép hạn chế hơn Python gói của các tác giả ban đầu của phương pháp, trong đó có các bài kiểm tra. Xem github.com/fmfn/BayesianOptimization .
egnha

8

Đây là một câu hỏi cũ hơn nhưng tôi nghĩ rằng tôi sẽ chia sẻ cách điều chỉnh các tham số xgboost. Ban đầu tôi nghĩ rằng tôi sẽ sử dụng dấu mũ cho việc này nhưng gần đây đã phát hiện ra một vấn đề xử lý tất cả các tham số cũng như các giá trị bị thiếu. Tôi cũng đã xem xét việc viết một vòng lặp thông qua các kết hợp tham số khác nhau nhưng muốn nó chạy song song và sẽ cần quá nhiều thời gian. Sử dụng GridSearch từ gói NMOF cung cấp tốt nhất từ ​​cả hai thế giới (tất cả các tham số cũng như xử lý song song). Dưới đây là mã ví dụ để phân loại nhị phân (hoạt động trên windows và 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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.