我正在尝试使用并行处理来加速在R中运行许多Boosted回归树。我正在使用BiocParallel包(http://lcolladotor.github.io/2016/03/07/BiocParallel/#.WiqF7bQ-e3c)。我已经创建了一些虚拟数据,然后设置了一个运行两个BRT模型的函数,我希望在Serial中然后并行运行。但是,我的并行运行似乎永远不会完成,而我的串行运行只需要大约3秒钟。
##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)
)
答案 0 :(得分:2)
一些快速评论:
始终避免assign()
;如果你发现自己正在使用它,那么这是一个好的迹象,表明你正在以错误的方式解决问题。
从函数内部(使用assign()
或<<-
)将变量分配给全局环境总是一个坏主意,并再次提示您应该使用更好的解决方案。
如果你仍然选择打破上面的1和2,那么当你使用并行处理时肯定会不。
相反,返回您的值(见下文)。
dismo::gbm.step()
函数默认情况下尝试绘制(plot.main = TRUE
)。这在所谓的分叉并行处理中是行不通的(实际上是无效的),这通常是Unix和macOS的默认处理。
并行绘图通常不是您想要做的(除非您绘制图像文件或类似文件)。
解决您的问题:将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
信息。