0

私は R の新入生です。R で randomForest を実行したいのですが、データは 1000 行 28 列です。アイデアは、すべての mtry (1:27) をテストすることであり、それらのそれぞれは、10 倍の CV を 10 回繰り返すことによってテストされます。問題は、非常に長い時間がかかり、それでも結果が得られないことです! 「for」の代わりに「foreach」ループを使用しようとしていますが、その方法がわかりません。コードを以下に示します。

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)

助けてください、どうもありがとう!

4

2 に答える 2

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
  • 外側の 2 つのループを並列処理していますが、クラスターにアクセスできる場合は、さらに先に進むことができます。ここには多くの並列性があります。
  • これは、高度な機能であるネストされた foreach ループを使用しますが、この種の問題には非常に役立ちます。
  • Xa2代わりに、ループがループの反復間で変数を更新できないことa2を強調するために使用しました。私のバージョンがあなたが望んでいることをするかどうかわからないので、それについて考える必要があります.foreacha2
  • .combine関数は少しトリッキーですが、2 つの結果を生成するために必要です。どちらも一種の転置を実行します。
  • randomForestより多くのメモリを使用し、遅くなる可能性があるため、数式インターフェイスを避ける必要があります。
  • あなたの使用はset.seedテストのためだけだと思います。
于 2013-05-28T15:56:22.853 に答える
0

dataが定義されていないため、例を実行できません。しかし、おそらく最小限のforeach-example が役立つかもしれません:

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

forとfor の 2 つのforeachループを実行する必要があると思います。trainrftestrf

于 2013-05-28T11:02:46.570 に答える