2017-12-08 14 views
0

R에서 부스트 된 회귀 트리를 빠르게 실행하기 위해 병렬 처리를 사용하려고합니다. BiocParallel 패키지 (http://lcolladotor.github.io/2016/03/07/BiocParallel/#.WiqF7bQ-e3c)를 사용하고 있습니다. 몇 가지 더미 데이터를 만든 다음 두 개의 BRT 모델을 실행하는 기능을 설정했습니다. 직렬 모델에서 병렬로 작업하기를 바랬습니다. 그러나 내 병렬 실행은 완료되는 것처럼 보이지 않지만 직렬 실행은 약 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) 플롯을 시도합니다. 유닉스와 macOS의 기본 동작 인 소위 forked parallel processing에서는 작동하지 않습니다 (실제로는 유효하지 않습니다).

  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)을 사용하면 전역 내보내기가 더 중요합니다.

추신. 나는 단지 a을 반환하고 b 정보를 외부로 추출합니다.

+0

시간을내어 설명해 주셔서 감사합니다. # 5는 오류를 확실히 해결합니다. 귀하의 코드에서 수익이 보이지 않습니까? – ctlamb