2.3.1 Logistic回归
下面这些医学研究问题,都把结局分为两类:
- 哪些术前因素与术后是否发生并发症有关?
- 某种暴露与是否出现感染有关吗?
- 综合患者的临床特征,能否计算规定随访期内再次入院的概率?
- 影像特征与病理诊断为恶性而非良性有怎样的关联?
Logistic 回归把二分类结局与一个或多个解释变量联系起来。 本节围绕一个问题展开:同一个模型中的回归系数、优势比和预测概率,分别在表达什么?学完后,你应能明确阳性结局,按单位和参考组解释优势比,并区分关联估计与概率预测。
2.3.1.1 先分清概率与优势
本节使用 MASS::birthwt 的189条母婴记录,结局 low=1表示出生体重小于2500克,0表示其他;共59例阳性。模型纳入年龄 age(岁)、末次月经时母亲体重 lwt(磅)和孕期吸烟 smoke(0=否,1=是),这四列均完整。数据说明
先看真实记录中的计数。后面的完整代码用 table() 得到:
吸烟组有30例低出生体重、44例其他,阳性比例是 。若把发生与未发生的数量直接相比,则是 。前者是概率的样本估计,后者是优势的样本估计。
优势(odds)定义为 ,其中 为阳性事件概率。它比较的是发生与未发生;概率则比较发生与全部观察。优势可以大于1,概率只能在0到1之间。
不吸烟组的优势为 。两组优势再相除,得到未经调整的优势比(odds ratio,OR):
这个数值表示吸烟组低出生体重的优势约为不吸烟组的2.022倍。它描述的是当前两组的直接比较;接下来的回归还会同时考虑年龄和母亲体重。Bland与Altman对OR的说明可用于进一步区分优势与事件概率。
2.3.1.2 系数为什么要指数化
概率有上下界,不能简单地用一个不受限制的线性和表示。Logistic 回归先将概率变为对数优势,再把它与各变量联系起来。
对本节模型,可写成:
是低出生体重的概率; 是对数优势,也称线性预测值。 是截距,其余 是回归系数。最后一项中,吸烟取1、不吸烟取0,因此不吸烟是参考组。这里连续变量线性关联的是对数优势,并不要求它们与概率呈直线关系。
保持其他入模变量相同,连续变量每增加一个原始单位,对数优势改变 ,优势乘以 ;所以该变量的 OR 为 。分类变量的 OR 则比较相应类别与参考类别。先看单位和参考组,才能知道 OR 对应哪一次比较。
“OR=2.022”表示优势的倍数;概率之间的倍数还取决于起始概率。上面的真实计数中,两组阳性比例之比约为1.608,和OR的数值不同。
2.3.1.3 用固定公式拟合模型
下面的代码独立准备输入,显示原始系数表,再计算 OR、Wald 置信区间和一条真实记录的概率。变量按当前教学问题预先列入模型;代码不进行自动筛选。
if (!requireNamespace("MASS", quietly = TRUE)) {
utils::install.packages("MASS", repos = "https://cloud.r-project.org")
}
utils::data("birthwt", package = "MASS")
# 结局low为数值0/1,1表示低出生体重。
model_formula <- low ~ age + lwt + smoke
smoking_levels <- c(0, 1)
smoking_labels <- c("no", "yes") # no=不吸烟,是参考水平。
conf_level <- 0.95 # OR的Wald置信水平;0.99通常给出更宽区间。
prediction_index <- 1L # 使用第一条真实记录,不构造新病例。
# 只按结局与入模变量保留完整观察。
analysis_data <- birthwt[c("low", "age", "lwt", "smoke")]
analysis_data <- analysis_data[stats::complete.cases(analysis_data), , drop = FALSE]
analysis_data$smoke <- factor(
analysis_data$smoke, levels = smoking_levels, labels = smoking_labels
)
# 固定处理对比:no为基准,系数smokeyes比较yes与no。
smoking_contrasts <- stats::contr.treatment(
levels(analysis_data$smoke), base = 1L
)
# binomial指定二分类分布;logit连接概率的对数优势。
# 改用probit或cloglog后,exp(系数)不能沿用本节的OR解释。
model_fit <- stats::glm(
model_formula, data = analysis_data,
family = stats::binomial(link = "logit"),
contrasts = list(smoke = smoking_contrasts),
na.action = stats::na.fail, # 缺失即停止,避免拟合时另行删行。
singular.ok = FALSE # 不允许不可估计的线性依赖项。
)
coefficient_summary <- summary(model_fit)$coefficients
if (!isTRUE(model_fit$converged) || isTRUE(model_fit$boundary) ||
any(!is.finite(coefficient_summary))) {
stop("请先检查模型收敛、分离或不可估计问题。")
}
# 先在系数尺度构造Wald区间,再指数化为OR;截距不列入OR表。
report_terms <- setdiff(rownames(coefficient_summary), "(Intercept)")
or_table <- cbind(
odds_ratio = exp(stats::coef(model_fit)[report_terms]),
exp(stats::confint.default(model_fit, parm = report_terms, level = conf_level))
)
# response返回low=1的概率;link返回对数优势,二者尺度不同。
prediction_sample <- analysis_data[prediction_index, , drop = FALSE]
predicted_log_odds <- stats::predict(
model_fit, newdata = prediction_sample, type = "link"
)
predicted_probability <- stats::predict(
model_fit, newdata = prediction_sample, type = "response"
)
print(table(analysis_data$smoke, analysis_data$low))
print(coefficient_summary)
print(or_table)
print(prediction_sample)
print(predicted_log_odds)
print(predicted_probability)公式 low ~ age + lwt + smoke 表示同时纳入三个变量,结局为 low。binomial(link = "logit") 指定二分类 Logistic 模型,系数表中的 smokeyes 对应吸烟相对于不吸烟。
confint.default() 使用 Wald 近似;直接调用 confint(model_fit) 通常采用轮廓似然方法,得到的区间可能不同。区间方法应与报告一致,提高 conf_level 会改变区间宽度,不会改变回归系数。
2.3.1.4 从原始系数表读到OR
summary(model_fit)$coefficients 实际返回:
先看 smokeyes 这一行,再认识各列:
| R 字段 | 统计含义 | 本例怎样读 |
|---|---|---|
Estimate |
回归系数,位于对数优势尺度 | 吸烟系数0.67076374,指数化后才是OR |
Std. Error |
系数估计的标准误 | 吸烟系数的标准误为0.325877764,描述系数估计的波动 |
z value |
系数除以标准误 | 约2.058,衡量系数偏离0的程度 |
Pr(>\|z\|) |
对系数等于0作双侧Wald检验的P值 | 吸烟项P约0.0396;这是系数检验,不是预测准确率 |
(Intercept) 是截距,参与概率计算。它对应年龄和体重均为0且不吸烟时的对数优势;这个取值组合缺乏本例医学解释,不应把截距指数化后当作某个风险因素的 OR。
指数化及区间计算返回:
这里的 2.5 % 和 97.5 % 是95%置信区间的两端;它们由系数区间指数化得到。以吸烟为例,:在年龄与母亲体重相同的条件下,吸烟组出现低出生体重的优势估计为不吸烟组的1.956倍,95%置信区间约为1.033~3.704。这个调整后 OR 与前面的直接比较回答不同的问题。
age 的 OR 约0.962,按年龄每增加1岁解释;其区间包含1,数据仍与优势不变相容。lwt 的 OR 约0.9879,按母亲体重每增加1磅解释,区间约0.9761~0.9999。解释时要保留原单位;若希望按千克或较大的变化单位报告,应先统一输入尺度或相应换算,不能只改结果标签。
模型里的“调整”仅指纳入了所列变量,并不自动消除其他混杂。各项结果描述条件关联,因果效应需要相应的研究设计和识别假设。
2.3.1.5 把一条真实记录换算成概率
完整代码选取的记录如下,原数据行名为 85:
其母亲年龄为19岁、体重182磅、孕期不吸烟。该记录的观察结局为0,模型使用所有建模记录估计参数,再据此计算这条记录的概率。先得到对数优势:
再通过 转换回概率。这里 ,因此概率约为0.1705。type = "response" 直接返回:
0.1705约为17.1%,对应的是结局 low = 1 的概率。单条观察的实际结局只有0或1,不能用它与预测概率是否接近来评价模型准确率。
这条记录参与了模型拟合,本节展示的是模型怎样计算概率。预测性能应通过适当的内部或外部验证,分别考察区分能力、校准和具体临床用途。相应模型评价专题待上线。
2.3.1.6 何时可以沿用这套解释
本节模型适用于独立观察的二分类结局。连续变量在对数优势尺度上的函数形式要合理,事件与非事件数量应能支持待估参数,不能仅按变量名称的个数判断模型复杂度。重复测量或聚类资料还需处理对象之间的相关性。
如果出现不收敛、系数极大或标准误异常,尤其某些类别完全预测结局时,应先检查类别分离和数据结构。Wald 区间依赖大样本近似,稀疏资料下可能不可靠;即使程序显示收敛,也仍需结合诊断判断估计是否可用。
用于实际预测的输入还应在预定预测时点可获得。本例的 bwt 直接定义 low,若把它加入预测变量,就把结局信息带回了输入。建立临床预测工具前,需要进一步明确目标人群、时点及验证方案。
若结局是连续指标、关心两组均值差,可回到1.5.1 t检验。将 Logistic 回归迁移到自己的数据,使用同编号代码碎片:先提供已编码的二分类数据,再配置变量角色和参考水平。
2.3.1.7 方法与操作来源
- Bland JM, Altman DG. Statistics notes: The odds ratio. BMJ. 2000;320:1468.
- R Core Team. Fitting Generalized Linear Models:分布族、连接函数及拟合。
- R Core Team. Summarizing Generalized Linear Model Fits:系数表及标准误、z值和P值。
- R Core Team. Confidence Intervals for Model Parameters与Predict Method for GLM Fits:区间方法与预测尺度。