如何加快随机森林的训练?

Fra*_* M. 11 parallel-processing r random-forest parallel-foreach doparallel

我正在尝试训练几个随机森林(用于回归)让他们竞争,看看哪个特征选择和哪个参数给出最佳模型.

然而,训练似乎花了很多时间,我想知道我做错了什么.

我用于训练的数据集(train下面称为)有217k行和58列(其中只有21列作为随机森林中的预测变量.它们都是numeric或者integer,除了布尔值,它是类的charactery输出是numeric).

我跑到下面的代码四次,给值4,100,500,2000nb_trees:

library("randomForest")
nb_trees <- #this changes with each test, see above
ptm <- proc.time()
fit <- randomForest(y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 
    + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 
    + x20 + x21, 
    data = train, 
    ntree = nb_trees, 
    do.trace=TRUE)
proc.time() - ptm
Run Code Online (Sandbox Code Playgroud)

以下是他们每个人训练的时间:

nb_trees | time
4          4mn
100        1h 41mn
500        8h 40mn
2000       34h 26mn
Run Code Online (Sandbox Code Playgroud)

由于我公司的服务器有12个核心和125G的RAM,我想我可以尝试并行化训练,遵循这个答案(但是,我使用了doParallel包,因为它似乎永远在运行doSNOW,我不知道为什么.而我我找不到的地方doParallel也会有用,对不起).

library("randomForest")
library("foreach")
library("doParallel")
nb_trees <- #this changes with each test, see table below
nb_cores <- #this changes with each test, see table below
cl <- makeCluster(nb_cores)
registerDoParallel(cl)
ptm <- proc.time()
fit <- foreach(ntree = rep(nb_trees, nb_cores), .combine = combine, .packages = "randomForest") 
    %dopar% {
        randomForest(y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 
        + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 
        + x20 + x21,
        data = train, 
        ntree = ntree,
        do.trace=TRUE)}
proc.time() - ptm
stopCluster(cl)
Run Code Online (Sandbox Code Playgroud)

当我运行它时,它比非并行化代码花费的时间更短:

nb_trees | nb_cores | total number of trees              | time
1          4          4                                    2mn13s
10         10         100                                  52mn
9          12         108 (closest to 100 with 12 cores)   59mn
42         12         504 (closest to 500 with 12 cores)   I won't be running this one
167        12         2004 (closest to 2000 with 12 cores) I'll run it next week-end
Run Code Online (Sandbox Code Playgroud)

但是,我认为它仍然需要花费很多时间,不是吗?我知道将树木组合到最终的森林需要时间,所以我没想到12个核心的速度要快12倍,但它只快2倍......

  • 这是正常的吗?
  • 如果不是,我可以用我的数据和/或我的代码做些什么来从根本上减少运行时间?
  • 如果没有,我应该告诉负责服务器的人它应该快得多吗?

谢谢你的回答.

备注:

  • 我是唯一使用此服务器的人
  • 对于我的下一个测试,我将摆脱随机森林中未使用的列
  • 我意识到我可以通过调用randomForest(predictors,decision)来改善运行时间而不是randomForest(decision~.,data=input),从现在开始我将会这样做,但我认为上面的问题仍然存在.

Tim*_*sen 8

虽然我是蛮力技术的粉丝,例如并行化或运行代码很长一段时间,但我更喜欢改进算法以避免使用暴力技术.

虽然使用2000棵树训练你的随机森林开始变得非常昂贵,但用较少数量的树木进行训练需要更合理的时间.对于初学者来说,你可以说训练4,8,16,32,...,256,512树木,仔细观察指标这让你知道该模型是如何健壮.这些指标包括最佳常量模型(森林在数据集上的表现与预测所有输入的中位数的模型相比),以及包外错误.此外,您可以观察顶部预测变量及其重要性,以及在添加更多树时是否开始看到会聚.

理想情况下,您不必使用数千棵树来构建模型.一旦您的模型开始收敛,添加更多树不一定会使模型恶化,但同时它不会添加任何新信息.通过避免使用太多树木,您可以减少计算,该计算可能需要一周到不到一天.如果最重要的是,你利用了十几个CPU核心,那么你可能会看到几个小时的东西.

要在每个随机林运行后查看变量重要性,您可以尝试以下方面的内容:

fit <- randomForest(...)
round(importance(fit), 2)
Run Code Online (Sandbox Code Playgroud)

据我所知,首先说5-10个预测器对模型影响最大.如果您注意到通过增加树,这些顶级预测变量并不真正改变相对于彼此的位置,并且重要性度量似乎保持不变,那么您可能想要考虑不使用这么多树.


use*_*924 5

randomForest()函数可以使用“公式接口”或“矩阵接口”接受数据。已知矩阵接口可提供更好的性能指标。

公式界面:

rf.formula = randomForest(Species ~ ., data = iris)
Run Code Online (Sandbox Code Playgroud)

矩阵界面:

rf.matrix = randomForest(y = iris[, 5], x = iris[, 1:4])
Run Code Online (Sandbox Code Playgroud)