如何确定mlr包5折交叉验证中最终所用的训练与测试折?
关于交叉验证中测试折的确定与mlr包的实操说明
嘿,我来帮你理清这两个关于交叉验证(CV)和mlr包的问题~
一、如何确定交叉验证中最终用作测试集的折
首先得明确:标准k折交叉验证的核心逻辑是没有固定的“最终测试折”——我们把数据集均匀分成k份,轮流用其中1份当测试集、剩下k-1份当训练集,跑满k次迭代后,模型的最终性能是这k次结果的平均值。
如果你的目标是用CV完成超参数调优后,得到一个可部署的最终模型,正确的做法是:
- 用k折CV找到最优超参数
- 拿全部训练数据(而非某几折)来训练这个最优参数的模型——这样能最大化利用数据,提升模型的泛化能力
- 要是你需要一个独立的测试集来评估最终模型,那得在CV开始前就把数据集拆成「训练集」和「独立测试集」,k折CV只在训练集内部进行,最后用独立测试集来验证最终模型的效果
二、mlr包5折CV中区分训练/测试折的实操
你提到用tuned_model$resampling$train.inds和test.inds只能拿到全部5折的索引,这是因为tuneParams函数在超参数调优时,会完整执行5次CV迭代,所以这两个列表分别存储了每一轮迭代对应的训练、测试样本索引。
1. 查看单轮CV的训练/测试索引
如果你想查看某一轮迭代的训练和测试样本,可以直接索引列表的对应位置,比如查看第1轮的情况:
# 第1轮CV的训练样本索引 tuned_model$resampling$train.inds[[1]] # 第1轮CV的测试样本索引 tuned_model$resampling$test.inds[[1]]
列表的每个元素就对应一轮CV的训练/测试集合。
2. 训练最终模型的正确姿势
调优完超参数后,不需要挑选某一折来训练最终模型,用全部数据训练才是最优选择:
# 用调优后的参数更新学习器 model_rf = setHyperPars(learner = learner, par.vals = tuned_model$x) # 用完整的mtcars数据训练最终模型 set.seed(1) final_model = train(learner = model_rf, task = regr_task)
3. 若需保留独立测试集的做法
如果你必须用一个独立的测试集来验证最终模型,得提前拆分数据,把CV的范围限制在训练集内:
# 先拆分训练集(80%)和测试集(20%) set.seed(1) train_idx = sample(1:nrow(mtcars), 0.8 * nrow(mtcars)) train_data = mtcars[train_idx, ] test_data = mtcars[-train_idx, ] # 基于训练集创建任务 regr_task_train = makeRegrTask(data = train_data, target = "hp") # 在训练集上执行5折CV调优 set.seed(1) tuned_model = tuneParams(learner = learner, task = regr_task_train, resampling = rdesc, measures = list(meas, setAggregation(meas, train.mean)), par.set = par_set, control = ctrl, show.info = FALSE) # 用调优后的参数在训练集上训练最终模型 model_rf = setHyperPars(learner = learner, par.vals = tuned_model$x) final_model = train(learner = model_rf, task = regr_task_train) # 用独立测试集评估模型性能 predictions = predict(final_model, newdata = test_data) performance(predictions, measures = rmse)
这样就能清晰区分用于CV调优的训练集,和最终用来评估的独立测试集了。
内容的提问来源于stack exchange,提问作者lodomi




