并行化 r 脚本

Parallelize r script

首先,我对 R 中的 doparallel 和 parallel 包有初步的了解,所以请不要在没有示例代码的情况下推荐这些包。

我目前正在处理使用 glmnet 包生成的 LASSO 回归模型。我依靠这个包中的 cv.glmnet 函数来告诉我理想的 lamda 是什么......所有这些垃圾都与我的实际问题无关,但我希望背景故事有所帮助。 cv.glmnet 函数可以满足我的要求,但耗时太长。我想将它并行化。

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

是否可以在 r 中跨多个 CPUs/cores 分配单个计算(哪些包、示例代码等)?或者,是否可以制作并行化包,如 parallel 和 doparallel,识别 cv.glmnet 函数的迭代结构,然后为我分发它?我正在寻找建议,将不胜感激任何帮助或见解。

很遗憾,我无权共享我正在使用的数据。有关可重现的示例,请参阅此 post,答案中的代码是 copy/paste 生成数据的质量,套索回归并给出了 cv.glmnet 函数的示例用法:https://stats.stackexchange.com/questions/72251/an-example-lasso-regression-using-glmnet-for-binary-outcome

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)

要添加到您的问题中,有一类称为 "Embarrassingly Parallel" 的问题可以简单地并行化,这些包大多数使用 foreach 循环,以便可以并行化这些循环中的代码。因此,这种情况下所需要做的就是启用并行化(注册一个并行后端)并且 foreach 循环将并行执行。