我是R的新生。我想在R中执行randomForest,数据有1000行和28列。我们的想法是测试所有mtry(1:27),每个mtry将通过10次重复10次CV测试。问题是需要这么长时间而且仍然没有结果!我尝试使用'foreach'循环而不是'for',但我不知道该怎么做。代码如下所示:
library(randomForest)
n <- nrow(data)
a1 <- 1:n
a2 <- rep(1:10,ceiling(n/10))[1:n]
k <- ncol(data)-1
trainrf <- testrf <- list()
for(i in 1:k){ # tune mtry from 1 to 27
rftrain <- rftest <- NULL
for(x in 1:10){ # 10 repeats 10-fold CV
set.seed(1981)
a2 <- sample(a2,n)
train.rf <- test.rf <- rep(0,10)
for(j in 1:10){
m <- a1[a2 == j]
n1 <- n-length(m)
n2 <- length(m)
set.seed(2013)
rf.data <- randomForest(level~., data=data[-m,], mtry=i, ntree=1000)
train.rf[j] <- sum(data[-m,28] == predict(rf.data, data[-m,]))/n1
test.rf[j] <- sum(data[m,28] == predict(rf.data, data[m,]))/n2
}
rftrain[x] <- mean(train.rf); rftest[x] <- mean(test.rf)
}
trainrf[[i]] <- rftrain; testrf[[i]] <- rftest
}
我的笔记本电脑是i7 Windows 7 64位,据我所知,我写了几个代码:
library(foreach)
library(doParallel)
cl <- makeCluster(4)
registerDoParallel(cl)
请帮助我,非常感谢!
答案 0 :(得分:2)
你可能应该阅读一些foreach
小插曲,因为虽然这是foreach
的相当简单的使用,但它并非无足轻重,就像许多例子一样。
这是我尝试将您的脚本翻译为foreach
,虽然我无法测试它,因为您的示例无法重现:
library(doParallel)
cl <- makeCluster(4)
registerDoParallel(cl)
n <- nrow(data)
a1 <- 1:n
a2 <- rep(1:10,ceiling(n/10))[1:n]
k <- ncol(data)-1
outercomb <- function(...) {
lapply(1:2, function(i) lapply(list(...), function(p) p[[i]]))
}
innercomb <- function(...) {
lapply(1:2, function(i) sapply(list(...), function(p) p[[i]]))
}
r <- foreach(i=1:k, .combine='outercomb', .multicombine=TRUE,
.packages='randomForest') %:%
foreach(1:10, .combine='innercomb', .multicombine=TRUE) %dopar% {
set.seed(1981)
Xa2 <- sample(a2, n)
train.rf <- double(10)
test.rf <- double(10)
for(j in 1:10){
m <- a1[Xa2 == j]
n1 <- n-length(m)
n2 <- length(m)
set.seed(2013)
rf.data <- randomForest(level~., data=data[-m,], mtry=i, ntree=1000)
train.rf[j] <- sum(data[-m,28] == predict(rf.data, data[-m,]))/n1
test.rf[j] <- sum(data[m,28] == predict(rf.data, data[m,]))/n2
}
c(mean(train.rf), mean(test.rf))
}
trainrf <- r[[1]]
testrf <- r[[2]]
以下是一些评论:
caret
包。我认为它可以很容易地为你做这种事情,它使用foreach
并行完成。Xa2
代替a2
来强调foreach
循环无法跨循环迭代更新变量a2
。我不确定我的版本是否符合您的要求,因此您必须考虑这一点。.combine
函数有点棘手,但需要产生两个结果。他们都进行各种转置。randomForest
的公式接口,因为它使用更多内存并且可能很慢。set.seed
仅用于测试。答案 1 :(得分:0)
我无法执行您的示例,因为未定义data
。但也许最小foreach
- 示例可能会有所帮助:
library(foreach)
library(doParallel)
cl <- makeCluster(4)
registerDoParallel(cl)
testList <- foreach(i=1:5) %dopar% {
1:i
}
i=1:5
每次投放的结果会合并到一个列表中并保存在变量testList
中:
> testList
[[1]]
[1] 1
[[2]]
[1] 1 2
[[3]]
[1] 1 2 3
[[4]]
[1] 1 2 3 4
[[5]]
[1] 1 2 3 4 5
您可以使用以下方法指定另一种合并方法:
> testList <- foreach(i=1:5, .combine="c") %dopar% {
+ 1:i
+ }
>
> testList
[1] 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5
我认为你必须做两个foreach
循环,一个用于trainrf
,一个用于testrf