首页 > 解决方案 > 并行化 r 脚本

问题描述

首先,我对 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

标签: rparallel-processingglmnet

解决方案


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 循环将并行执行。


推荐阅读