如何解释 R 中 lm 公式中的交互项?

机器算法验证 r 回归
2022-03-28 10:24:06

在 R 中,如果我lm()按以下方式调用函数:

lm.1 = lm(response ~ var1 + var2 + var1 * var2)
summary(lm.1)

这给了我一个响应变量的线性模型var1var2以及它们之间的相互作用。但是,我们如何准确地用数字解释交互项?

文档说这是var1and之间的“交叉” var2,但没有解释“交叉”到底是什么。

知道 R 正在计算哪些确切数字以合并两个变量之间的相互作用对我很有帮助。

4个回答

为您的模型编写预测方程的标准方法是:

y^=b0+b1x1+b2x2+b12x1x2

但是,如果我们以不同的方式考虑这一点,则理解交互会更容易一些:

y^=(b0+b2x2)+(b1+b12x2)x1

通过这个分解,我们可以看到对于给定的的 y 截距上的斜率之间的关系取决于x2x1b0+b2x2x1(b1+b12x2)yx1x2

的不同值(或相反)绘制R 的 TeachingDemos 包中的函数旨在帮助处理这些类型的绘图。yx1x2Predict.PlotTkPredict

用离散变量来考虑交互是最容易的。也许您可能已经研究过双向方差分析,其中我们有两个分组变量(例如性别和年龄类别,具有三个年龄级别),并且正在研究它们如何与某些连续测量(我们的因变量,例如智商)相关联。

x1 * x2 项,如果重要的话,可以理解为(在这个琐碎的、虚构的例子中)智商在不同性别的年龄水平上表现不同。例如,也许三个年龄组的男性智商是稳定的,但年轻女性的开始低于年轻男性,并且有上升的轨迹(老年组的平均值高于男性的老年组)。在均值图中,这意味着图表中间的男性水平线,可能是女性的 45 度线,从男性下方开始但在男性上方结束。

要点是,当您沿着一个变量的水平移动(或“保持 X1 不变”)时,另一个变量中发生的事情会发生变化。这种解释也适用于连续预测变量,但并不容易具体说明。在这种情况下,您可能想要取 X1 和 X2 的特定值,看看 Y 会发生什么。

假设你得到 4 的点估计x1, 2 为x2和 1.5 用于交互。然后,方程是说lm拟合是

y=4x1+2x2+1.5x1x2

那是你想要的吗?

根据@Greg Snow 的回答,我只想添加一个模拟显示:

set.seed(6);library(viridis)
n = 100
x.lm1 = rnorm(n = n, mean = 5, sd = 1)
x.lm2 = rnorm(n = n, mean = 2, sd = 1) # Note that this doesn't have to be normally distributed. This could be a uniform distribution or from a binomial.
beta0 = 2.5
beta1 = 1.5
beta2 = 2
beta3 = 3
err.lm = rnorm(n = n, mean = 0, sd = 1)
y.lm = beta0 + beta1*x.lm1 + beta2*x.lm2 + beta3*x.lm1*x.lm2 + err.lm
df.lm = data.frame(x1 = x.lm1, x2 = x.lm2, y = y.lm)
lm.out = lm(y~x1*x2, data = df.lm)

# Make a new range of x2 values on which we will test the effect of x1 
x2r = range(x.lm2)
x2.sim = seq(x2r[1],x2r[2], by = .5)

# this is the effect of x1 at different values of x2 (which moderates the effect of x1)
eff.x1 <- coef(lm.out)["x1"] + coef(lm.out)["x1:x2"] * x2.sim # this gets you the slopes  
eff.x1.int <- coef(lm.out)["(Intercept)"] + coef(lm.out)["x2"] * x2.sim # this gets you the intercepts  
eff.dat <- data.frame(x2.sim, eff.x1, eff.x1.int)

virPal <- viridis::viridis(length(x2.sim),alpha = .8)
eff.dat$x2.col <- virPal[as.numeric(cut(eff.dat$x2.sim,breaks = length(x2.sim)))]

df.lm$x2.col <- virPal[as.numeric(cut(df.lm$x2,breaks = length(x2.sim)))]
par(mfrow=c(1,1), mar =c(4,4,1,1))
plot(x = df.lm$x1, y = df.lm$y, bg = df.lm$x2.col, 
     pch = 21, xlab = "x1", ylab = "y")
apply(eff.dat, 1, function(x) abline(a = x[3], b = x[2], col = x[4], lwd  = 2))
abline(h = 0, v = 0,lty = 3)
legend("topleft", title = "x2",legend = round(eff.dat$x2.sim,1), lty = 1, lwd = 3,
       col = eff.dat$x2.col, bg = scales::alpha("white",.5))

在此处输入图像描述