如何用Bootstrap输出评估K折交叉验证(K=5)的准确率?
问题
我研究该问题已有一段时间,仍不清楚如何利用Bootstrap输出评估K折交叉验证(K=5)的准确率。我已正确实现两者的代码,能得到K=5交叉验证和Bootstrap的输出,但不了解理论层面的关联逻辑。我知道K折交叉验证给出模型的平均测试预测准确率,Bootstrap给出标准误差,但不确定该标准误差如何与K折交叉验证结合使用,仅能想到可能和逻辑回归模型的标准误差做对比,但这只是我的猜测。
另外,Bootstrap的索引B应如何设置?训练集有450个观测值,测试集有180个观测值。
代码实现
# 拟合逻辑回归模型 log.fit <- glm(highcrime ~ density+prbpris+prbarr+polpc, data = crime, family = "binomial") summary(log.fit) # 定义分类错误率成本函数 cost.fn <- function(r, pi = 0) mean(abs(r-pi) > 0.5) # 不同K值的交叉验证 cv.glm(crime,log.fit,cost=cost.fn)$delta[1] # 默认留一法 cv.glm(crime,log.fit,cost=cost.fn, K=3)$delta[1] cv.glm(crime,log.fit,cost=cost.fn, K=5)$delta[1] cv.glm(crime,log.fit,cost=cost.fn, K=10)$delta[1] cv.glm(crime,log.fit,cost=cost.fn, K=20)$delta[1] # Bootstrap估计系数标准误差 boot.fn = function(data, index) { logit.fit <- glm(highcrime ~ density+prbpris+prbarr+polpc, data = data, family = "binomial", subset=index) return(coef(logit.fit)) } set.seed(10) # 修正:原代码data参数应为crime而非Default,否则会报错 boot(crime, boot.fn, 200)
输出结果
# 逻辑回归模型摘要 Call: glm(formula = highcrime ~ density + prbpris + prbarr + polpc, family = "binomial", data = crime) Deviance Residuals: Min 1Q Median 3Q Max -2.15233 -0.79314 -0.01228 0.75161 2.04665 Coefficients: Estimate Std. Error z value Pr(>|z|) (Intercept) -2.4275 0.5939 -4.088 4.36e-05 *** density 2.1346 0.2287 9.333 < 2e-16 *** prbpris 2.0586 1.1908 1.729 0.083849 . prbarr -3.3042 0.8720 -3.789 0.000151 *** polpc 162.4758 55.0382 2.952 0.003157 ** Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 (Dispersion parameter for binomial family taken to be 1) Null deviance: 873.37 on 629 degrees of freedom Residual deviance: 599.10 on 625 degrees of freedom AIC: 609.1 Number of Fisher Scoring iterations: 6 # K=5交叉验证的分类错误率 > cv.glm(crime,log.fit,cost=cost.fn, K=5)$delta[1] [1] 0.2444444 # Bootstrap系数估计结果 Call: boot(data = crime, statistic = boot.fn, R = 200) Bootstrap Statistics : original bias std. error t1* -2.427495 -0.02408247 0.5500529 t2* 2.134586 0.01427247 0.2267037 t3* 2.058553 0.06418547 1.1090652 t4* -3.304248 -0.17618726 0.8482598 t5* 162.475758 20.89146943 56.7783311
解答
1. Bootstrap与K折交叉验证的关联及结合方式
你当前的代码实现了两个不同的目标:
- K折交叉验证:用来估计模型的泛化错误率(这里是分类错误率,值为0.244,对应准确率为75.6%),反映模型在未见过的数据上的预测能力。
- Bootstrap:用来估计模型系数的标准误差,这是对
glm输出中Std. Error的补充——glm的标准误差基于渐近正态假设,而Bootstrap是无分布假设的,当数据不符合正态性时,Bootstrap结果更可靠。
如何结合两者评估CV准确率?
如果你想评估K折CV得到的准确率的可靠性(即这个平均准确率的变异程度),需要调整Bootstrap的统计量,改为每次Bootstrap抽样后执行K折CV并记录准确率,示例代码如下:
# 定义Bootstrap统计量:计算单次Bootstrap样本的K=5 CV准确率 boot_cv_fn <- function(data, index) { boot_data <- data[index, ] cv_result <- cv.glm(boot_data, glm(highcrime ~ density+prbpris+prbarr+polpc, data=boot_data, family="binomial"), cost=cost.fn, K=5)$delta[1] return(1 - cv_result) # 返回准确率(1-错误率) } set.seed(10) # 执行Bootstrap,B=1000 boot_cv_result <- boot(crime, boot_cv_fn, 1000) # 查看结果:original是原数据的CV准确率,std. error是CV准确率的标准误差 boot_cv_result
得到的std. error就是CV准确率的变异程度,值越小说明CV结果越稳定,也可以用它来构建准确率的置信区间(如95%置信区间=original ± 1.96*std.error)。
与glm标准误差的对比
你之前的猜测是合理的:Bootstrap给出的系数标准误差可以和glm的Std. Error对比。比如你的polpc系数,glm给出的标准误差是55.04,Bootstrap给出的是56.78,差异很小,说明渐近正态假设在这里适用;如果差异很大,说明模型的系数估计可能不符合正态性,此时Bootstrap的结果更可信。
2. Bootstrap的B值(即R参数)设置建议
- 基本原则:B越大,标准误差的估计越稳定,但计算时间越长。
- 针对你的样本量:训练集有450个观测值,属于中等样本量,建议设置B=1000作为最小值,B=2000-5000会更可靠。你当前用的B=200,估计结果波动较大,不够稳定。
- 特殊情况:如果是小样本(n<200),需要更大的B(如5000);如果计算资源有限,B=500也可以接受,但优先保证B≥1000。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

