我正在尝试训练几个随机森林(进行回归)以使其竞争,并查看哪些特征选择和哪些参数可以提供最佳模型。

但是,培训似乎要耗费大量时间,而且我想知道自己是否做错了什么。

我用于训练的数据集(以下称为train)具有217k行和58列(其中只有21列用作随机森林中的预测变量。它们都是numericinteger,但例外一个布尔值类型(类型为charactery输出为numeric)。

我运行了以下代码四次,将值41005002000赋予nb_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


这是他们每个人花了多长时间训练:

nb_trees | time
4          4mn
100        1h 41mn
500        8h 40mn
2000       34h 26mn


由于我公司的服务器具有12个核心和125Go的RAM,我认为我可以尝试按照this answer并行进行培训(但是,我使用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)


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

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


但是,我认为仍然需要很多时间,不是吗?我知道将树木合并到最终森林中需要时间,所以我没想到12核的速度会快12倍,但是速度只快2倍左右...


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


感谢您的回答。

注意事项:


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

最佳答案

虽然我喜欢蛮力技术,例如并行化或运行代码很长时间,但我还是更喜欢改进算法以避免使用蛮力技术。

虽然使用2000棵树来训练您的随机森林开始变得令人难以置信的昂贵,但是使用较少数量的树进行训练花费了更合理的时间。对于初学者,您可以训练诸如481632...256512的树,并仔细观察度量标准,以使您知道模型的健壮性。这些指标包括最佳常数模型(森林在数据集上的表现与预测所有输入的中位数的模型)之类的东西,以及袋外误差。此外,您可以观察到最重要的预测变量及其重要性,以及在添加更多树时是否开始看到收敛。

理想情况下,您不必使用数千棵树来构建模型。一旦模型开始收敛,添加更多的树并不一定会使模型恶化,但同时也不会添加任何新信息。通过避免使用过多的树木,您可能可以减少一周左右到不到一天的计算时间。如果最重要的是,您利用了12个CPU内核,那么您可能要花几个小时的时间。

要在每次随机森林运行后查看变量的重要性,可以尝试以下方法:

fit <- randomForest(...)
round(importance(fit), 2)


据我了解,第一个说5-10个预测变量对模型的影响最大。如果您注意到通过增加树木,这些顶级预测变量实际上并没有真正改变彼此的位置,并且重要性指标似乎保持不变,那么您可能要考虑不使用那么多树木。

10-04 14:16