将线性混合模型拟合到非常大的数据集
fitting a linear mixed model to a very large data set
我想 运行 一个混合模型(使用 lme4::lmer
)基于以下格式的 60M 观察;除了连续因变量 tc
之外,所有 predictor/dependent 变量都是分类(因素); 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 个左右。我不认为我可以获得任何额外的 space 分配。
除了我目前使用的是四个内核中的一个外,我对并行处理一无所知。谁能为这个模型建议并行代码,或者可能是不同的修复?
正如 Carl Witthoft 所指出的,R 中的标准并行化工具使用 共享内存 模型,因此它们会使事情变得更糟而不是更好(它们的主要目的是加速计算绑定 使用多个处理器的作业)。
在短期内,您可以通过将分类固定效应预测变量(age
、atc
)视为随机效应但强制它们的方差变大来节省一些内存。我不知道这是否足以拯救你;它会大量压缩固定效应模型矩阵,但模型框架仍将 stored/replicated 与模型对象 ...
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()
恢复他们的 (unsh运行k) 估计。
从长远来看,解决这个问题的正确方法可能是将其与分布式内存模型并行化。换句话说,您可能希望将数据分块发送到不同的服务器;使用 ?modular
中描述的机制来建立一个似然函数(实际上是一个 REML 准则函数),该函数将数据子集的 REML 准则作为参数的函数;然后 运行 一个中央优化器,它采用一组参数并通过将参数提交给每个服务器、从每个服务器检索值并添加它们来评估 REML 标准。我看到实现它的唯一两个问题是(1)我实际上不知道如何在 R 中实现分布式内存计算(基于 this intro document it seems that the Rmpi/doMPI 包可能是正确的方法); (2) 在 lmer
的默认实现方式中,固定效应参数被分析出来,而不是明确地成为参数向量的一部分。
我想 运行 一个混合模型(使用 lme4::lmer
)基于以下格式的 60M 观察;除了连续因变量 tc
之外,所有 predictor/dependent 变量都是分类(因素); 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 个左右。我不认为我可以获得任何额外的 space 分配。
除了我目前使用的是四个内核中的一个外,我对并行处理一无所知。谁能为这个模型建议并行代码,或者可能是不同的修复?
正如 Carl Witthoft 所指出的,R 中的标准并行化工具使用 共享内存 模型,因此它们会使事情变得更糟而不是更好(它们的主要目的是加速计算绑定 使用多个处理器的作业)。
在短期内,您可以通过将分类固定效应预测变量(age
、atc
)视为随机效应但强制它们的方差变大来节省一些内存。我不知道这是否足以拯救你;它会大量压缩固定效应模型矩阵,但模型框架仍将 stored/replicated 与模型对象 ...
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()
恢复他们的 (unsh运行k) 估计。
从长远来看,解决这个问题的正确方法可能是将其与分布式内存模型并行化。换句话说,您可能希望将数据分块发送到不同的服务器;使用 ?modular
中描述的机制来建立一个似然函数(实际上是一个 REML 准则函数),该函数将数据子集的 REML 准则作为参数的函数;然后 运行 一个中央优化器,它采用一组参数并通过将参数提交给每个服务器、从每个服务器检索值并添加它们来评估 REML 标准。我看到实现它的唯一两个问题是(1)我实际上不知道如何在 R 中实现分布式内存计算(基于 this intro document it seems that the Rmpi/doMPI 包可能是正确的方法); (2) 在 lmer
的默认实现方式中,固定效应参数被分析出来,而不是明确地成为参数向量的一部分。