基于mlr3的自定义滚动窗口嵌套重采样问题求助
解决mlr3嵌套滚动窗口交叉验证的行ID不存在错误
问题背景
自mlr3tuning v0.17.2版本起,AutoTuner类支持使用自定义实例化重采样。尝试构建嵌套滚动窗口交叉验证(内重采样调优超参数,外重采样评估模型)时,运行代码出现如下错误:
Error: Train set 3 of inner resampling 'custom' contains row ids not present in task 'data_': {91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120}
错误原因
你预先基于完整数据集实例化了内重采样custom,其训练集包含全量数据的行ID(比如第3个训练集对应month3和month4的行91-120)。但在外重采样的第一轮中,任务被子集化为仅包含month1-3的外训练集(行1-90),此时内重采样引用的91-120行在当前子任务中不存在,因此触发错误。
修正方案
不要预先实例化内重采样,而是使用mlr3内置的rolling_window重采样(或动态生成适配子任务的自定义重采样),让内重采样在外重采样的每一轮中,基于当前的外训练集自动生成适配的划分。
完整修正代码
library(mlr3) library(mlr3tuning) library(mlr3pipelines) library(mlr3learners) # 构建任务 task = tsk("iris") task_ = task$clone() data_ = task_$data() data_ = cbind(data_, monthid = c(rep(1, 30), rep(2, 30), rep(3, 30), rep(4, 30), rep(5, 30))) task = as_task_classif(data_, target = "Species") task$set_col_roles("monthid", "order") # 设置monthid为排序依据,供滚动窗口使用 # 内滚动窗口重采样:不预先实例化,自动适配子任务 inner_rsmp = rsmp("rolling_window", train_size = 2, test_size = 1, gap = 0) # train_size=2:每次用2个时间块训练;test_size=1:用1个时间块测试;gap=0:训练和测试块无间隔 # 外滚动窗口重采样:基于完整任务实例化 outer_rsmp = rsmp("rolling_window", train_size = 3, test_size = 1, gap = 0) outer_rsmp$instantiate(task) # 构建管道学习器 graph = po("removeconstants", id = "removeconstants_1", ratio = 0) %>% po("branch", options = c("nop_prep", "yeojohnson", "pca", "ica"), id = "prep_branch") %>% gunion(list(po("nop", id = "nop_prep"), po("yeojohnson"), po("pca", scale. = TRUE), po("ica"))) %>% po("unbranch", id = "prep_unbranch") %>% po("learner", learner = lrn("classif.rpart")) graph_learner = as_learner(graph) # 定义搜索空间 search_space = ps( prep_branch.selection = p_fct(levels = c("nop_prep", "yeojohnson", "pca", "ica")), pca.rank. = p_int(2, 6, depends = prep_branch.selection == "pca"), ica.n.comp = p_int(2, 6, depends = prep_branch.selection == "ica"), yeojohnson.standardize = p_lgl(depends = prep_branch.selection == "yeojohnson") ) # 构建AutoTuner:传入未实例化的内重采样 at = auto_tuner( method = "random_search", learner = graph_learner, resampling = inner_rsmp, measure = msr("classif.acc"), search_space = search_space ) # 执行嵌套重采样 rr = resample(task, at, outer_rsmp, store_models = TRUE)
关键修改说明
- 设置排序列:给任务添加
order角色的monthid,让滚动窗口重采样按时间顺序划分数据。 - 使用内置滚动窗口重采样:
rsmp("rolling_window")无需手动构建训练/测试集,会自动根据train_size、test_size参数按时间顺序划分,且在外重采样的子任务中自动适配。 - 内重采样不预先实例化:让AutoTuner在外重采样的每一轮中,基于当前的外训练集(子任务)动态实例化内重采样,确保所有行ID都存在于当前任务中。
内容的提问来源于stack exchange,提问作者Mislav Sagovac
相关产品推荐
相关产品推荐

