Rou*_*use 12 parallel-processing foreach r glmnet
我的训练数据集有大约200,000条记录,我有500个功能.(这些是来自零售组织的销售数据).大多数功能都是0/1,并存储为稀疏矩阵.
目标是预测约200种产品的购买概率.因此,我需要使用相同的500个功能来预测200种产品的购买概率.由于glmnet是模型创建的自然选择,我想到了为200个产品并行实现glmnet.(因为所有200个型号都是独立的)但是我被困在使用foreach.我执行的代码是:
foreach(i = 1:ncol(target)) %dopar%
{
assign(model[i],cv.glmnet(x,target[,i],family="binomial",alpha=0,type.measure="auc",grouped=FALSE,standardize=FALSE,parallel=TRUE))
}
Run Code Online (Sandbox Code Playgroud)
model是一个列表 - 包含200个模型名称的列表,我想在其中存储各自的模型.
以下代码有效.但它没有利用并行结构,需要大约一天才能完成!
for(i in 1:ncol(target))
{ assign(model[i],cv.glmnet(x,target[,i],family="binomial",alpha=0,type.measure="auc",grouped=FALSE,standardize=FALSE,parallel=TRUE))
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,有人能指出如何利用并行结构吗?
Ste*_*ton 23
为了并行执行"cv.glmnet",您必须指定该parallel=TRUE选项,并注册foreach并行后端.这允许您选择最适合您的计算环境的并行后端.
以下是cv.glmnet手册页中"并行"参数的文档:
parallel:如果为'TRUE',请使用并行'foreach'来适合每个折叠.必须事先注册并行,例如'doMC'或其他.请参阅下面的示例.
以下是使用适用于Windows,Mac OS X和Linux的doParallel软件包的示例:
library(doParallel)
registerDoParallel(4)
m <- cv.glmnet(x, target[,1], family="binomial", alpha=0, type.measure="auc",
grouped=FALSE, standardize=FALSE, parallel=TRUE)
Run Code Online (Sandbox Code Playgroud)
这个对cv.glmnet的调用将使用四个worker并行执行.在Linux和Mac OS X上,它将使用"mclapply"执行任务,而在Windows上,它将使用"clusterApplyLB".
嵌套并行性变得棘手,并且对于仅有4个工作者可能没有帮助.我会尝试在cv.glmnet周围使用正常for循环(如第二个示例中所示)并注册并行后端,并在添加另一个并行级别之前查看性能.
另请注意,在注册并行后端时,第一个示例中对"model"的赋值不起作用.当并行运行时,副作用通常会被抛弃,就像大多数并行编程包一样.
偶然发现了这个旧线程,并认为提及在未来的框架中可以进行嵌套和并行foreach()调用会很有用。例如,假设您有三台本地机器(通过 SSH 访问)并且您希望在每台机器上运行四个内核,那么您可以使用:
library("doFuture")
registerDoFuture()
plan(list(
tweak(cluster, workers = c("machine1", "machine2", "machine3")),
tweak(multiprocess, workers = 4L)
))
model_fit <- foreach(ii = seq_len(ncol(target))) %dopar% {
cv.glmnet(x, target[,ii], family = "binomial", alpha = 0,
type.measure = "auc", grouped = FALSE, standardize = FALSE,
parallel = TRUE)
}
str(model_fit)
Run Code Online (Sandbox Code Playgroud)
“外部” foreach 循环将迭代目标,以便每次迭代都由单独的机器处理。每次迭代将依次cv.glmnet()使用四名工人在它最终使用的任何机器上进行处理。
(当然,如果你只能访问一台机器,那么做嵌套并行处理就没有意义了。我这种情况,你可以使用:
plan(list(
sequential,
tweak(multiprocess, workers = 4L)
))
Run Code Online (Sandbox Code Playgroud)
并行化cv.glmnet()调用,或者,
plan(list(
tweak(multiprocess, workers = 4L),
sequential
))
Run Code Online (Sandbox Code Playgroud)
,或等效地只是plan(multiprocess, workers = 4L),以并行化目标。