【问题标题】:Parallel model scoring R并行模型评分 R
【发布时间】:2013-11-26 17:59:18
【问题描述】:

我正在尝试使用 snow 包在 R 中对弹性网络模型进行评分,但我无法弄清楚如何让 predict 函数在集群中的多个节点上运行。下面的代码既包含时间基准测试,也包含产生错误的实际代码:

##############
#Snow example#
##############

library(snow)
library(glmnet)
library(mlbench)

data(BostonHousing)
BostonHousing$chas<-as.numeric(BostonHousing$chas)

ind<-as.matrix(BostonHousing[,1:13],col.names=TRUE)
dep<-as.matrix(BostonHousing[,14],col.names=TRUE)

fit_lambda<-cv.glmnet(ind,dep)

#fit elastic net
fit_en<<-glmnet(ind,dep,family="gaussian",alpha=0.5,lambda=fit_lambda$lambda.min)

ind_exp<-rbind(ind,ind)

#single thread baseline
i<-0
while(i < 2000){
    ind_exp<-rbind(ind_exp,ind)
    i = i+1
    }

system.time(st<-predict(fit_en,ind_exp))

#formula for parallel execution
pred_en<-function(x){
    x<-as.matrix(x)
    return(predict(fit_en,x))
    }

#make the cluster
cl<-makeSOCKcluster(4)
clusterExport(cl,"fit_en")
clusterExport(cl,"pred_en")

#parallel baseline
system.time(mt<-parRapply(cl,ind_exp,pred_en))

我已经能够通过使用多核的 Linux 机器上的 fork 进行并行化,但我最终不得不使用性能相当差的 mclapply 与 unlist 相结合,并正在寻找一种更好的方法来处理雪(顺便说一句也行)在我的开发 Windows PC 和我的 prod Linux 服务器上)。谢谢。

【问题讨论】:

    标签: r parallel-processing multicore prediction snow


    【解决方案1】:

    首先我应该说predict.glmnet 函数的计算密集度似乎不够值得并行化。但这是一个有趣的例子,我的回答可能对你有所帮助,即使这种特殊情况不值得并行化。

    主要问题是parRapply 函数是apply 的并行包装器,它反过来在子矩阵的行上调用您的函数,这不是您想要的。您希望直接在子矩阵上调用您的函数。 Snow 不包含执行此操作的便捷函数,但很容易编写:

    rowchunkapply <- function(cl, x, fun, ...) {
        do.call('rbind', clusterApply(cl, splitRows(x, length(cl)), fun, ...))
    }
    

    您的示例中的另一个问题是您需要在工作人员上加载 glmnet 以便调用正确的预测函数。您也不需要显式导出 pred_en 函数,因为它会为您处理。

    这是我的示例版本:

    library(snow)
    library(glmnet)
    library(mlbench)
    
    data(BostonHousing)
    BostonHousing$chas <- as.numeric(BostonHousing$chas)
    ind <- as.matrix(BostonHousing[,1:13], col.names=TRUE)
    dep <- as.matrix(BostonHousing[,14], col.names=TRUE)
    fit_lambda <- cv.glmnet(ind, dep)
    fit_en <- glmnet(ind, dep, family="gaussian", alpha=0.5,
                     lambda=fit_lambda$lambda.min)
    ind_exp <- do.call("rbind", rep(list(ind), 2002))
    
    # make and initialize the cluster
    cl <- makeSOCKcluster(4)
    clusterEvalQ(cl, library(glmnet))
    clusterExport(cl, "fit_en")
    
    # execute a function on row chunks of x and rbind the results
    rowchunkapply <- function(cl, x, fun, ...) {
        do.call('rbind', clusterApply(cl, splitRows(x, length(cl)), fun, ...))
    }
    
    # worker function
    pred_en <- function(x) {
        predict(fit_en, x)
    }
    mt <- rowchunkapply(cl, ind_exp, pred_en)
    

    您可能也有兴趣使用 cv.glmnet parallel 选项,该选项使用 foreach 包。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-19
      • 1970-01-01
      • 1970-01-01
      • 2016-10-03
      • 2016-04-07
      • 1970-01-01
      • 1970-01-01
      • 2019-01-13
      相关资源
      最近更新 更多