ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

GLMM实战解析:正确处理嵌套数据与伪重复问题

GLMM实战解析:正确处理嵌套数据与伪重复问题 上周一个做生态学的师弟来找我说手头有三年野外样地调查数据响应变量是样地里观测到的某种鸟类个体数量普通泊松回归跑出来显著性一片红审稿人却质疑他有“伪重复”。这种场景我太熟悉了——问题几乎一定出在数据不独立上同一个样地、同一条样线、同一只个体被反复测量观测与观测之间根本没满足传统回归要求的独立性。处理这种嵌套结构、重复测量、响应变量还明显非正态的数据就得把广义线性混合模型也就是GLMM正式抬上桌面。今天这篇不谈空泛的概念就聊清楚三件事为什么你的普通GLM在这里不成立、GLMM的数学结构究竟是怎么把固定和随机两部分“混合”起来的、以及从拿到数据到完成一篇能过审稿人眼的论文插图具体应该按什么步骤跑。适合正在做生态、医学、教育、经济类纵向数据或区组设计数据的朋友参考也适合刚入门混合模型但被各种术语绕晕的同学。1. 为什么普通回归搞不定嵌套数据GLMM的出场逻辑1.1 伪重复你算错的不是模型是样本量先回到我师弟那个案例。他的数据结构很简单40个样地每个样地每年调查一次连续三年共120条记录。响应变量是计数预测变量是生境类型和年份。按理说用泊松回归很合理计数数据嘛用glm(count ~ habitat year, family poisson)直接跑也没报错。问题在哪问题在于这120条记录根本不是120个互相独立的样本。实际上只有40个独立的“样地单元”每年测的那三次是同一块地重复观察的结果。用普通GLM处理时模型默认每条记录都携带等量的独立信息于是自由度被严重高估标准误被严重低估本来不显著的效应也会被跑出显著的P值。这就是生态学文献里反复警告的“伪重复”pseudoreplication本质上是一个样本量口径错误的问题统计软件不会主动提醒你因为软件根本不知道哪些记录来自同一个样地。伪重复的后果是隐蔽的系数估计可能还存在方向也可能基本对但标准误、置信区间和P值全都不靠谱。也就是说你得到了一条明确的虚假证据链。审稿人一旦画出你的数据结构图指出“同一个样地的重复测量应该作为随机效应放进模型”你如果没提前处理就只能匆匆重跑。所以第一课就是先看数据结构别急着灌进glm()。1.2 当“固定效应”装不下所有组间差异时传统GLM把所有解释变量都当作固定效应意思是每个变量带来的影响是固定的、普遍的、可重复估计的比如“生境A比生境B的鸟类数量平均高多少”。这没有错但它隐含了一个假设所有观测在拟合时是独立的组间差异要么可以完全被固定效应捕捉要么就不存在。真实数据很少这么干净。样地之间、个体之间、班级之间天然会有一些难以测量的、随机的异质性。比如样地A土壤湿度大样地B周围有河流这些都可能影响鸟类数量但你不一定都测了或者测了也不想把它们当作主要研究对象。这时这些“潜变量”就是一股笼罩在数据上的随机扰动源它们会让组内观测更相似、组间观测差异更大如果不加处理模型残差就会显示出明显的组内相关性普通GLM的独立性假设直接崩塌。混合模型的思路就是把模型里的一部分项设成“随机效应”——它们来自一个均值为0、方差待估计的分布用来吸收组间随机的、不可测的那部分差异让固定效应的估计重新变得干净。广义线性混合模型则在此基础上进一步允许响应变量服从二项、泊松、负二项等非正态分布所以‘广义’、‘线性’和‘混合’三个词缺一不可。1.3 什么情况下你该考虑换用GLMM根据我这几年的使用经验下面几条里命中两条以上基本就走GLMM路线了响应变量不是连续正态分布而是计数、0/1成败、比例或右偏的连续正数数据存在明显的嵌套结构、分层结构、重复测量、区组设计、纵向追踪你关心总体平均效应但需要同时考虑个体/样地/班级之间难以测量的随机波动固定效应模型跑完以后残差仍有明显的组内相关或诊断图中出现“一团一团的散点”。命中这些条件后别再用简单回归硬抗也不建议把每个组都放进固定效应里那样会消耗大量自由度而且无法对新组做预测。把组当作随机效应是更优雅也统计上更合理的选择。2. 拆开GLMM的数学内核固定效应、随机效应与链接函数2.1 模型公式从线性预测器到观测值GLMM的常见写法是[ g(\mu_{ij}) \mathbf{x}{ij}^\top \boldsymbol\beta \mathbf{z}{ij}^\top \mathbf{b}_i ]其中 (\mu_{ij} E(Y_{ij} \mid \mathbf{b}i))表示在第 (i) 个组里第 (j) 次观测的期望响应值(g(\cdot)) 是链接函数(\mathbf{x}{ij}^\top \boldsymbol\beta) 是固定效应部分所有个体共享(\mathbf{z}_{ij}^\top \mathbf{b}_i) 是随机效应部分每个组有自己的实现。随机效应部分通常假设 (\mathbf{b}_i \sim N(0, \mathbf{D}))也就是这些组级别的偏移量来自一个均值为0、协方差矩阵为 (\mathbf{D}) 的多元正态分布。你不需要去估计每个组的随机效应具体值背后的“原因”只估计它们服从的分布参数比如随机截距方差 (\sigma_b^2)就足以刻画组间异质性。为了更容易理解可以把整条链路拆三层线性预测器(\eta_{ij} \mathbf{x}{ij}^\top \boldsymbol\beta \mathbf{z}{ij}^\top \mathbf{b}_i)它是一个不受取值范围限制的连续量链接函数(\mu_{ij} g^{-1}(\eta_{ij}))把线性预测器映射到响应期望的取值范围抽样分布(Y_{ij} \sim \text{Dist}(\mu_{ij}, \phi))实际观测被视为围绕着期望值、按特定分布生成的随机实现。这第三层很关键。混合模型的核心并非套一个数学模型而已而是明确区分了“结构部分”哪些变量影响均值和“随机部分”数据围绕均值怎么波动。传统线性回归只允许高斯波动GLMM把波动方式扩展到了二项、泊松、负二项等覆盖范围和现实数据终于对上了。2.2 链接函数与分布族不是所有计数都能直接套泊松在GLMM里“广义”三个字具体就体现在分布族和链接函数的组合上。下面这个表是我平时选型时最常用的速查表响应变量类型分布族常用链接函数最典型场景连续、近似对称高斯identity恒等生长量、成绩、血压变化0/1成败二项logit或probit存活/死亡、有无、是否发病计数泊松log个体数量、发生次数过离散计数负二项log昆虫计数、植物密度正偏态连续Gammalog反应时间、成本、生物量比例/比率二项logit覆盖率、成功率、患病率为什么需要链接函数一个很朴素的类比线性预测器 (\eta) 可以跑到负无穷到正无穷但泊松分布的均值 (\mu) 必须大于零二项分布的均值必须落在0到1之间。链接函数就是一座桥把无限区间“压”到响应变量允许的范围内。比如泊松回归用 log 链接意味着 (\mu \exp(\eta))这样不管 (\eta) 是什么(\mu) 都自动大于0。没有这座桥理论上就会出现“预测出负的计数”这种荒谬结果。需要特别提醒碰到计数数据时先不要默认选泊松。泊松分布有一个很强的假定——方差等于均值现实中数据几乎总是方差大于均值也就是过离散。如果过离散存在却不处理标准误仍然会被低估。常规做法是先拟合泊松GLMM计算皮尔逊残差平方和除以剩余自由度若显著大于1就要转向负二项分布或者在模型里加一个观测水平随机效应专门吸收过离散部分。2.3 随机效应不只是“加个截距”随机截距与随机斜率很多初学者对随机效应的理解停留在“给每个组加一个随机截距”这远远不够。随机效应能改变的不只是各组基准水平的不同还包括各组对同一预测变量的响应幅度不同。随机截距(z_{ij}1)(\mathbf{b}_i) 是一个标量各组整体上下移动随机斜率比如考虑年份对鸟类数量的影响某些样地增加迅速、某些样地基本不增甚至下降此时1 year | site_id就允许每块样地有自己的年份斜率项随机截距与随机斜坡相关(D) 里还包含截距和斜率之间的协方差表述“基准水平高的组变化趋势是否也更强”。随机斜率不是加得越多越好。随机效应结构过大会让模型极度难以收敛尤其是组数少、每组观测少的时候。我的习惯是先尽量拟合最完整的随机效应结构如果出现收敛警告或奇异拟合就用主成分分析考察随机效应协方差矩阵依据特征值把贡献极小的随机项去掉如果模型没报错再用似然比检验判断复杂随机结构是否显著优于简单结构。整个过程像在做减法而不是加法。2.4 参数是怎么估出来的REML、Laplace与自适应高斯求积理解估计方法对你是很有帮助的因为很多运行报错都跟估计方法有关。线性混合模型LMM里常用REML也就是限制最大似然它对方差分量做无偏估计但到了GLMM由于响应分布不再假设为高斯通常没有解析的边际似然需要通过数值积分“积掉”随机效应得到边际似然后再做最大似然估计。常用的近似手段包括惩罚拟似然速度快但对二项和泊松这种离散分布偏差较大尤其均值很小或数据稀疏时偏差明显不太建议作为最终报告依据拉普拉斯近似目前lme4默认的方法之一精度比PQL高适用于较常见的模型自适应高斯求积在高斯点基础上迭代调整节点位置和尺度对随机效应维度较低时精度很好贝叶斯MCMC或Hamiltonian Monte Carlo比如brms、MCMCglmm处理复杂的随机效应结构、小样本或强先验信息时表现更稳。每个方法的本质都是回答“如何在存在潜变量 (\mathbf{b}_i) 的情况下最大化观测数据的边际似然”——因为观测数据的概率需要对所有可能的随机效应取值求平均而不是在某个固定随机效应取值上求似然。这一步如果做得不好后面的系数估计和似然比检验全都不可靠。3. 一套能直接复制的GLMM分析流程以R为例比起堆概念这里直接给一套我常用的、可复制的分析流程软件以R的lme4包为主辅以DHARMa、marginaleffects等工具。这套流程我至少跑了上百次逻辑大致稳定。3.1 数据准备先确认三件事再跑模型第一件明确数据的层级结构。谁嵌套在谁里病人嵌套在医生、学生嵌套在班级、观测嵌套在个体这些层级中哪些是我们要当随机效应处理的要注意随机效应之间可能是“交叉”的因子水平并非严格嵌套比如同时给每个学生和每个单词加随机截距两者就是交叉关系。第二件数一数组的数量。随机效应组的数量太少方差会估计得很不稳定。经验上随机效应的组数最好不少于6个如果能到10个以上更好。组数只有三四个时不建议轻易用GLMM除非你有很强的先验信息或使用贝叶斯方法。第三件对连续预测变量中心化或标准化。这一点在GLMM里经常被忽略。中心化能降低固定效应截距项与随机效应之间的相关性还能显著降低优化难度。特别是模型含交互项时中心化几乎成了标配。数据准备的代码很简单但重要library(lme4) library(lmerTest) library(DHARMa) library(marginaleffects) df - read.csv(bird_data.csv) df$year_c - scale(df$year, center TRUE, scale TRUE) df$habitat - factor(df$habitat) df$site_id - factor(df$site_id) str(df)很多人的第一行模型就死于变量之间量纲差异巨大导致的数值问题。把数据整理清楚不是洁癖是严谨的建模习惯。3.2 拟合模型理解lme4的核心语法最常用的函数是lmer()响应为高斯分布和glmer()其它分布。两者的语法结构一样核心就是模型公式。走上正轨的一个完整示例m_pois - glmer(count ~ habitat * year_c (1 year_c | site_id), data df, family poisson, control glmerControl( optimizer bobyqa, optCtrl list(maxfun 2e5) ))模型公式里(1 year_c | site_id)是理解GLMM的关键语法竖线左边的1表示随机截距year_c表示随机斜率竖线右边是随机效应分组变量。小括号整体表示“随机效应部分”而固定效应直接写在公式主体里。control参数的设置不能省。lme4默认优化器在处理稍微复杂一点的模型时就报“收敛警告”我在跑含随机斜率的泊松模型时经常会遇到。显式设定为bobyqa并调高最大迭代次数maxfun是解决这类警告最直接的手段。注意虽然还有Nelder_Mead优化器可以尝试但bobyqa对GLMM的稳定性整体更好一些。拟合完成后第一件事是看summary()但更重要的三件事看固定效应部分的系数、标准误、P值看随机效应部分的方差分量看输出末尾有没有收敛警告。如果看到“boundary (singular) fit”或“failed to converge”先不要急着解释系数回到第4节去处理。3.3 模型比较与固定效应推断怎么判断谁该留在模型里GLMM的推断通常围绕两个层面固定效应是否显著以及随机效应结构是否合适。固定效应检验有几个层次用summary()直接看系数表其中P值在lmerTest包加载后会基于Satterthwaite或Kenward-Roger自由度近似给出用anova(m_full, m_reduced)比较两个嵌套模型的拟合优度差异得到卡方和P值这是似然比检验用confint(m, method Wald)或profile置信区间看参数估计的不确定性只报P值不报置信区间是目前很多期刊明确反对的。随机效应结构比较则更谨慎。一般流程是固定效应先保持不变比较随机效应结构的简单与复杂版本m_simple - glmer(count ~ habitat * year_c (1 | site_id), data df, family poisson) m_complex - glmer(count ~ habitat * year_c (1 year_c | site_id), data df, family poisson) anova(m_simple, m_complex)如果似然比检验显示复杂随机结构并没有显著改善拟合就选更简单的随机结构因为随机斜率模型拟合困难和过度参数化的风险更高。反过来若检验显著说明各组的年份趋势确实不同保留随机斜率是合理的。还需要看整体模型的解释力。可以用MuMIn::r.squaredGLMM()计算边际R²固定效应单独解释的方差比例和条件R²固定随机共同解释的方差比例。需要记住GLMM的R²没有线性回归的R²那么直观只能辅助比较不能作为唯一判断标准。3.4 模型诊断summary没问题不代表模型没问题诊断这一节是我每次上课都要强调的环节。GLMM的残差不像线性回归那样可以直接套正态假设尤其泊松和二项分布原始残差天然是离散的、异方差的直接画残差图几乎看不出问题。我用DHARMa包做模拟残差诊断这是目前我觉得最可靠的做法。核心思路是基于拟合模型模拟多次新数据把观测值放在模拟分布中的位置作为残差得到标准化的残差。然后检查四点残差是否整体均匀分布看KS检验P值是否出现系统性偏差看残差对预测值的分位数回归线是否过离散DHARMa会直接给出检验结果是否有离群点看outlier检验。代码如下sim_out - simulateResiduals(fittedModel m_pois) plot(sim_out) testDispersion(sim_out)关于过离散还有一个更直接的手工判断法计算皮尔逊残差平方和与剩余自由度之比明显大于1说明存在过离散。如果过离散得到确认通常有两种方案改用family negbinomial负二项或保留泊松但加入观测水平随机效应(1 | obs_id)。随机效应本身的诊断也不能跳过。用ranef()提取随机效应估计值画QQ图检查它们是否大致服从正态分布。如果随机效应分布严重偏离正态会影响对其协方差矩阵的解释但并不一定会改变固定效应的系数估计。遇到极端情况时考虑对响应变量做变换或改用贝叶斯混合模型。4. 你大概率会碰到的运行错误与统计陷阱把这一章单独拿出来是因为GLMM的运行错误几乎人人都会碰到而且报错信息往往不直接告诉你问题出在哪容易让人一头雾水。下面几个场景是我自己在实际分析中最常遇到的。4.1 收敛警告模型没有失败但你也没法信任它lme4输出“Model failed to converge with max|grad| 0.002...”这类警告时最麻烦的是模型仍然给出了一组看起来很完整的系数和方差。初学者最容易犯的错误是“它还能输出应该只是吓唬我”。但事实是优化器没有在参数空间里找到稳定的最大值跑出来的参数不能当作可靠结果报告。处理顺序是这样的换优化器比如把bobyqa换成Nelder_Mead或同时为固定效应和随机效应指定不同优化器增加迭代次数maxfun到10万、20万甚至50万。模型太复杂时默认迭代可能恰好不够检查预测变量的量纲数值范围差异过大的先中心化和标准化简化随机效应结构把最复杂的那部分随机斜率去掉查看allFit()的多优化器比较结果如果大部分优化器收敛到近似的参数值说明警告可能是数值误差结果仍可报告反之则必须改模型。我还碰到过一种情况用bobyqa还是持续报不收敛稳但把响应变量的单位扩大十倍就正常了。这种由于数据尺度引起的数值问题通过重新缩放往往是见效最快的。4.2 奇异拟合随机效应方差等于0问题出在哪“boundary (singular) fit”是另一个高频警告。它表示某个随机效应的方差被估计为0或随机效应之间的相关系数被估计为±1也就是说优化过程跑到了参数空间的边界。这类警告通常意味着模型对数据来说太复杂了。你给每个组都加了随机斜率但组间差异并没有那么大或者组内观测太少不足以支持估计这么多随机参数。此时要做的是简化随机效应结构去掉随机斜率只保留随机截距或检验不同结构之间的似然比。不过也有一类特殊情况如果重复测量数据中个体间差异客观存在但观测值本身波动特别大随机效应方差被压缩到0也是有可能的。这时要结合研究设计来判断理论上必须存在的随机效应即使方差是0也可能需要保留。关键是把判断写清楚而不是盲目追求跑通一个“漂亮的模型”。4.3 完分离二项模型里的一类显著假象在二项GLMM里如果某个预测变量组合下响应全部是0或全部是1就会发生完分离最大似然估计会趋向无穷大。这时候输出里会出现异常大的标准误或者模型干脆拒绝收敛。对这种问题常用的处理方案有用惩罚似然方法比如brglm2包给参数估计加一点惩罚换用贝叶斯GLMM为固定效应指定温和的先验比如正态先验可以稳定估计检查是否有变量线性组合能完美预测响应必要时合并类别或删除预测变量。完分离问题在生态学里常见的“所有存活”或“所有死亡”组里出现。数据本身是真实的但标准GLMM无能为力直接跑出来的结果也非常不可信。遇到它不要硬跑要换方法。4.4 组数太少GLMM不是包治百病的灵药经常会有人拿着三个重复、每个重复里几十个个体的数据来找我跑GLMM。随机效应组数这么少估计出来的组间方差可信吗基本不可信。随机效应的方差估计在组数少时通常偏低且极大似然估计容易产生较大偏差。有两个替代思路如果你是固定效应为主只有少量组需要控制差异考虑把组当作固定效应虽然消耗自由度但至少估计稳定用贝叶斯混合模型配合信息性先验比如对随机效应方差给一个正则化先验能在一定程度上缓解小样本问题。很关键的一点是做统计方法和模型选择要诚实当数据无法支撑复杂模型时选择更简单的方法并解释原因远比硬报一个不稳定GLMM结果更体面。4.5 过离散的规范化处理细节泊松模型跑完以后如果不做过渡离散检验就急着解释结果很容易中招。实际操作上发现过离散后转向负二项分布通常是合理的但在报告里需要明确说明检验过程和分布选择的依据。如果数据是“比例型”的计数数据比如“100个个体里有多少成活”正确的做法往往既不是直接当二项响应把所有个体都当成0/1记录也不是用logit变换后跑普通线性模型而是用加权的二项模型或者以个体数量为权重的二项GLMMm_binom - glmer(cbind(success, total - success) ~ treatment (1 | site_id), data df, family binomial)这里的响应变量是两列组成的矩阵lme4会自动按比例数据的方式处理。这种写法很多教科书没细讲但实际应用中非常常见。5. 结果汇报与论文呈现怎样让别人信服你的GLMM5.1 一篇论文里GLMM方法部分必须写清楚的七件事审稿人看到“we used a generalized linear mixed model”这句话后心里会立刻列一个检查清单漏了任何一项都会被质疑方法不透明。我建议至少写清楚这七项响应变量的分布族和链接函数比如“Poisson distribution with log link”固定效应有哪些变量是否包含交互项连续变量是否中心化随机效应结构明确写出随机截距和随机斜率的设定以及分组因素数据层级结构比如样地内的重复观察、个体内的纵向测量拟合软件和核心函数版本比如R的lme4版本号估计方法比如Laplace近似模型比较流程比如用似然比检验比较嵌套模型用AIC比较非嵌套模型。写清楚这些不是说能保证发表但至少能减少“方法细节不足”这一类的审稿意见。5.2 汇报固定效应和随机效应的正确姿势固定效应部分我推荐的汇报格式是给出每个因子的效应估计值β、标准误、置信区间然后是P值。不能只写P值因为P值不提供效应大小和方向的信息。比如下面这种写作方式就比较完整生境类型显著影响鸟类个体数β 0.42SE 0.1895% CI [0.07, 0.78]P 0.021表明生境B比生境A的预测鸟类数量平均增加52%exp(0.42) ≈ 1.52。这里的逆链接变换非常关键。在GLMM里系数是线性预测器尺度上的只有转换回原始尺度才有直观意义。泊松模型的系数取指数后是倍数效应logit模型的系数取指数后是优势比odds ratio。很多读者愤恨地在文章里看到“β 0.42”却不给出任何变换等于让读者自己查对数表体验极差。随机效应部分报告方差分量的估计值和标准差或者直接报告组内相关系数ICC也就是组间方差占总方差的比例。ICC的含义是“总变异里有多大比例来自组间差异”它和固定效应一样重要却经常被忽略。对生态学里的嵌套数据而言ICC高说明不可测的组间异质性强也就是说随机效应的建模是必要的。5.3 图形展示要画模型预测别只画原始均值图形上最常见的错误是把原始数据的均值画成柱状图加标准误然后在图上标字母表示显著性。这种做法既不展示模型结构也不利于比较组间差异的大小审稿人早就看腻了。建议展示模型预测值和置信区间。推荐用marginaleffects或effects包来绘制library(marginaleffects) newdata - expand.grid( habitat levels(df$habitat), year_c seq(min(df$year_c), max(df$year_c), length.out 50) ) pred - predictions(m_pois, newdata newdata, re.form NA) head(pred)re.form NA表示计算边际效应时随机效应被设为0即得到的是总体平均预测而不是某个具体样地的条件预测。如果想让图体现随机效应造成的组间变异可以通过re.form NULL来生成每个组对应的条件预测画成一组细线或分面图。再补充一个个人习惯在同一张图上画固定效应的总体预测线和95%置信带同时用半透明的细线叠加上各组条件预测让读者一眼看到“总体趋势”和“组间差异”的关系。这种画法在生态学论文里出现频率越来越高展示的信息量大且直观。5.4 灵活应对来自审稿人/导师的质疑最后几个我亲测有效的高频问答写在这里供你参考“你的样本量是否够”——回答时直接列出随机效应组数、每组观测数、总观测数结合自己的模型复杂程度解释经验法则是每组至少5-10个观测随机效应组数最好在10个以上如果不够明说使用了贝叶斯先验做辅助。“你怎么证明泊松分布合适”——展示过渡离散检验结果和DHARMa残差图如果改用负二项分布解释为什么以及结果是否有实质性变化。“随机斜率有必要吗”——展示似然比检验结果说明复杂随机结构是否显著改善拟合。不显著就不保留并说明这是为了控制模型复杂度。“为什么不用普通回归”——画出数据分层结构图展示ICC或组间差异直接说明伪重复风险。这个理由在几乎所有领域都是成立的。应对这些问题的核心就是一句话每一步都要有迹可循模型选择过程透明检验结果直接展示不藏着掖着。审稿人对统计方法的质疑往往不是真的要推翻结论而是确认作者没有乱用模型。在实际操作中我还发现一个容易被忽略的小技巧把所有模型比较的结果包括AIC变化、似然比检验的卡方和P值按顺序整理成一张表格放进附录正文里只保留最终模型的结果。这不仅让主文干净还能在审稿人质疑时展示出完整的建模逻辑链。把这一步做扎实GLMM这条路就算走通了。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进