为什么在使用 trainControl 时在插入符中使用 "xgbTree" 这么慢?

Why is using "xgbTree" in caret so slow with trainControl?

我正在尝试将 xgboost 模型拟合到多类预测问题上,并想使用 caret 进行超参数搜索。 为了测试这个包,我使用了下面的代码,当我没有为 trainControl

提供 train 对象时,它需要 20 秒
# just use one parameter combination
xgb_grid_1 <- expand.grid(
  nrounds = 1,
  eta = 0.3,
  max_depth = 5,
  gamma = 0,
  colsample_bytree=1, 
  min_child_weight=1
)
# train
xgb_train_1 = train(
  x = as.matrix(sparse_train),
  y = conversion_tbl$y_train_c ,
  trControl = trainControl(method="none", classProbs = TRUE, summaryFunction = multiClassSummary),
  metric="logLoss",
  tuneGrid = xgb_grid_1,
  method = "xgbTree"
)

但是,当我向 train 提供一个 trainControl 对象时,代码永远不会完成......或者花费很长时间(至少它完成了 15 分钟。

xgb_trcontrol_1 <- trainControl(
  method = "cv",
  number = 2,
  verboseIter = TRUE, 
  returnData = FALSE,
  returnResamp = "none",                                         
  classProbs = TRUE,                                           
  summaryFunction = multiClassSummary
)
xgb_train_1 = train(
  x = as.matrix(sparse_train),
  y = conversion_tbl$y_train_c ,
  trControl = xgb_trcontrol_1,
  metric="logLoss",
  tuneGrid = xgb_grid_1,
  method = "xgbTree"
)

这是为什么?

仅供参考,我的数据大小是

 dim(sparse_train)
[1] 702402     36

您的 trainControl 对象不同。

在第一个trainControl对象中,方法是method="none"。 在第二个trainControl对象中,方法是method="cv"number=2。所以,在第二个对象中,你是 运行 一个双重交叉验证,它需要比 运行 更长的交叉验证。

您可以尝试的另一件事是将 nthread = 1 添加到 caret::train() 调用中。

XGBoost 和 Caret 都尝试尽可能使用 parallel/multicore 处理,过去我发现这会(悄悄地)导致产生太多线程,从而限制您的机器。

告诉 caret 按顺序处理模型可以最大限度地减少问题,并且应该意味着只有 xgboost 会生成线程。