使用 xgboost 和 caret 进行并行处理

Posted

技术标签:

【中文标题】使用 xgboost 和 caret 进行并行处理【英文标题】:Parallel processing with xgboost and caret 【发布时间】:2017-01-24 12:00:07 【问题描述】:

我想在使用插入符号时并行化 xgboost 的模型拟合过程。从我在 xgboost 的documentation 中看到的情况来看,nthread 参数控制在拟合模型时要使用的线程数,即以并行方式构建树。 Caret 的train 函数将执行并行化,例如,在 k 折 CV 中为每次迭代运行一个进程。这种理解是否正确,如果是,是否更好:

    注册内核数量(例如,使用doMC 包和registerDoMC 函数),通过插入符号的train 函数设置nthread=1,以便它将该参数传递给xgboost,在trainControl 中设置allowParallel=TRUE , 并让caret 处理交叉验证的并行化;或 禁用插入符号并行化(allowParallel=FALSE 并且没有并行后端注册)并将nthread 设置为物理内核数,因此并行化仅包含在 xgboost 中。

或者没有“更好”的方法来执行并行化?编辑:我运行了@topepo 建议的代码,使用tuneLength = 10search="random",并且在最后一行指定nthread=1(否则我知道xgboost 将使用多线程)。有我得到的结果:

xgb_par[3]
elapsed  
283.691 
just_seq[3]
elapsed 
276.704 
mc_par[3]
elapsed 
89.074 
just_seq[3]/mc_par[3]
elapsed 
3.106451 
just_seq[3]/xgb_par[3]
elapsed 
0.9753711 
xgb_par[3]/mc_par[3]
elapsed 
3.184891

最后,事实证明,对于我的数据和这个测试用例,让插入符号处理并行化在运行时方面是更好的选择。

【问题讨论】:

避免交叉验证不是“模型拟合”的事实,没有理由这些选项必须相互排斥。无论如何,这个问题是基于意见的,我投票结束。您还没有定义“更好”;但是,我假设你的意思是更少的运行时间......你总是可以分析你的代码。我建议library(microbenchmark) 可能在术语上存在误解。当然,交叉验证的最终目标是模型验证,但我所说的“模型拟合”是指在​​每次迭代中,您确实必须在 (k-1) 次折叠上拟合模型。这个问题的原因是我不知道通过构造是否存在理论上更好的并行化方法(例如,每次迭代产生更多线程可能比并行化重采样循环有更多开销),并且想知道是否有人更有经验的可以对此提出建议。但确实这可能取决于具体情况。 【参考方案1】:

预测最佳策略是什么并不容易。我的(有偏见的)想法是你应该并行化耗时最长的过程。在这里,这将是重采样循环,因为打开的线程/工作者会多次调用模型。并行化模型拟合的相反方法将反复启动和停止工作人员,理论上会减慢速度。你的旅费可能会改变。

我没有安装 OpenMP,但下面有代码可以测试(如果你能报告你的结果,那会很有帮助)。

library(caret)
library(plyr)
library(xgboost)
library(doMC)

foo <- function(...) 
  set.seed(2)
  mod <- train(Class ~ ., data = dat, 
               method = "xgbTree", tuneLength = 50,
               ..., trControl = trainControl(search = "random"))
  invisible(mod)


set.seed(1)
dat <- twoClassSim(1000)

just_seq <- system.time(foo())


## I don't have OpenMP installed
xgb_par <- system.time(foo(nthread = 5))

registerDoMC(cores=5)
mc_par <- system.time(foo())

我的结果(没有 OpenMP)

> just_seq[3]
elapsed 
326.422 
> xgb_par[3]
elapsed 
319.862 
> mc_par[3]
elapsed 
102.329 
> 
> ## Speedups
> xgb_par[3]/mc_par[3]
elapsed 
3.12582 
> just_seq[3]/mc_par[3]
 elapsed 
3.189927 
> just_seq[3]/xgb_par[3]
 elapsed 
1.020509 

【讨论】:

以上是关于使用 xgboost 和 caret 进行并行处理的主要内容,如果未能解决你的问题,请参考以下文章

R语言使用caret包构建xgboost模型(xgbTree算法)构建回归模型通过method参数指定算法名称通过trainControl函数控制训练过程

R语言使用caret包构建xgboost模型(xgbDART算法使用的dropout思想)构建回归模型通过method参数指定算法名称通过trainControl函数控制训练过程

R语言caret包构建xgboost模型实战:特征工程(连续数据离散化因子化无用特征删除)配置模型参数(随机超参数寻优10折交叉验证)并训练模型

xgboost需不需要特征挑选

干货|长文详解自然语言处理算法xgboost和python实战

GBDT为什么不能并行,XGBoost却可以