glm对象的visreg绘图与模型输出值不匹配问题咨询
问题描述
我有一份数据集,用以下R代码构建了一个所有变量均为因子类型的二项逻辑回归模型:
#setwd("wherever you downloaded the file") data_ev <- read.csv("all_EV.csv") df_all_EV <- data.frame(data_ev) #remove extra columns df_all_EV <- df_all_EV[,-1] df_all_EV <- df_all_EV[,-3] df_all_EV <- df_all_EV[,-4] #remove uneeded rows df_ev2 <- subset(df_all_EV, EV!="unknown") #factorize df_ev2$EV <- as.factor(df_ev2$EV) df_ev2$Speech_VP <- as.factor(df_ev2$Speech_VP) df_ev2$Genre <- as.factor(df_ev2$Genre) #set response variable ref level df_ev2$EV <- relevel(df_ev2$EV, ref = "self") #create glm object ev2.glm <- glm(EV ~ Genre + Speech_VP, data = df_ev2, family = binomial) summary(ev2.glm) #plot glm library(visreg) visreg(ev2.glm, "Speech_VP") visreg(ev2.glm, "Genre") visreg(ev2.glm, "Speech_VP", by = "Genre")
模型的输出结果如下:
Call: glm(formula = EV ~ Genre + Speech_VP, family = binomial, data = df_ev2) Deviance Residuals: Min 1Q Median 3Q Max -2.0115 -0.4628 -0.1381 0.5326 3.0519 Coefficients: Estimate Std. Error z value Pr(>|z|) (Intercept) -4.6475 0.5115 -9.086 < 2e-16 *** GenreTN 4.0611 0.4379 9.274 < 2e-16 *** Speech_VPN 2.4675 0.3762 6.559 5.4e-11 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 (Dispersion parameter for binomial family taken to be 1) Null deviance: 434.02 on 313 degrees of freedom Residual deviance: 227.37 on 311 degrees of freedom AIC: 233.37 Number of Fisher Scoring iterations: 5
用visreg包绘制Genre变量的可视化图后,我发现Y轴显示的数值和模型摘要里的对数优势比对不上:比如模型中GenreTN的对数优势比是4.06,但图里蓝色拟合线的数值大概是2,其他变量也有同样的情况。想问问这种模型摘要和绘图数值不一致的原因是什么?
问题解答
核心原因是visreg默认展示的是边际预测值,不是单纯的变量系数,二者的含义完全不同:
- 模型摘要里的系数(比如GenreTN的4.0611),指的是把其他协变量固定在参考水平时,该变量水平相对于参考水平的对数优势比变化量。
- 而visreg的默认逻辑是:绘制目标变量的效应时,会将其他协变量的所有水平做整合处理——分类变量取各水平预测值的加权平均(权重是各水平的样本量),连续变量取均值,最终展示的是整合其他变量后的边际预测对数优势比。
拿你的模型举例:
- 当绘制Genre的效应时,visreg会对Speech_VP的两个水平(参考水平和N水平)的预测值取加权平均,而不是固定Speech_VP在参考水平。
- 具体计算:GenreTN对应的预测对数优势比,在Speech_VP参考水平时是
-4.6475 + 4.0611 = -0.5864;在Speech_VPN水平时是-4.6475 + 4.0611 + 2.4675 = 1.8811。如果两个水平的样本量相近,加权平均后就会接近1.8,和你图里看到的数值一致。
如果想让visreg绘制固定其他协变量在参考水平的预测值,可以用cond参数指定,比如:
# 固定Speech_VP在参考水平,绘制Genre的效应 visreg(ev2.glm, "Genre", cond = list(Speech_VP = levels(df_ev2$Speech_VP)[1]))
另外,你也可以通过scale参数切换Y轴的展示尺度,比如设置scale="response"直接展示预测概率,会更直观:
visreg(ev2.glm, "Genre", scale="response")
内容的提问来源于stack exchange,提问作者Wangana
相关产品推荐
相关产品推荐

