首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在R中求randomForest回归的速度

在R中求randomForest回归的速度
EN

Stack Overflow用户
提问于 2016-01-10 14:40:48
回答 3查看 7.7K关注 0票数 5

我必须在R中用随机森林进行回归,我的问题是我的数据是巨大的:我有12个变量和400多个条目。当我尝试-代码写在底部-得到一个randomForest回归,系统需要许多小时来处理数据:经过5,6个小时的计算,我有义务停止操作,没有任何输出。有人能建议我怎样才能更快地得到它吗?谢谢

代码语言:javascript
复制
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)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-01-10 15:17:55

由于您使用的是插入符号,所以可以使用方法= "parRF“。这是并行随机森林的一个实现。

例如:

代码语言:javascript
复制
library(caret)
library(randomForest)
library(doParallel)

cores <- 3
cl <- makePSOCKcluster(cores)
registerDoParallel(cl)

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,]

# 3 times cross validation.
my_control <- trainControl(method = "cv", number = 3 )

my_forest <- train(Clip_pm25 ~ e_1 + Clipped_so + Clip_no2 + t2m_1 + tp_1 + Clipped_nh  +  Clipped_co + Clipped_o3 + ssrd_1 + Clipped_no + Clip_pm10 + sp_1, , 
                   data = trainSet,
                   method = "parRF",
                   ntree = 250,
                   trControl=my_control)

这里还有一个foreach实现:

代码语言:javascript
复制
foreach_forest <- foreach(ntree=rep(250, cores), 
                          .combine=combine, 
                          .multicombine=TRUE, 
                          .packages="randomForest") %dopar%
   randomForest(Clip_pm25 ~ e_1 + Clipped_so + Clip_no2 + t2m_1 + tp_1 + Clipped_nh  +  Clipped_co + Clipped_o3 + ssrd_1 + Clipped_no + Clip_pm10 + sp_1, 
                   data = trainSet, ntree=ntree)

# don't forget to stop the cluster
stopCluster(cl)

别忘了我没有种任何种子。你也应该考虑一下。下面是一个随机森林包的链接,它也并行运行。但我还没试过这个。

票数 3
EN

Stack Overflow用户

发布于 2016-01-11 11:57:17

我不认为在一台PC (2-4核)上并行是答案。有足够的低挂水果可采摘。

1)射频模型的复杂度随训练样本数的增加而增加。平均树深度将类似于log(480,000/5)/log(2) = 16.5中间节点。在绝大多数例子中,每棵树有2000到10000个样本是很好的。如果你想在kaggle上获胜,一个小小的额外表现真的很重要,因为胜利者占据了一切。实际上,你可能不需要这个。

2)不要在R代码中克隆数据集,只保留数据集的一个副本(引用传递当然可以)。对于这个数据集来说,这不是一个大问题,因为数据集并不是那么大(~38 as ),甚至对于R。

3)对于大型数据集,不要使用公式接口和randomForest算法。它将额外复制数据集。但同样,记忆也没有那么大的问题。

4)使用更快的RF算法:extraTreesrangerRborist都适用于R. extraTrees不是一个确切的RF算法,而是非常接近的。

5)避免10类以上的分类特征。射频可以处理多达32,但变得超级慢,因为任何2^32可能的分裂必须评估。extraTreesRborist只通过测试一些随机选择的分片来处理更多的类别(这很好)。另一种解决方案,如在python-sklearn中,每个类别都分配了一个唯一的整数,该特性被作为数字处理。您可以使用as.numeric转换分类特性,在运行randomForest之前也可以这样做。

6)大得多的数据。用随机块分割数据集,在每个块上训练几棵(~10)树。合并森林或单独保护森林。这将略微增加树的相关性。有一些不错的集群实现可以像这样进行培训。但是对于1-100 on以下的数据集来说,这并不是必需的,这取决于树的复杂性等等。

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

代码语言:javascript
复制
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
票数 13
EN

Stack Overflow用户

发布于 2021-01-07 22:52:47

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

我建议你看看这三个:

游侠(使用C++编译器) randomForestSRC (使用C++编译器) h2o (Java编译器-需要Java 8或更高版本)还有一些额外的阅读,让您可以选择更多的软件包:https://arxiv.org/pdf/1508.04409.pdf

第8页展示了一些基准,显示相对于增长的数据大小,游标者相对于randomForest的性能改善要快得多,这是因为运行时的线性增长,而不是对于randomForest来说,对于树/样本/拆分/特征大小的上升而言是非线性的。

祝好运!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34706654

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档