数学建模国赛倒计时4天——《统计模型精讲(混合效应模型R语言实现)》

文章目录

0、引言

本文基于 R语言 介绍完整实战案例。我们将使用内置数据集 sleepstudy,它记录了10名受试者在连续0-9天内的睡眠剥夺后,对反应时间(Reaction)的影响。这是一个典型的纵向数据(重复测量),非常适合用混合效应模型来分析。

这个案例会从数据探索模型构建模型比较结果可视化,逐步带你走一遍完整流程。


第一步:加载包和数据

首先,我们需要加载必要的R包并查看数据。

r 复制代码
# 安装必要的包(如果尚未安装)
# install.packages("lme4")
# install.packages("lmerTest")  # 提供p值
# install.packages("ggplot2")

# 加载包
library(lme4)      # 混合效应模型核心包
library(lmerTest)  # 提供p值
library(ggplot2)   # 绘图

# 加载内置数据集
data("sleepstudy")
head(sleepstudy)

输出示例:

复制代码
  Reaction Days Subject
1 249.5600    0     308
2 258.7047    1     308
3 250.8006    2     308
4 321.4398    3     308
5 356.8519    4     308
6 414.6901    5     308
  • Reaction:反应时间(毫秒),因变量(连续型)
  • Days:睡眠剥夺的天数(0-9天),自变量(连续型)
  • Subject:受试者编号(1-18),分组变量(分类)

第二步:数据可视化

我们先画一张图,直观地看看不同受试者的变化趋势。

r 复制代码
# 绘制每个受试者的反应时间随天数的变化
ggplot(sleepstudy, aes(x = Days, y = Reaction, color = Subject)) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE) +  # 每个受试者单独拟合回归线
  theme_minimal() +
  labs(title = "不同受试者睡眠剥夺后的反应时间变化",
       x = "睡眠剥夺天数", y = "反应时间 (毫秒)")

从图中你会发现:

  • 大部分受试者的反应时间随天数增加而上升(正向斜率)。
  • 但不同受试者的**起点(截距)上升速度(斜率)**差异很大。这就是引入随机效应的原因。

第三步:构建三个递进的混合效应模型

我们逐步从简单到复杂构建三个模型,并比较它们的优劣。

模型1:普通线性回归(无随机效应,作为基准)
r 复制代码
m0 <- lm(Reaction ~ Days, data = sleepstudy)
summary(m0)

This model assumes that all subjects share exactly the same intercept and slope, ignoring the "clustered" structure of the data.


模型2:随机截距模型(Random Intercept)

允许不同受试者的**起点(截距)不同,但斜率(Days的影响)**相同。

r 复制代码
m1 <- lmer(Reaction ~ Days + (1 | Subject), data = sleepstudy)
summary(m1)
  • (1 | Subject) 表示:随机效应只作用于截距,不同受试者的截距围绕总体平均值随机波动。

模型3:随机截距 + 随机斜率模型(最完整)

允许不同受试者既有不同的起点,又有不同的变化速度

r 复制代码
m2 <- lmer(Reaction ~ Days + (1 + Days | Subject), data = sleepstudy)
summary(m2)
  • (1 + Days | Subject) 表示:截距和斜率都随受试者变化,且两者之间可能存在相关性。

第四步:模型比较与选择

我们可以用 anova() 进行似然比检验,比较哪个模型更好。

r 复制代码
# 比较模型1(m0)和模型2(m1)
# 注意:lm 和 lmer 不能直接比较,这里比较 m1 和 m2
anova(m1, m2)

输出示例:

t 复制代码
Data: sleepstudy
Models:
m1: Reaction ~ Days + (1 | Subject)
m2: Reaction ~ Days + (1 + Days | Subject)
    npar    AIC    BIC  logLik deviance  Chisq Df Pr(>Chisq)    
m1    4 1802.1 1814.8 -897.04   1794.1                         
m2    6 1763.9 1783.1 -875.97   1751.9 42.139  2  7.072e-10 ***

解读

  • AIC和BIC值:m2(1763.9)明显小于m1(1802.1),说明m2拟合更好。
  • 似然比检验:p值极小(7.07e-10),表明随机斜率模型(m2)显著优于随机截距模型(m1)。这说明不同受试者受睡眠剥夺影响的程度确实不同。

因此,我们最终选择模型 m2作为最优模型。


第五步:查看模型结果并解释

r 复制代码
summary(m2)

关键输出解读:

固定效应部分

r 复制代码
Fixed effects:
            Estimate Std. Error     df t value Pr(>|t|)    
(Intercept)  251.405      6.825  17.00  36.838  < 2e-16 ***
Days          10.467      1.546  17.00   6.771 2.68e-06 ***
  • 截距 (251.4):当Days=0时,受试者的平均反应时间约为251.4毫秒。
  • 斜率 (10.47):睡眠剥夺每增加1天,反应时间平均增加约10.47毫秒,且这个效应非常显著(p < 0.001)。

随机效应部分

r 复制代码
Random effects:
 Groups   Name        Variance Std.Dev. Corr
 Subject  (Intercept) 612.10   24.741       
          Days         35.07    5.922   0.07
 Residual             654.94   25.592       
  • Subject截距方差 (612.10):不同受试者起点差异很大。
  • Days斜率方差 (35.07):不同受试者受睡眠剥夺影响的程度差异很大。
  • Corr = 0.07:截距和斜率的相关系数接近0,说明起点高的人不一定下降得慢。

第六步:可视化模型预测结果

最后,我们提取每个受试者的随机效应,并画出各自的拟合线,直观展示模型如何捕捉个体差异。

r 复制代码
>  coef(m1)
$Subject
    (Intercept)     Days
308    292.1888 10.46729
309    173.5556 10.46729
310    188.2965 10.46729
330    255.8115 10.46729
331    261.6213 10.46729
332    259.6263 10.46729
333    267.9056 10.46729
334    248.4081 10.46729
335    206.1230 10.46729
337    323.5878 10.46729
349    230.2089 10.46729
350    265.5165 10.46729
351    243.5429 10.46729
352    287.7835 10.46729
369    258.4415 10.46729
370    245.0424 10.46729
371    248.1108 10.46729
372    269.5209 10.46729

attr(,"class")
[1] "coef.mer"
r 复制代码
# 提取每个受试者的随机效应系数
coef_m1 <- coef(m1)$Subject
head(coef_m1)
coef(m1)
# 绘制原始数据 + 模型拟合线
ggplot(sleepstudy, aes(x = Days, y = Reaction, color = Subject)) +
  geom_point() +
  geom_abline(data = coef_m1, 
              aes(intercept = `(Intercept)`, slope = Days, color = rownames(coef_m1)),
              show.legend = FALSE) +
  theme_minimal() +
  labs(title = "混合效应模型(随机截距+斜率)拟合结果",
       x = "睡眠剥夺天数", y = "反应时间 (毫秒)")
r 复制代码
# 提取每个受试者的随机效应系数
coef_m2 <- coef(m2)$Subject
head(coef_m2)

# 绘制原始数据 + 模型拟合线
ggplot(sleepstudy, aes(x = Days, y = Reaction, color = Subject)) +
  geom_point() +
  geom_abline(data = coef_m2, 
              aes(intercept = `(Intercept)`, slope = Days, color = rownames(coef_m2)),
              show.legend = FALSE) +
  theme_minimal() +
  labs(title = "混合效应模型(随机截距+斜率)拟合结果",
       x = "睡眠剥夺天数", y = "反应时间 (毫秒)")
r 复制代码
> coef_m2
    (Intercept)       Days
308    253.6637 19.6662617
309    211.0064  1.8476053
310    212.4447  5.0184295
330    275.0957  5.6529356
331    273.6654  7.3973743
332    260.4447 10.1951090
333    268.2456 10.2436499
334    244.1725 11.5418676
335    251.0714 -0.2848792
337    286.2956 19.0955511
349    226.1949 11.6407181
350    238.3351 17.0815038
351    255.9830  7.4520239
352    272.2688 14.0032871
369    254.6806 11.3395008
370    225.7921 15.2897709
371    252.2122  9.4791297
372    263.7197 11.7513080
> 

你会看到:每个受试者都有一条属于自己的回归线,截距和斜率各不相同,完美地拟合了各自的个体差异。


总结与建议

模型 公式 适用场景
随机截距模型 `lmer(y ~ x + (1 group))`
随机截距+斜率 `lmer(y ~ x + (1 + x group))`

注意事项

  1. 如果你的分组数很少(如 < 5),随机效应可能估计不准,需谨慎。
  2. 如果数据量较大,可以考虑 glmer() 用于广义混合效应模型(如逻辑回归、泊松回归)。
  3. 模型收敛问题:若遇到收敛警告,可尝试调整优化器参数或中心化自变量。

相关推荐
知无不研1 小时前
c语言中循环的介绍与简单应用
c语言·开发语言·算法·循环·for·while
郝学胜-神的一滴1 小时前
Qt 高级编程 045:坐标体系深度实战
开发语言·c++·windows·python·qt·程序人生
dsyyyyy11011 小时前
JS复习,难点,易错点总结
开发语言·javascript·ecmascript
“AI国潮设计-小江”2 小时前
Python实战 | SDXL精准控制“普宁英歌舞×星空蛋糕”IP落地,附核心Prompt与商用授权思路
开发语言·人工智能·python·prompt·aigc
小刘在重生~4 小时前
Java常用类|String类详解 + BigDecimal精准计算(含面试题)
java·开发语言·python
YYYing.4 小时前
【C++进阶系列 (二)】关于线程堆栈的那些事——函数调用过程
开发语言·c++·函数·线程堆栈
邪修king4 小时前
Re:Linux系统篇(十九):进程篇(八): 进程等待详解:wait/waitpid,僵尸进程到底该如何回收
java·开发语言
嵌入式冰箱5 小时前
数学建模辅助平台使用说明书 && 实际使用参考:各环节 Token 消耗明细及费用预估指南
数学建模
我爱写代码i5 小时前
SKAPP SK影视反编译详细教程+源码 含苹果端ipa
开发语言·javascript·ecmascript