R Academy · 课时

使用 rsample 进行重抽样与交叉验证

使用 k 折 CV、Bootstrap 和嵌套重抽样评估模型

第 4 / 4 课13 个步骤

使用 rsample 进行重抽样与交叉验证 是 CoddyKit 上的免费 R Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。

为什么要重抽样?

单次训练/测试划分对模型性能的估计可能不稳定——测试集中包含哪些观测可能只是运气好或运气差。重抽样会重复这一过程多次,从而稳定、可靠地估计模型对新数据的泛化能力。

library(rsample)

# Single split — performance estimate depends heavily
# on which 20% ended up as test data
split <- initial_split(mtcars, prop = 0.8)
train <- training(split)
test  <- testing(split)

cat('Train:', nrow(train), '| Test:', nrow(test))

initial_split()

initial_split(data, prop, strata)会将数据随机划分为训练集和测试集。使用strata按某一列进行分层(例如响应变量),可以确保两个分区中的类别比例保持平衡。

library(rsample)

# Stratified split by outcome variable
split <- initial_split(ames, prop = 0.8, strata = Sale_Price)

train <- training(split)
test  <- testing(split)

cat('Train rows:', nrow(train))
cat('Test rows:', nrow(test))

vfold_cv() — K 折交叉验证

vfold_cv(data, v = 10)会创建 10 个折。数据被分成 10 个大小相等的部分,其中 9 个用于训练,1 个用于验证,并轮流使用所有折。这样可以得到 10 个性能估计值,再将它们取平均以获得稳定的指标。

folds <- vfold_cv(housing_train, v = 10, strata = price)

# Each fold is a split object
print(folds)

# Inspect one fold
fold_1 <- folds$splits[[1]]
train_1 <- analysis(fold_1)
val_1   <- assessment(fold_1)
cat('Fold 1 — Train:', nrow(train_1), '| Val:', nrow(val_1))

fit_resamples()

fit_resamples(workflow, resamples, metrics)会在每个训练折上拟合工作流,并在验证折上评估,同时收集所请求的指标。它会返回一个结果 tibble,您可以使用collect_metrics()对其进行汇总。

library(tune)

folds <- vfold_cv(housing_train, v = 10)

res <- fit_resamples(
  wf,       # your workflow
  folds,
  metrics = metric_set(rmse, rsq)
)

# Average metric across all 10 folds
collect_metrics(res)

collect_metrics()

collect_metrics(resample_result)会返回一个整洁的 tibble,汇总所有折上的模型性能。mean列是指标均值,std_err是标准误,可帮助您了解估计值的方差。

metrics_df <- collect_metrics(res)
print(metrics_df)

#   .metric .estimator   mean  n std_err .config
#   rmse    standard    24500  10   1200  Preprocessor1_Model1
#   rsq     standard    0.882  10  0.012  Preprocessor1_Model1

# Pull a single metric
collect_metrics(res) |>
  dplyr::filter(.metric == 'rmse') |>
  dplyr::pull(mean)

bootstraps() — 自助法重抽样

bootstraps(data, times = 25)会创建自助法样本:每个样本都以有放回抽样的方式从原始数据集中随机抽取,样本大小与原数据集相同。未被抽到的观测组成袋外(OOB)评估集。与 k 折相比,自助法的方差更高,但适用于较小的数据集。

boot_samples <- bootstraps(housing_train, times = 25, strata = price)

print(boot_samples)

# Average proportion of unique rows in each bootstrap
mean(sapply(boot_samples$splits, function(s) {
  nrow(analysis(s)) / nrow(housing_train)
}))

蒙特卡洛交叉验证

mc_cv(data, prop, times)会创建times个随机划分,每次使用prop比例的数据进行训练。与 k 折不同,同一个观测可能多次出现在验证集中。当您需要的重抽样迭代次数多于 k 折所能提供的次数时,这种方法非常有用。

mc_splits <- mc_cv(housing_train, prop = 0.8, times = 20)

res_mc <- fit_resamples(
  wf,
  mc_splits,
  metrics = metric_set(rmse, rsq)
)

collect_metrics(res_mc)

tune_grid() — 超参数搜索

当工作流包含tune()占位符时,可以使用tune_grid(wf, resamples, grid)在超参数值网格上进行搜索。每种组合都会在所有折上进行评估,最后使用select_best()选择最佳配置。

rf_spec <- rand_forest(mtry = tune(), trees = tune()) |>
  set_engine('ranger') |>
  set_mode('regression')

wf_tune <- workflow() |> add_recipe(rec) |> add_model(rf_spec)

grid <- grid_regular(mtry(range = c(2, 10)), trees(range = c(100, 500)), levels = 3)

tune_res <- tune_grid(wf_tune, resamples = folds, grid = grid)
collect_metrics(tune_res) |> head()

select_best() 和 finalize_workflow()

调参后,select_best(tune_res, metric)会选出平均指标最佳的超参数组合。finalize_workflow(wf, best_params)会创建一个新工作流,用这些值替换tune()。

best_params <- select_best(tune_res, metric = 'rmse')
print(best_params)

# Substitute best values into the workflow
final_wf <- finalize_workflow(wf_tune, best_params)

# Fit on all training data, evaluate on test
final_fit <- last_fit(final_wf, split)
collect_metrics(final_fit)

嵌套交叉验证

如果还要调节超参数,并且需要真正无偏的评估,请使用嵌套交叉验证:外层循环用于估计性能,内层循环用于调参。在 rsample 中,创建一个外层vfold_cv,并在每个外层折内使用内层折进行调参。

# Outer folds for unbiased evaluation
outer_folds <- vfold_cv(housing_train, v = 5)

# For each outer fold, tune on the inner training data
res_nested <- tune_grid(
  wf_tune,
  resamples = outer_folds,
  grid = 10,  # 10 random configurations
  metrics = metric_set(rmse)
)

collect_metrics(res_nested)

比较重抽样策略

每种重抽样策略都有取舍。请根据数据集大小和计算预算进行选择:

  • k 折(v=10):偏差低、方差适中。大多数问题的默认选择。
  • 自助法:适用于非常小的数据集;方差高于 k 折。
  • 蒙特卡洛交叉验证:更加灵活;适合时间受限的调参。
  • 重复 k 折:方差更低;在计算资源充足时使用。
# Repeated k-fold: 5-fold repeated 3 times = 15 models fitted
repeated_folds <- vfold_cv(housing_train, v = 5, repeats = 3)

res_rep <- fit_resamples(
  wf,
  repeated_folds,
  metrics = metric_set(rmse, rsq)
)

collect_metrics(res_rep)

快速检查

将collect_metrics()应用于fit_resamples()的结果时,会返回什么?

重抽样回顾

使用 rsample 进行重抽样和交叉验证的要点:

  • initial_split(data, prop, strata)会创建分层的训练/测试划分。
  • vfold_cv(data, v = 10)会创建 k 折交叉验证折。
  • bootstraps(data, times)会为小型数据集创建自助法样本。
  • fit_resamples(wf, folds, metrics)会在所有折上评估工作流。
  • collect_metrics()会使用均值和标准误汇总结果。
  • tune_grid()搜索超参数;select_best()选出最佳方案。
  • finalize_workflow()加last_fit()完成从调参到部署的流程。
# Full rsample pipeline
split  <- initial_split(data, prop = 0.8, strata = y)
train  <- training(split)
folds  <- vfold_cv(train, v = 10)

res    <- fit_resamples(wf, folds, metrics = metric_set(rmse, rsq))
collect_metrics(res)

# After tuning
best   <- select_best(tune_res, metric = 'rmse')
fin_wf <- finalize_workflow(wf_tune, best)
last_fit(fin_wf, split) |> collect_metrics()
免费开始

用 AI 导师学习 R — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
43
课程
159

常见问题解答

「使用 rsample 进行重抽样与交叉验证」课时是免费的吗?

是的 — 「使用 rsample 进行重抽样与交叉验证」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。

「使用 rsample 进行重抽样与交叉验证」这节课中我会学到什么?

使用 k 折 CV、Bootstrap 和嵌套重抽样评估模型 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 R Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「使用 rsample 进行重抽样与交叉验证」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 R Academy 课中编写并运行代码吗?

能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用 recipes 进行特征工程
  2. 使用 parsnip 定义模型规格
  3. 工作流:组合配方与模型
  4. 使用 rsample 进行重抽样与交叉验证
← 返回 R Academy