逻辑回归中geom_smooth()与手动LOESS拟合的差异及二进制数据处理
二元结局变量与LOESS平滑的正确处理方式
你遇到的核心问题是变换顺序差异,以及普通LOESS直接处理二元0/1数据的局限性。下面详细解释原因和正确做法:
为什么结果不一致?
你的代码里存在两个关键问题:
- 手动拟合的是
chd ~ sbp的普通LOESS(直接对0/1值做线性平滑),之后对预测值做logit变换; chd_odd的构造逻辑错误——你用整体样本的log odds替换个体的0/1值,完全不符合个体水平的log odds定义,导致geom_smooth拟合的是错误的响应变量,自然和手动结果脱节。
LOESS处理二进制数据的正确思路
普通LOESS是为连续响应变量设计的,直接拟合0/1数据会有两个问题:
- 预测值可能超出0-1范围(逻辑上不符合概率定义);
- 忽略二元数据的伯努利分布特性,拟合效率低。
正确的处理方式有两种:
方式1:在Logit尺度做LOESS平滑,再反变换回概率
先把二元结局转换为logit尺度(为避免0/1导致的无穷值,可加微小偏移),用LOESS拟合这个连续的logit值,最后通过plogis()反变换得到符合0-1范围的概率:
set.seed(123) n <- 100 data_mi <- data.frame( sbp = rnorm(n, mean = 130, sd = 15), chd = rbinom(n, size = 1, prob = 0.3) ) # 计算带偏移的logit值,避免0/1导致的无穷大 data_mi$logit_chd <- log( (data_mi$chd + 0.01) / (1 - data_mi$chd + 0.01) ) # 拟合LOESS到logit尺度 loess_logit_fit <- loess(logit_chd ~ sbp, data = data_mi, degree = 1) data_mi$pred_logit <- predict(loess_logit_fit) # 反变换回概率 data_mi$pred_prob <- plogis(data_mi$pred_logit) # 可视化 library(ggplot2) ggplot(data_mi, aes(x = sbp)) + geom_point(aes(y = chd), alpha = 0.6) + geom_line(aes(y = pred_prob), color = "darkred", linewidth = 1) + labs(y = "CHD发病概率", x = "收缩压(SBP)")
方式2:使用广义加性模型(GAM)替代LOESS
GAM专门支持非参数平滑,且可以指定二项式族适配二元数据,是更专业的选择:
library(mgcv) # 拟合GAM模型 gam_fit <- gam(chd ~ s(sbp), data = data_mi, family = binomial) # 预测概率 data_mi$gam_pred_prob <- predict(gam_fit, type = "response") # 可视化 ggplot(data_mi, aes(x = sbp)) + geom_point(aes(y = chd), alpha = 0.6) + geom_line(aes(y = gam_pred_prob), color = "steelblue", linewidth = 1) + labs(y = "CHD发病概率", x = "收缩压(SBP)")
原始结果对比
拟合结果对比图:
Logit变换图:
内容的提问来源于stack exchange,提问作者doraemon
相关产品推荐
相关产品推荐

