并行化r脚本

问题描述 投票:1回答:2

首先,我对R中的多波并行和并行封装有一个基本的了解,所以请不要在没有示例代码的情况下建议这些封装。

我目前正在使用glmnet包生成的LASSO回归模型。我依靠这个软件包中的cv.glmnet函数来告诉我理想的lamda是什么......所有这些垃圾对我的实际问题都是不敬的,但我希望后面的故事有所帮助。 cv.glmnet函数可以实现我想要的功能,但需要的时间太长。我想并行化它。

我的问题是并行r包被设计为获取列表然后将操作应用于该列表,所以当我尝试传递像cv.glmnet这样的抛光函数时(即使它是迭代的),我得到一个单核处理我希望cv.glmnet处理的单个数据集,而不是这个进程分布在我服务器上的所有核心上。

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

不幸的是,我没有权限分享我正在使用的数据。有关可重复的示例,请参阅此文章,答案中的代码是复制/粘贴质量以生成数据,套索回归并给出了cv.glmnet函数的示例使用:https://stats.stackexchange.com/questions/72251/an-example-lasso-regression-using-glmnet-for-binary-outcome

r parallel-processing glmnet
2个回答
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循环将并行执行。


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])

然后将您的应用功能更改为parApply

 parApply(cl,data,2,function(x){#your function})
© www.soinside.com 2019 - 2024. All rights reserved.