使用tidymodels的fit_resamples做时间序列交叉验证遇异常问题
tidymodels时间序列交叉验证报错解决
问题现象
运行时间序列交叉验证代码时,出现警告:
Warning message: More than one set of outcomes were used when tuning. This should never happen. Review how the outcome is specified in your model.
同时resamples对象的.metrics和.predictions仅第一个元素有数据,其余均为空。
错误原因
核心问题在于配方绑定了单个拆分数据集:
- 代码中
recipe(value ~ year_month, splits$splits[[1]])将配方直接基于第一个交叉验证拆分的子集构建,导致后续其他拆分无法正确应用该配方——配方的元数据(如变量类型、统计量)仅来自第一个子集,无法适配全局数据。 - 这种绑定会让
fit_resamples在后续迭代中无法正确识别统一的结果变量,进而触发警告,且只有第一个拆分能正常生成指标和预测值。
修正步骤
- 独立定义配方:不要将配方与单个拆分绑定,直接基于原始数据集定义通用配方,确保所有交叉验证拆分都能应用一致的预处理逻辑。
- 调整滑动窗口参数(可选):原代码
skip=23会导致交叉验证拆分数量极少(仅1个有效拆分),可根据需求调整skip值以获得更多验证样本。
修正后完整代码
library(tidyverse) library(tidymodels) # 生成模拟数据 df <- data.frame( year_month = seq(as.Date("2020-01-01"), as.Date("2024-03-01"), "month"), value = sample(1:100, length(seq(as.Date("2020-01-01"), as.Date("2024-03-01"), "month"))) ) # 创建滑动窗口交叉验证拆分,调整skip为1以生成多个验证样本 splits <- sliding_window(df, lookback = Inf, skip=1, assess_start = 1, assess_stop = 1, complete = TRUE) # 定义ARIMA模型规范 model_spec <- arima_reg() %>% set_engine("auto_arima") # 独立定义时间序列配方,不绑定到单个拆分 ts_recipe <- recipe(value ~ year_month, data = df) # 运行交叉验证拟合 resamples <- fit_resamples( object = model_spec, preprocessor = ts_recipe, resamples = splits, control = control_resamples(save_pred = TRUE) ) # 查看交叉验证指标 collect_metrics(resamples) # 查看所有预测值 resamples %>% select(id, .predictions) %>% unnest(.predictions)
关键说明
- 独立配方确保每个交叉验证拆分都能正确执行预处理,避免了变量识别问题。
- 调整
skip=1后,每次滑动窗口仅前进1个月,原数据共51个月,会生成27个有效拆分(初始训练集23个月,验证1个月,之后每次训练集递增1个月,验证下一个月),能更充分地验证模型稳定性。
内容的提问来源于stack exchange,提问作者Nick M
相关产品推荐
相关产品推荐

