如何提高randomForest性能?

时间:2014-04-15 05:43:44

标签: r performance random-forest

我有一个大小为38 MB的训练集(12个属性,420000行)。我正在运行以下R代码段,以使用randomForest训练模型。这对我来说需要几个小时。

rf.model <- randomForest(
              Weekly_Sales~.,
              data=newdata,
              keep.forest=TRUE,
              importance=TRUE,
              ntree=200,
              do.trace=TRUE,
              na.action=na.roughfix
            )

我认为,由于na.roughfix,执行需要很长时间。训练集中有NA's个{。}}。

有人可以告诉我如何改善表现吗?

我的系统配置是:

Intel(R) Core i7 CPU @ 2.90 GHz
RAM - 8 GB
HDD - 500 GB
64 bit OS

4 个答案:

答案 0 :(得分:51)

(tl; dr是你应该a)将nodesize增加到&gt;&gt; 1)和b)排除非常低重要性的特征列,甚至可以排除(比如说)80%的列。您的问题几乎肯定不是na.roughfix,但如果您怀疑,请在调用na.roughfix之前单独运行randomForest作为独立步骤。首先让红鲱鱼脱离。)

现在,以下所有建议仅适用于您超出内存限制,因此请测量内存使用情况,并确保不超过。 (从可笑的小参数开始,然后将它们放大,测量运行时间,并继续检查它不会不成比例地增加。)

影响randomForest性能的主要参数是:

  • mtry (越少越快)
  • ntrees
  • 功能数量 / cols数据 - 更多是二次方更慢或更糟!见下文
  • 数据中的观察/行数
  • ncores(更多更快 - 只要使用并行选项)
  • 通过设置重要性= F和接近度= F(不计算邻近矩阵)来提升性能
  • 永远不要使用疯狂的默认nodesize=1 进行分类!在Breiman的软件包中,您无法直接设置maxdepth,但可以使用nodesize作为代理,并在以下网址阅读所有好建议:CrossValidated: "Practical questions on tuning Random Forests"
  • 所以这里您的数据有4.2e + 5行,如果每个节点不应小于~0.01%,请尝试nodesize=42。 (首先尝试nodesize = 4200(1%),查看它的速度,然后重新运行,调整节点大小。根据经验确定此数据集的良好节点大小。)
  • 运行时与~2 ^ D_max成正比,即多项式为(-log1p(nodesize))
  • 您也可以使用抽样来加速,请参阅strata,sampsize参数

然后是运行时的一阶估计,表示mtry = M,ntrees = T,ncores = C,nfeatures = F,nrows = R,maxdepth = D_max,是:

Runtime proportional to: T * F^2 * (R^1.something) * 2^D_max / C

(同样,如果超过内存,所有投注都会关闭。另外,尝试只运行一个核心,然后运行2,然后运行4并验证您实际上是否获得线性加速。而不是减速。) (大R的影响比线性更差,可能是二次的,因为树分区必须考虑数据行的所有分区;当然它比线性稍差。通过使用采样或索引来检查它只给它说10%的行。)

提示:保持大量垃圾低重要性功能可以平方增加运行时间,从而提高精度的次线性增加。这是因为在每个节点,我们必须考虑所有可能的特征选择(或任何数字mtry)允许。在每棵树中,我们必须考虑所有(F-choose-mtry)可能的特征组合。 所以,这是我的方法,做&#34;快速和肮脏的功能选择性能&#34;:

  1. 生成一棵树(慢),虽然使用了一个nodesize=42或更大的
  2. 查看rf $ importances或randomForest::varImpPlot()。只选择前K个功能,选择K;对于一个愚蠢的例子,选择K = 3。保存整个列表以供将来参考。
  3. 现在重新运行树,但只给它newdata[,importantCols]
  4. 确认速度是二次方的更快,并且oob.error并不是更糟糕
  5. 一旦您知道变量的重要性,就可以关闭importance=F
  6. 调整mtry和nodesize(一次调整一个),重新运行并测量速度提升
  7. 在对数轴上绘制性能结果
  8. 把结果发给我们!你证实了上述情况吗?有关内存使用的任何意见吗?
  9. (请注意,以上不是实际特征选择的统计有效程序,不依赖于此,请阅读randomForest包以获取基于RF的特征选择的实际正确方法。)

答案 1 :(得分:1)

我怀疑do.trace也可能消耗时间...而不是do.trace = TRUE,你可以使用do.trace = 5(只显示5条痕迹)只是为了让你有一些错误的感觉。对于大型数据集,do.trace也会花费很多时间。

答案 2 :(得分:1)

另一种选择是实际使用专为高维/大容量数据集构建的更新包。他们使用低级语言(C++ 和/或 Java)运行代码,并且在某些情况下使用并行化。

我建议看看这三个:

游侠(使用 C++ 编译器) randomForestSRC(使用 C++ 编译器) h2o(Java 编译器 - 需要 Java 8 或更高版本) 此外,这里还有一些额外的阅读内容,可以让您更多地了解选择哪个套餐:https://arxiv.org/pdf/1508.04409.pdf

第 8 页显示的基准测试显示了 Ranger 与 randomForest 在不断增长的数据大小下的性能改进 - 由于运行时的线性增长,而不是 randomForest 的非线性增长,ranger 的速度更快,因为树/样本/分割/特征大小不断增长。

>

祝你好运!

答案 3 :(得分:0)

另一个我认为我注意到的东西:
正确的是ntrees,而不是ntree
500软件包的默认值为randomForest