2017-12-08 5 views
0

私は並列処理を使用して、Rで多くのブーストされた回帰木を高速化しようとしています。私はBiocParallelパッケージ(http://lcolladotor.github.io/2016/03/07/BiocParallel/#.WiqF7bQ-e3c)を使用しています。いくつかのダミーデータを作成してから、2つのBRTモデルを実行する関数を設定しました。これはSerialで、次にParallelでの時間を期待していました。しかし、私の並列実行は約3秒かかりますが、私の並列実行は決して完了しないようです。BiocParallelがシリアルよりずっと長く実行されている並列処理

##CAN I USE PARALLEL PROCESSING TO SPEED UP BRT'S? 

##LOAD PACKAGES 
library(BiocParallel) 
library(dismo) 
library(gbm) 
library(MASS) 

##CREATE RANDOM, CORRELATED DATA 
## FROM https://www.r-bloggers.com/simulating-random-multivariate-correlated-data-continuous-variables/ 
R = matrix(cbind(1,.80,.2, .80,1,.7, .2,.7,1),nrow=3) 
U = t(chol(R)) 
nvars = dim(U)[1] 
numobs = 100 
set.seed(1) 
random.normal = matrix(rnorm(nvars*numobs,0,1), nrow=nvars, ncol=numobs); 
X = U %*% random.normal 
newX = t(X) 
raw = as.data.frame(newX) 
orig.raw = as.data.frame(t(random.normal)) 
names(raw) = c("response","predictor1","predictor2") 
cor(raw) 


########################################################### 
## MODEL 
########################################################## 


##WITH FUNCTIONS, 

Tc<-c(4, 8) ##Tree Complexities 

Lr<-c(0.01) ## Learning Rates 

Vars <- split(expand.grid(Tc,Lr),seq(nrow(expand.grid(Tc,Lr)))) 

brt <- function(x){ 
    a <- gbm.step(raw,gbm.x=c(2:3),gbm.y="response",tree.complexity=x[1],learning.rate=x[2],bag.fraction=0.65, family="gaussian") 
    b <- data.frame(model=paste("Tc= ",x[1]," _ ","Lr= ",x[2],sep=""), R2=a$cv.statistics$correlation.mean, Dev=a$cv.statistics$deviance.mean) 
    ##Reassign model with unique name 
    assign(paste("patch.tc",x[1],".lr",x[2],sep=""),a, envir = .GlobalEnv) 
    assign(paste("RESULTS","patch.tc",x[1],".lr",x[2],sep=""),b, envir = .GlobalEnv) 
    print(b) 
} 



############################ 
###IN Serial 
############################ 

system.time(
lapply(Vars, brt) 
) 


############################ 
###IN PARALLEL 
############################ 

system.time(
bplapply(Vars, brt) 
) 

答えて

2

いくつかの簡単なコメント:

  1. 必ずassign()を避けます。あなたがそれを使用していると分かっている場合は、間違った方法で問題に近づいているという良い兆候です。

  2. 関数内で変数をグローバル環境に割り当てる(assign()または<<-を使用する)ことは常に悪い考えであり、使用するべきよりよい解決策があることを示唆しています。

  3. 上記の1と2を打破することを選択した場合は、並列処理を使用すると確かにではなくが動作します。

  4. 代わりに返信あなたの値(下記参照)。

  5. そのdismo::gbm.step()は、デフォルトでプロットしようとします(plot.main = TRUE)。これは、いわゆるforkされた並列処理ではうまく動作しません(実際は無効です)。これは、しばしばUnixやmacOSのデフォルトの動作です。

  6. 画像ファイルなどをプロットしない限り、並行してプロットすることは、しばしばやりたいことではありません。あなたの問題へ

:へのごbrt()を変更した後(1-6による)は:

brt <- function(x){ 
    a <- gbm.step(raw, gbm.x=c(2:3), gbm.y="response", tree.complexity=x[1], learning.rate=x[2], bag.fraction=0.65, family="gaussian", plot.main = FALSE) 
    b <- data.frame(model=paste("Tc= ", x[1], " _ ", "Lr= ", x[2], sep=""), R2=a$cv.statistics$correlation.mean, Dev=a$cv.statistics$deviance.mean) 
    list(a = a, b = b) 
} 

それは私bplapply(Vars, brt)のためだけでなく、future::future_lapply(Vars, brt)で動作します。 parallel::parLapply(cl, Vars, brt)では、グローバルのエクスポートにもっと注意を払う必要があります。

PS。私はおそらくちょうどaを返し、b情報を外部に抽出するでしょう。

+0

これを説明する時間をいただきありがとうございます。 #5は間違いなくエラーを解決します。私はあなたのコードでリターンが表示されません? – ctlamb

関連する問題