Tidymodels重采样预测方法结果差异及RMSE置信区间求解
一、三条指标计算语句的差异解析
先修正你代码中的小错误:collect_predictions()不需要重复传入resampd(管道已经传递了该对象),正确的三条语句应该是:
# 语句1 resampd %>% collect_predictions(summarize = TRUE) %>% metrics(mass, .pred) # 语句2 resampd %>% collect_predictions(summarize = FALSE) %>% metrics(mass, .pred) # 语句3 resampd %>% collect_metrics()
三者的核心差异在于计算指标时的聚合逻辑不同:
语句3(
collect_metrics()):这是tidymodels官方推荐的标准重采样指标计算方式。它会先针对每个重采样样本(这里是50个bootstrap样本)单独计算RMSE,最后返回这50个RMSE的平均值和标准差。本质是「按折计算指标 → 对指标取平均」,反映的是模型在不同重采样样本上的平均表现。语句2(
summarize = FALSE):summarize=FALSE会保留所有重采样过程中生成的预测值——包括同一个原始观测在不同bootstrap样本中被多次预测的结果。之后直接对**所有预测值(总数量为原始数据行数×重采样次数)**计算全局RMSE。这种方式没有区分不同重采样样本的边界,把所有预测值混在一起计算,结果和按折平均的逻辑完全不同。语句1(
summarize = TRUE):summarize=TRUE会先对同一个原始观测的所有预测值(来自不同bootstrap样本)取平均值,得到每个原始观测的唯一平均预测值,再基于原始真实值和这个平均预测值计算RMSE。这种逻辑是「先聚合同一观测的多次预测 → 再算全局指标」,结果自然和前两种都有差异。
二、RMSE置信区间的正确计算方法
你当前的思路(按重采样折计算RMSE,再求置信区间)是正确的,但可以用tidymodels原生工具更规范地实现,同时适配bootstrap的特性:
方法1:使用tidymodels原生的百分位数置信区间(推荐)
bootstrap重采样的置信区间通常用百分位数法更合适,而非正态近似:
# 提取每个重采样折的RMSE fold_rmse <- resampd %>% collect_metrics() %>% filter(.metric == "rmse") # 计算百分位数置信区间(默认95%置信水平) int_pctl(fold_rmse, .estimate)
方法2:正态近似置信区间(你的实现优化)
如果你倾向于使用正态近似的置信区间,可以简化代码,同时确保只提取RMSE指标:
fold_rmse <- resampd %>% collect_metrics() %>% filter(.metric == "rmse") %>% pull(.estimate) # 正态近似置信区间 confintr::ci_mean(fold_rmse) # 同时计算均值 mean(fold_rmse)
注意:bootstrap场景下,百分位数法的置信区间更贴合bootstrap的抽样特性,结果也更稳健,优先推荐方法1。
内容的提问来源于stack exchange,提问作者Jeff

