r - 将 glmer 输出(logit 回归)转换为概率
问题描述
我有这样的数据。我在所有 Q 变量上运行 glm 。
dat <- read_table2("condition school Q5_3 Q6 Q7_1 Q7_2 Q7_3 Q7_4 Q13_1 Q13_2 Q13_3
0 A 1 1 1 1 1 1 0 1 1
1 B 1 0 0 NA NA NA NA 1 1
1 C 1 0 1 1 1 1 0 1 1
1 A 0 0 0 NA NA NA NA 1 1
1 B 1 0 0 NA NA NA NA 1 1
0 C 1 1 1 1 1 0 0 0 0
0 A 0 0 0 NA NA NA NA NA NA
0 B 1 1 1 1 1 1 1 1 1
0 C 1 1 0 NA NA NA NA 1 0
0 A 1 0 0 NA NA NA NA 1 0
0 B 1 0 1 1 0 1 1 NA NA
0 C 1 0 1 1 1 1 1 1 0
1 A 1 1 1 1 0 1 0 1 1
1 B 0 0 0 NA NA NA NA 1 1
0 C 1 0 0 NA NA NA NA NA NA
")
这是我用来提取我想要的系数的循环。
# We only need the condition and school
# Apply
models <- function(x)
{
model1 <- glmer(x~ (1|school) + condition ,data=dat , family = binomial, na.action = na.exclude)
return(model1)
}
y <- apply(dat[,-c(1,2)],2,models)
#Extract results
extract <- function(x)
{
z <- as.data.frame(summary(x)$coefficient)
z$id <- rownames(z)
z <- z[,c(dim(z)[2],1:(dim(z)[2]-1))]
rownames(z)<-NULL
return(z)
}
#Extract summary with function
DF <- as.data.frame(do.call(rbind,lapply(y,extract)))
#Format variables
DF$var <- gsub("\\..*","",rownames(DF))
#Arrange columns
DF_glm <- DF[,c(dim(DF)[2],1:(dim(DF)[2]-1))]
rownames(DF)<-NULL
这个循环工作正常,但我需要将输出(系数)从对数赔率转换为概率。关于如何做到这一点的任何建议?
解决方案
坏消息:实际上没有任何明智的方法可以将逻辑回归的系数(在对数优势比或 logit 尺度上)转换为概率尺度。从对数赔率到概率的转换取决于基线水平,因此要获得概率,您必须对特定情况下的概率进行预测:参见例如这个 CrossValidated question。
好消息:对系数取幂可以得到优势比,这通常比对数优势比更容易理解并且可以说更容易理解。
library(broom.mixed)
dd <- dat[,-c(1,2)]
## find (and drop) examples with no variation
uu <- apply(dd,2,function(x) length(unique(na.omit(x))))
modList <- apply(dd[,uu>1],2,models)
## generate list of models
purrr:::map_dfr(modList,tidy,
effect="fixed",
exponentiate=TRUE,.id="Q")
这为您提供了一个表格(小标题),其中包含对优势比量表、标准误差、p 值等的估计值。还有其他选项,例如conf.int=TRUE
您是否需要表格中的置信区间。您可以使用任何 tidyverse 工具来操作它(例如%>% filter(term=="condition")
,如果您对截取不感兴趣)。
这个例子中的许多答案都是假的,但那是因为你的数据集太小了......我希望你的真实数据集比这个大......
解释为什么您通常不能将优势比转换为概率(不指定基线)实际上更像是一个统计/交叉验证问题,但我将根据UCLA 统计网站给出一个简短的示例
- 导入数据:缩放 GRE 和 GPA 的预测变量以获得更多可解释的参数值。
library(tidyverse)
dd <- (haven::read_dta("https://stats.idre.ucla.edu/stat/stata/dae/binary.dta")
%>% mutate_at(c("gre","gpa"), ~drop(scale(.)))
)
- 拟合模型并提取系数
m <- glm(admit~gre+gpa, family=binomial, dd)
cc <- coef(m)
## (Intercept) gre gpa
## -0.8097503 0.3108184 0.2872088
- 改造:
plogis()
是用于逆 logit(逻辑)变换的内置 R 函数。
转换截距参数确实有意义:它给出了具有基线特征的个体的预测概率;由于我们已将预测变量居中,因此这对应于具有总体平均 GPA 和 GRE 的个体。
int_prob <- plogis(cc["(Intercept)"]) ## 0.307
我们还可以预测平均 GRE 和 GPA 比平均值高一个标准差的个人的概率(GPA 参数的单位是“每标准差”,因为我们用标准差缩放了 GPA 变量):
gre_prob <- with(as.list(cc), plogis(`(Intercept)`+gre)) ## 0.3777
我们可以计算这些预测之间的差异,这是指定 GRE 对概率尺度影响的一种方法:
gre_prob-int_prob ## 0.0698
但是,它仅适用于这种特定的比较(平均 GPA 和 GRE 高于平均数 1 SD 的个人与平均 GPA 和 GRE 的个人相比)。如果我们从不同的基线开始或对不同的 GRE 变化进行预测,那么每单位 GRE 的概率变化会有所不同。
如果需要,您可以对 GRE 系数进行逻辑转换:
plogis(cc["gre"]) ## 0.577
不过,这意味着什么?如果您随后将其 GRE 提高 1 个标准差,则它是基线对数几率为零的个人(不是具有平均 GPA 和 GRE 的个人)的成功概率。不是一件容易解释的事情......
还有其他经验法则/近似规则可以理解对数赔率的含义,例如除以 4 规则,但它们都以某种方式依赖于指定基线水平。
推荐阅读
- php - 如何检查函数执行时间&如果执行时间超过 10 秒则返回
- visual-studio - 验证安装目录是否为 FAT
- ms-access - Microsoft Access,其他用户无法打开表/查询
- r - ggplot2:组合条形图和折线图对齐
- git - 适用于 Linux 的 Windows 子系统 git mergetool meld UnicodeDecodeError
- javascript - ReactJS/GraphQL:显示来自查询的数据
- scala - 标签之间的 Alpakka XML 内容
- go - 在 go-mode emacs 会话中找不到 Godef
- python - 在 pymc3 逻辑回归中使用 NUTS 调试收敛和慢速采样问题
- python - Unicode 到字典(Unicode 包含撇号标点符号)