我认为在这里退后一步并简化事情是有道理的。出于这个答案的目的,我们可以考虑这个模型:
Y ~ X + (X | G)
...在两种情况下:X
个人/单位级别的X
变化,以及群体水平的变化。
拟合随机斜率的动机通常源于以下原因。我们有一项测量个人的研究,我们对某些固定效应感兴趣,即变量的斜率。例如,它可以是随时间测量的相同变量,也可以是对变量不同处理水平的反应。如果我们只有一个人,我们只需进行测量并考虑如下图:
set.seed(1)
X <- 1:20
Y <- 3 + X + rnorm(20, 0, 3)
ggplot(data.frame(Y, X), aes(y = Y, x = X)) + geom_point() + geom_smooth(method = 'lm', se = FALSE)
然后,我们的兴趣将是模型中拟合线的斜率:
> lm(Y ~ X) %>% coef()
(Intercept) X
3.062716 1.067789
现在,当我们有多个个体时,我们不想为每个个体拟合单独的模型,如下所述:Difference between t-test on betas from individual regressions vs linear mixed modeling
所以我们想要随机截距,其中每个个体对 X 具有相同的固定效应(斜率),但截距不同。此外,我们自然会期望每个人都有自己的斜率,所以我们想要随机斜率X
:
set.seed(1)
n.group <- 10
dt <- expand.grid(G = 1:n.group, X = 1:20)
dt$Y = 1
X <- model.matrix(~ X, dt)
myFormula <- "Y ~ X + (X | G)"
foo <- lFormula(eval(myFormula), dt)
Z <- t(as.matrix(foo$reTrms$Zt))
betas <- c(3, 1)
b1 <- rnorm(n.group, 0, 3) # random intercepts
b2 <- rnorm(n.group, 0, 0.5) # random slopes
b <- c(rbind(b1, b2))
dt$Y <- X %*% betas + Z %*% b + rnorm(nrow(dt), 1)
dt$G <- as.factor(dt$G)
ggplot(dt, aes(y = Y, x = X, colour = G)) + geom_point() + geom_smooth(method = 'lm', formula= y ~ x, se = FALSE)
一切都很好。这是说明随机斜率和截距的经典图。每条线代表一个人/组,并有自己的截距和斜率。请注意,这不是从混合模型的输出中绘制的,而是从数据本身绘制的。我们拟合混合模型以估计参数,在随机效应的情况下,随机截距和斜率的方差和协方差。
现在,如果我们让X
成为一个组级预测器:
dt$X <- as.numeric(dt$G) / 4
X <- model.matrix(~ X, dt)
dt$Y <- X %*% betas + Z %*% b + rnorm(nrow(dt), 1)
ggplot(dt, aes(y = Y, x = X, colour = G)) + geom_point() + geom_smooth(method = 'lm', formula= y ~ x, se = FALSE)
我们可以立即看到,每组是每个X
值的垂直累积点。因此,每个组/个人都没有斜率。
这就是为什么为仅在组级别变化的变量拟合随机斜率是没有意义的。如果我们尝试将具有随机斜率的模型拟合到此类数据,它几乎肯定不会收敛或收敛到奇异拟合。我几乎可以肯定地说,因为正如 OP 中所述,我们有时确实会看到这样的模型确实会收敛。这就是为什么分析师有必要考虑他们在做什么。绘制数据是许多分析任务中非常好的第一步,可以帮助避免错误,并通常引导分析朝着正确的方向发展。