代码之家  ›  专栏  ›  技术社区  ›  Erdne Htábrob

带lme4和长向量的mclapply

  •  2
  • Erdne Htábrob  · 技术社区  · 7 年前

    我正在使用 mclapply parallel 用混合算法估计混合GLMME模型 lme4 高性能群集上的包。我有这个问题 described here . 我应用建议的添加 mc.preschedule=F ,但问题仍然存在。代码设置为 described here .

    我不知道该怎么办,有什么想法吗?我应该切换到另一种并行化方法吗?如果是这样,怎么办?

    这是我的代码,但基本上遵循链接文章的逻辑:

    rm(list = ls())
    
    require(lme4)
    require(parallel)
    
    load(file="//share//home//eborbath//ess_rescaled.Rda") # load data
    
    # paralelizing function
    
    f_lmer_mc = function(data, calls, mc.cores) {
      require(parallel)
      if (is.data.frame(data)) 
        data = replicate(length(calls), data, simplify = F)
      for (i in 1:length(data)) attr(data[[i]], "cll") = calls[i]
      m.list = mclapply(data, function(i) eval(parse(text = attr(i, "cll"))), 
                        mc.cores = mc.cores, mc.preschedule = FALSE)
      return(m.list)
    }
    
    ##########
    # Models #
    ##########
    
    
    controls <- c("gender", "agea", "eduyrs", "domicil", "unemployed", "rideol", "union", "pid", "hincfel")
    values <- c("conformity", "universalism", "security")
    issues <- c("gincdif", "freehms")
    agr.ctrl <- c("gdp_wb_ppp", "wb_vae")
    lr.agr <- c("lr_rsquar_std", "ri_l2_std")
    val.agr <- c("mean_univ", "mean_conf", "mean_secur")
    end <- "1 + (1|cntry/countryyear), data=i, control=glmerControl(optimizer='bobyqa', optCtrl = list(maxfun = 1e9)), family=binomial(link='logit'))"
    
    models = c(paste0("glmer(protest ~", paste(c(controls, end), collapse="+")),
    paste0("glmer(protest ~", paste(c(controls, values, end), collapse="+")),
    paste0("glmer(protest ~", paste(c(controls, values, issues, end), collapse="+")),
    paste0("glmer(protest ~ region+", paste(c(controls, values, issues, end), collapse="+")),
    paste0("glmer(protest ~ region+", paste(c(controls, values, issues, agr.ctrl, end), collapse="+")), 
    paste0("glmer(protest ~ region+", paste(c(controls, values, issues, agr.ctrl, lr.agr, end), collapse="+")),
    paste0("glmer(protest ~ region+", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")), # until here it's only main effects
    paste0("glmer(protest ~ region*rideol + region+", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")), 
    paste0("glmer(protest ~ region*rideol*year + region+year+", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")), 
    paste0("glmer(protest ~ region*rideol*year_num + region+year_num+", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")), 
    paste0("glmer(protest ~ region*soc_pop_eleches + region+soc_pop_eleches+", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")), # now come the expl. models
    paste0("glmer(protest ~ region*rideol*soc_pop_eleches + region+soc_pop_eleches+", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")),
    paste0("glmer(protest ~ region*ri_l2_std + region+", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")),
    paste0("glmer(protest ~ region*ri_l2_std*rideol + region+", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")),
    paste0("glmer(protest ~ region*lr_rsquar_std + region+", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")),
    paste0("glmer(protest ~ region*lr_rsquar_std*rideol + region+", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")),
    paste0("glmer(protest ~ region+gov_genlr", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")),
    paste0("glmer(protest ~ region*gov_genlr + region+gov_genlr", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")),
    paste0("glmer(protest ~ region*gov_genlr*rideol + region+gov_genlr", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")),
    paste0("glmer(protest ~ region+pol_lrecon", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")),
    paste0("glmer(protest ~ region+pol_galtan", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")),
    paste0("glmer(protest ~ region+pol_galtan+pol_lrecon", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")),
    paste0("glmer(protest ~ region*pol_lrecon+region+pol_galtan+pol_lrecon", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")),
    paste0("glmer(protest ~ region*pol_galtan+region+pol_galtan+pol_lrecon", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")),
    paste0("glmer(protest ~ region*pol_lrecon*rideol+region+pol_galtan+pol_lrecon", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")),
    paste0("glmer(protest ~ region*pol_galtan*rideol+region+pol_galtan+pol_lrecon", paste(c(controls, values, issues, agr.ctrl, lr.agr, val.agr, end), collapse="+")))
    
    m.list = f_lmer_mc(data, models, 24)
    
    m.1 <- c(m.list[1:3])
    m.2 <- c(m.list[4:6])
    m.3 <- c(m.list[7:9])
    m.4 <- c(m.list[10:12])
    m.5 <- c(m.list[13:15])
    m.6 <- c(m.list[16:18])
    m.7 <- c(m.list[19:21])
    m.8 <- c(m.list[22:24])
    m.9 <- c(m.list[25:26])
    
    save(m.1, data, file='m_1.RData')
    save(m.2, data, file='m_2.RData')
    save(m.3, data, file='m_3.RData')
    save(m.4, data, file='m_4.RData')
    save(m.5, data, file='m_5.RData')
    save(m.6, data, file='m_6.RData')
    save(m.7, data, file='m_7.RData')
    save(m.8, data, file='m_8.RData')
    save(m.9, data, file='m_9.RData')
    

    这是相关的错误信息:

    Error in sendMaster(try(eval(expr, env), silent = TRUE)) : 
      long vectors not supported yet: fork.c:378
    Calls: f_lmer_mc ... mclapply -> lapply -> FUN -> mcparallel -> sendMaster
    

    谢谢!

    更新:

    数据是公开可用的 European Social Survey . 你可以从 here (1.8 MB)

    2 回复  |  直到 7 年前
        1
  •  3
  •   Steve Weston    7 年前

    我认为这个错误是因为分叉的工作进程正在错误地序列化非常大的结果对象。我已经能够用下面的代码在r 3.3.2中重现这个错误:

    library(parallel)
    r <- mclapply(1:2, function(i) 1:2^30, mc.cores=2, mc.preschedule=FALSE)
    

    但是,这个例子为我使用了一个64位的R3.4.3版本,所以序列化的限制似乎已经被删除(或至少增加)在R的后期版本中。

    我建议您要么尝试将result对象的大小减小到小于2GB,要么使用r的最新版本。

        2
  •  2
  •   Aaron - mostly inactive    7 年前

    对我以上的评论进行扩展:

    我看到你正在复制数据集,然后把它发送给 过程。我已经有一段时间没做过类似的事情了,但你可能不会 需要这样做;小插曲说“用mclapply把所有的包和 我们使用的对象在工人身上自动可用。 这将负责处理进程,而Ralf Stubner 希望这项建议能起到作用。

    若要尝试不复制数据,请首先使用调用 data 正如你读到的 load 打电话,而不是 i ;你只要换这条线就行了。

    end <- "1 + (1|cntry/countryyear), data=data, control=glmerControl(optimizer='bobyqa', optCtrl = list(maxfun = 1e9)), family=binomial(link='logit'))"
    

    然后有 mclapply 只需运行这些,而不复制数据。

    library(parallel)
    m.list = mclapply(calls, function(i) eval(parse(text=i)), 
                      mc.cores = 2, mc.preschedule = FALSE)
    

    在查看 glmer 输出,我认为最好在进程中执行您希望的任何处理,而不是修改 格尔默 输出,修改 格尔默 输出可能会更难获得您想要的摘要之后。这里我只得到了摘要,并把它放在一个列表中,这样你也可以很容易地添加其他输出。

    library(parallel)
    m.list = mclapply(calls, function(i) {
                         a <- eval(parse(text=i))
                         list(summary=summary(a))
                      }, mc.cores = 2, mc.preschedule = FALSE)
    

    请注意,这些都是未经测试的…