将线性混合模型拟合到非常大的数据集

时间:2015-07-16 11:23:50

标签: r parallel-processing bigdata lme4 mixed-models

我想在以下格式的60M观察中运行混合模型(使用lme4::lmer);除连续因变量tc外,所有预测变量/因变量都是分类(因子); patient是随机拦截术语的分组变量。我有64位R和16Gb RAM,我在中央服务器上工作。 RStudio是最新的服务器版本。

model <- lmer(tc~sex+age+lho+atc+(1|patient),
              data=master,REML=TRUE)

lho sex tc      age         atc patient
18  M   16.61   45-54       H   628143
7   F   10.52   12-15       G   2013855
30  M   92.73   35-44       N   2657693
19  M   24.92   70-74       G   2420965
12  F   17.44   65-69       A   2833610
31  F   7.03    75 and over A   1090322
3   F   28.59   70-74       A   2718649
29  F   4.09    75 and over C   384578
16  F   67.22   65-69       R   1579355
23  F   7.7     70-74       C   896374

我收到cannot allocate a vector of 25.5Gb错误。我在服务器上分配40Gb并使用25,所以我想这意味着我需要另外10个左右。我认为我不能分配任何额外的空间。

我不知道并行处理的第一件事,只是我目前正在使用四个核心之一。任何人都可以建议这个模型的并行代码,或者可能是一个不同的修复程序?

1 个答案:

答案 0 :(得分:3)

正如Carl Witthoft所指出的,R中的标准并行化工具使用共享内存模型,因此它们会使事情变得更糟而不是更好(它们的主要目的是加速计算 - 使用多个处理器绑定作业。)

在短期内,您可以通过将分类固定效应预测变量(ageatc)视为随机效果但强制其差异较大来节省一些记忆。我不知道这是否足以拯救你;它会压缩固定效应模型矩阵很多,但模型框架仍将与模型对象一起存储/复制......

dd1 <- read.table(header=TRUE,
text="lho sex tc      age         atc patient
18  M   16.61   45-54       H   628143
7   F   10.52   12-15       G   2013855
30  M   92.73   35-44       N   2657693
19  M   24.92   70-74       G   2420965
12  F   17.44   65-69       A   2833610
31  F   7.03    75_and_over A   1090322
3   F   28.59   70-74       A   2718649
29  F   4.09    75_and_over C   384578
16  F   67.22   65-69       R   1579355
23  F   7.7     70-74       C   896374")
n <- 1e5
set.seed(101)
dd2 <- with(dd1,
      data.frame(tc=rnorm(n,mean=mean(tc),sd=sd(tc)),
                 lho=round(runif(n,min=min(lho),max=max(lho))),
                 sex=sample(levels(sex),size=n,replace=TRUE),
                 age=sample(levels(age),size=n,replace=TRUE),
                 atc=sample(levels(atc),size=n,replace=TRUE),
                 patient=sample(1:1000,size=n,replace=TRUE)))
library("lme4")
m1 <- lmer(tc~sex+(1|lho)+(1|age)+(1|atc)+(1|patient),
           data=dd2,REML=TRUE)

随机效果按最大顺序自动排序 到最小数量的水平。遵循机器描述 在?modular帮助页面中:

lmod <- lFormula(tc~sex+(1|lho)+(1|age)+(1|atc)+(1|patient),
                  data=dd2,REML=TRUE)
names(lmod$reTrms$cnms)  ## ordering
devfun <- do.call(mkLmerDevfun, lmod)
wrapfun <- function(tt,bigsd=1000) {
    devfun(c(tt,rep(bigsd,3)))
}
wrapfun(1)
opt <- optim(fn=wrapfun,par=1,method="Brent",lower=0,upper=1000)
opt$fval <- opt$value  ## rename/copy
res <- mkMerMod(environment(devfun), opt, lmod$reTrms, fr=lmod$fr)
res

您可以忽略报告的分类术语差异,并使用 ranef()恢复他们的(未经预算)估计。

从长远来看,解决此问题的正确方法可能是将其与分布式内存模型并行化。换句话说,您可能希望将数据以块的形式包装到不同的服务器中;使用?modular中描述的机制建立似然函数(实际上是REML标准函数),该函数根据参数给出数据子集的REML标准;然后运行一个中央优化器,它接受一组参数并通过向每个服务器提交参数,从每个服务器检索值并添加它们来评估REML标准。我实现这一点时遇到的唯一两个问题是:(1)我实际上并不知道如何在R中实现分布式内存计算(基于this intro document似乎Rmpi / {{3} }包可能是正确的方法); (2)以默认方式实现lmer,固定效应参数被分析出来而不是明确地成为参数向量的一部分。