我的训练数据集有大约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))
}
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))
}
在这种情况下,有人能指出如何利用并行结构吗?
2 回答
为了并行执行"cv.glmnet",您必须指定
parallel=TRUE
选项,并注册foreach并行后端 . 这允许您选择最适合您的计算环境的并行后端 .以下是cv.glmnet手册页中“并行”参数的文档:
以下是使用适用于Windows,Mac OS X和Linux的doParallel软件包的示例:
这个对cv.glmnet的调用将使用四个worker并行执行 . 在Linux和Mac OS X上,它将使用“mclapply”执行任务,而在Windows上,它将使用“clusterApplyLB” .
嵌套并行性变得棘手,并且对于仅有4个工作者可能没有帮助 . 我会尝试在cv.glmnet周围使用正常for循环(如第二个示例中所示)并注册并行后端,并在添加另一级并行之前查看性能 .
另请注意,在注册并行后端时,第一个示例中的“model”赋值不起作用 . 当并行运行时,副作用通常会被抛弃,就像大多数并行编程包一样 .
偶然发现这个旧线程并认为使用future框架提及它是有用的,可以进行嵌套和并行的
foreach()
调用 . 例如,假设您有三台本地计算机(SSH访问)并且您希望在每台计算机上运行四个核心,那么您可以使用:"outer" foreach循环将迭代目标,以便每个迭代由单独的机器处理 . 每次迭代都将使用四个工作人员在最终的任何机器上处理
cv.glmnet()
.(当然,如果你只能访问一台机器,那么进行嵌套并行处理就没什么意义了 . 在这种情况下,你可以使用:
并行化
cv.glmnet()
呼叫,或者,,或等效地只是
plan(multiprocess, workers = 4L)
,以并行化目标 .