r - 在 R 中更快地获得随机森林回归

标签 r regression random-forest

我必须在 R 中使用 randomforest 进行回归。我的问题是我的数据框很大:我有 12 个变量和超过 400k 的条目。当我尝试(代码写在底部)以获得随机森林回归时,系统需要花费很多小时来处理数据:经过 5、6 小时的计算,我不得不停止操作而没有任何输出。有人可以建议我如何才能更快地获得它? 谢谢

library(caret)
library(randomForest)

dataset <- read.csv("/home/anonimo/Modelli/total_merge.csv", header=TRUE)
dati <- data.frame(dataset)
attach(dati)


trainSet <- dati[2:107570,]
testSet <- dati[107570:480343,]

output.forest <- randomForest(dati$Clip_pm25 ~ dati$e_1 + dati$Clipped_so + dati$Clip_no2 + dati$t2m_1 + dati$tp_1 + dati$Clipped_nh  +  dati$Clipped_co + dati$Clipped_o3 + dati$ssrd_1 + dati$Clipped_no + dati$Clip_pm10 + dati$sp_1, data=trainSet, ntree=250)

最佳答案

我不认为在单台 PC(2-4 核)上并行化是答案。有很多唾手可得的果实可供采摘。

1) RF 模型的复杂性随着训练样本数量的增加而增加。平均树深度类似于 log(480,000/5)/log(2) = 16.5 个中间节点。在绝大多数示例中,每棵树 2000-10000 个样本就可以了。如果你想在 Kaggle 上获胜,一点点额外的表现真的很重要,因为胜者为王。实际上,您可能不需要它。

2) 不要在 R 代码中克隆数据集,并尝试只保留数据集的一份副本(通过引用传递当然没问题)。对于这个数据集来说这不是一个大问题,因为即使对于 R 来说,数据集也不是那么大(~38Mb)。

3) 对于大型数据集,不要使用带有 randomForest 算法的公式接口(interface)。它将制作数据集的额外副本。不过,内存并不是什么大问题。

4) 使用更快的 RF 算法:extraTreesrangerRborist 可用于 R。extraTrees不完全是 RF 算法,但非常接近。

5) 避免使用超过 10 个类别的分类特征。 RF 最多可以处理 32 个,但会变得 super 慢,因为必须评估任何 2^32 可能的分割。 extraTreesRborist 通过仅测试一些随机选择的分割来处理更多类别(效果很好)。另一个解决方案是 python-sklearn 中的每个类别都被分配一个唯一的整数,并且该特征被处理为数字。您可以使用 as.numeric 转换您的分类特征,然后运行 ​​randomForest 来执行相同的操作。

6) 对于更大的数据。将数据集拆分为随机 block ,并在每个 block 上训练一些(~10)棵树。合并森林或单独保存森林。这将稍微增加树的相关性。有一些很好的集群实现可以像这样进行训练。但对于低于 1-100Gb 的数据集则不需要,具体取决于树的复杂性等。

#下面我使用解决方案 1-3) 并获得了几分钟的运行时间

library(randomForest)
#simulate data 
dataset <- data.frame(replicate(12,rnorm(400000)))
dataset$Clip_pm25 = dataset[,1]+dataset[,2]^2+dataset[,4]*dataset[,3]
#dati <- data.frame(dataset) #no need to keep the data set, an extra time in memory
#attach(dati) #if you attach dati you don't need to write data$Clip_pm25, just Clip_pm25
#but avoid formula interface for randomForest for large data sets because it cost extra memory and time 

#split data in X and y manually
y = dataset$Clip_pm25
X = dataset[,names(dataset) != "Clip_pm25"]
rm(dataset);gc()

object.size(X) #38Mb, no problemo

#if you were using formula interface
#output.forest <- randomForest(dati$Clip_pm25 ~ dati$e_1 + dati$Clipped_so + dati$Clip_no2 + dati$t2m_1 + dati$tp_1 + dati$Clipped_nh  +  dati$Clipped_co + dati$Clipped_o3 + dati$ssrd_1 + dati$Clipped_no + dati$Clip_pm10 + dati$sp_1, data=trainSet, ntree=250)
#output.forest <- randomForest(dati$Clip_pm25 ~ ., ntree=250) # use dot to indicate all variables

#start small, and scale up slowly
rf = randomForest(X,y,sampsize=1000,ntree=5) #runtime ~15 seconds
print(rf) #~67% explained var

#you probably really don't need to exeed 5000-10000 samples per tree, you could grow 2000 trees to sample most of training set
rf = randomForest(X,y,sampsize=5000,ntree=500) # runtime ~5 minutes
print(rf) #~87% explained var


#regarding parallel
#here you could implement some parallel looping
#.... but is it really worth for a 2-4 x speedup?
#coding parallel on single PC is fun but rarely worth the effort

#If you work at some company or university with a descent computer cluster,
#then you can spawn the process across 20-80-200 nodes and get a ~10-60-150 x speedup
#I can recommend the BatchJobs package

关于r - 在 R 中更快地获得随机森林回归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34706654/

相关文章:

r - 不创建 SpatialGridDataFrame 对象的函数

R 使用逻辑索引从数据帧中选择行: accessing columns by `$` vs `[]`

python - 如何使用 statsmodels python 进行 2SLS IV 回归?

python - 在 python 中每次运行随机森林、非线性 SVC 和多项式 NB 时获得不同的准确度以进行文本分类

python - 使用特征名称绘制特征重要性

Selenium 问题

r - 计算两个子组之间的统计检验的 ggplot2/plyr 方法是什么?

python - scikit-learn 中的多输出高斯过程回归

hadoop - 在Mahout中使用Logistic回归

r - 对于 R 中的随机森林模型,predict() 函数和 model$predicted 有什么区别?