2

biglm を並列モードで実行することは可能ですか? doMC を使用してから foreach ループに biglm を埋め込もうとしましたが、すべてのコアが同じデータのチャンクを同時に処理しているようです。これを並列化するにはどうすればよいですか?

library(doMC)
RegisterDoMC(4)

require(ffbase)
sample <- read.table.ffdf(file="sample_output.csv", FUN = "read.csv", na.strings = "")  
library(biglm)
model<-list()
biglmupdate<-function(dataset,start,end) {
 if (start==1) {
    model <<- biglm(a~b+c, data=dataset[start:end,])
 }
 else {
    model <<- update(model,dataset[start:end,])
 }
}

chunks <- floor(dim(sample)[1]/220000)+1
start<-0; end<-0;
foreach (i = 1: chunks) %dopar% { 
    start = end +1; end =ifelse (i == chunks, dim(sample)[1], start+220000); 
    print(paste("chunk ",i," ",start,":",end," started at:", Sys.time()));
    biglmupdate(dataset = sample, start, end);
    print(paste("chunk ",i,"ended at:", Sys.time()));
}
4

1 に答える 1

0

私はbiglmパッケージにあまり詳しくありませんが、モデル オブジェクトへの一連の更新によって機能するため、簡単に並列実行できるようには見えません。この種のループは基本的にシーケンシャルです。たとえば、次のものは並列化できません。

i <- 0
for (i in 1:10) {
    i <- i + 1
}

10 の異なるプロセスをそれぞれ に追加する1ことによってi。ループは、 を順次更新することに依存していますi。私が見る限り、同じことがbiglm関数にも当てはまります。

この基本的な問題の他に、あなたのコードには他に 2 つの問題があります。 と の計算startend、ウェイmodelが変更されています。上記の例のように、ループが並列実行されている場合、前の繰り返しの値に基づいてループ変数の値を計算することはできません。この場合、ループを次のように変更することで修正できます。

n <- nrow(sample)
m <- 220000
foreach(start=seq(1,n,by=m), end=seq(m,n,by=m) %dopar% {
    # ...
}

startとの値endはすべて事前に計算されているため、ループを並列に実行しても問題はありません。これにより、すべてのコアが同じデータのチャンクで動作していたというコメントにつながった問題が解決されると思います。biglm残念ながら、これは並列実行の根本的な問題に対処していません。

問題は、並列プロセスから単一のグローバルのようなmodel変数を更新しようとしていることです。を使用する場合は、ループの各反復から値を返し、それらを関数で処理するという観点から考える必要があります。本体でループ外の変数を変更すると、ほとんどの場合失敗します。foreach.combine

于 2013-05-17T11:56:34.250 に答える