如何对0-1分布数据的glm回归进行bootstrap、估算95%置信区间并绘图
基于Bootstrap的二项分布GLM回归置信区间绘图方案
你目前处理0-1分布数据集的GLM回归,已通过ggplot2::geom_smooth完成基础绘图,原代码及结果如下:
library(ggplot2) set.seed(123) df <- transform(data.frame(Conc=runif(200, min=200, max=1000)), AE=rbinom(200, 1, prob=plogis((Conc - 600)/100))) ggplot(df, aes(x = Conc, y = AE)) + geom_jitter(height = 0.05, alpha = 0.5) + geom_smooth(method = "glm", formula = y ~ log(x), method.args = list(family = "binomial"), color = "grey10")

你尝试用Bootstrap估算95%置信区间但未成功,之前的代码存在两个核心问题:
- 误用线性模型
lm替代二项分布广义线性模型glm(family = binomial),和基础绘图的模型不匹配 - 直接基于回归系数绘制直线,但二项GLM在原始0-1尺度上是非线性的,应该通过Bootstrap样本拟合模型后生成预测值来计算置信区间
修正后的完整解决方案
1. 加载依赖包
library(ggplot2) library(dplyr) library(purrr) set.seed(123) # 固定随机种子,保证结果可复现
2. 拟合Bootstrap模型并生成预测值
nboot <- 1000 # Bootstrap重复次数 # 定义Bootstrap函数:输入采样后的数据集,返回该样本的预测结果 boot_pred <- function(sample_df) { # 拟合正确的二项GLM模型 model <- glm(AE ~ log(Conc), data = sample_df, family = binomial) # 生成覆盖原始Conc范围的连续x序列,用于预测 new_x <- tibble(Conc = seq(min(df$Conc), max(df$Conc), length.out = 100)) # 预测响应概率(type="response"返回原始尺度的概率值) new_x$pred_prob <- predict(model, newdata = new_x, type = "response") return(new_x) } # 执行Bootstrap采样与预测 boot_results <- map_dfr(seq_len(nboot), function(.x) { df %>% slice_sample(prop = 1, replace = TRUE) %>% # 有放回采样 boot_pred() %>% mutate(boot_id = .x) # 标记每个Bootstrap样本的ID })
3. 计算95%置信区间并绘图
# 对每个Conc值,计算预测概率的2.5%和97.5%分位数,得到95%置信区间 ci_df <- boot_results %>% group_by(Conc) %>% summarise( lower = quantile(pred_prob, 0.025), upper = quantile(pred_prob, 0.975), .groups = "drop" ) # 绘制最终图形 ggplot(df, aes(x = Conc, y = AE)) + geom_jitter(height = 0.05, alpha = 0.5) + # 原始数据点(抖动避免重叠) geom_ribbon(data = ci_df, aes(y = NULL, ymin = lower, ymax = upper), fill = "forestgreen", alpha = 0.2) + # Bootstrap置信区间带 geom_smooth(method = "glm", formula = y ~ log(x), method.args = list(family = "binomial"), color = "grey10", linewidth = 1) + # 原始GLM拟合曲线 theme_bw() # 简洁主题
额外说明
如果需要查看所有Bootstrap拟合的曲线,可在绘图代码中添加以下图层:
geom_line(data = boot_results, aes(group = boot_id), color = "forestgreen", alpha = 0.1)
内容的提问来源于stack exchange,提问作者Dylan Li
相关产品推荐
相关产品推荐

