并行化脚本

时间:2018-09-18 02:54:28

标签: r parallel-processing glmnet

首先,我对R中的doparallel和parallel软件包非常熟悉,所以请不要建议没有示例代码的这些软件包。

我目前正在使用使用glmnet软件包生成的LASSO回归模型。我依赖于此程序包中的cv.glmnet函数来告诉我理想的lamda是...所有这些垃圾都与我的实际问题无关,但我希望后面的故事有所帮助。 cv.glmnet函数可以实现我想要的功能,但是花费的时间太长。我要并行化它。

我的问题是,并行r软件包设计为获取列表,然后对该列表应用操作,因此当我尝试传递诸如cv.glmnet之类的完善函数(即使它是迭代的)时,我得到了单核处理我希望cv.glmnet处理的单个数据集,而不是将此过程分布在服务器上的所有核上。

是否可以在r中的多个CPU /内核之间分配单个计算(哪些程序包,示例代码等)?或者,是否有可能使并行化包(如parallel和doparallel)识别cv.glmnet函数的迭代结构,然后为我分发它?我正在寻求建议,任何帮助或见识将不胜感激。

不幸的是,我无权共享正在使用的数据。有关可重现的示例,请参见这篇文章,答案中的代码是复制/粘贴质量,用于生成数据,套索回归,并提供了cv.glmnet函数的使用示例:https://stats.stackexchange.com/questions/72251/an-example-lasso-regression-using-glmnet-for-binary-outcome

2 个答案:

答案 0 :(得分:3)

cv.glmnet易于设置并行参数设置为TRUE

有关如何执行此操作的示例可以在文档中找到

https://www.rdocumentation.org/packages/glmnet/versions/2.0-16/topics/cv.glmnet

此示例使用doMC,但是您应该能够轻松地将其更改为使用并行包

require(doMC)
registerDoMC(cores=4)
x = matrix(rnorm(1e5 * 100), 1e5, 100)
y = rnorm(1e5)
system.time(cv.glmnet(x,y))                # not parallel
system.time(cv.glmnet(x,y,parallel=TRUE))  # this is parallel

并行版本如下:

library(doParallel)
library(glmnet)
no_cores <- detectCores() - 1
print(no_cores)
# Initiate cluster
cl <- makeCluster(no_cores)
registerDoParallel(cl)

x = matrix(rnorm(1e5 * 100), 1e5, 100)
y = rnorm(1e5)
system.time(cv.glmnet(x,y))                # not parallel
system.time(cv.glmnet(x,y,parallel=TRUE))  # this is parallel
stopCluster(cl)

要添加到您的问题中,有一类问题可以称为“令人尴尬的并行”,这些问题可以平凡地并行化,这些软件包大多数使用foreach循环,以便可以并行化这些循环内的代码。因此,在这种情况下,所需要做的就是启用并行化(注册并行后端),并且foreach循环将并行执行。

答案 1 :(得分:0)

对我来说,这个非常简单的解决方案有效:

在您的功能之前添加它。在这里要小心,如果您在函数中包含此功能,则我几乎总是会用完RAM(并且我有32 GB的RAM)。如果我将其包裹在整个脚本中,效果很好。

 library(doParallel)
 cl <- makeCluster(detectCores(), type='PSOCK')
 registerDoParallel(cl)
 # some function
 registerDoParallel()

其他方式:

 library(doParallel)
 cores=detectCores()
 cl <- makeCluster(cores[1])

然后将您的apply函数更改为parApply

 parApply(cl,data,2,function(x){#your function})
相关问题