R语言fpp3时间序列交叉验证报错 非CV方法正常如何解决
问题根因
- 无参数调用
stretch_tsibble()时,函数默认从序列第一个观测点开始生成滚动训练集,最靠前的几折训练集仅包含个位数到十几个月的样本,完全达不到模型拟合的最小数据量要求。 - 样本量不足直接触发所有警告和异常结果:
- 带季节项的TSLM、季节朴素模型至少需要1个完整年度周期(12个月)的样本才能估计季节系数,样本不足时会出现秩缺陷、自动删除回归项的警告,拟合结果完全失真
- ETS、ARIMA类模型需要至少2-3个完整周期(24-36个月)的样本才能稳定估计参数,样本量过小时直接抛出"数据不足无法建模"的错误,失败的拟合结果会严重干扰整体精度计算
- 前几折的异常拟合结果拉偏了整体交叉验证精度,才会出现RMSE远高于固定训练集结果的情况
- 固定2022年2月为训练集截止点时,训练样本量足够覆盖所有模型的最小数据要求,因此无报错、结果稳定。
修正方案
核心是给滚动交叉验证设置足够长的初始训练窗口,月度数据建议初始窗口设为5年(60个月),可同时设置滚动步长为1个月平衡计算量和评估可靠性,修正后的完整代码如下:
library(tidyverse) library(fpp3) # 数据加载与预处理 All_Employees <- read_csv('All_Employees.csv', col_select = c(Label, Value), show_col_types = FALSE) All_Employees <- All_Employees %>% rename(Month = Label, Total_Employees = Value) All_Employees <- All_Employees %>% mutate(Month = yearmonth(Month)) %>% as_tsibble(index = Month) # 生成交叉验证滚动数据集:初始训练窗口60个月,每次扩展1个月 All_Employees_cv <- All_Employees %>% stretch_tsibble(.init = 60, .step = 1) # 批量拟合模型 model_fits <- All_Employees_cv %>% model( linear = TSLM(Total_Employees ~ trend() + season()), Exponential = TSLM(log(Total_Employees) ~ trend() + season()), Arima = ARIMA(Total_Employees ~ trend() + season()), Ets = ETS(Total_Employees), Mean = MEAN(Total_Employees), Naive = NAIVE(Total_Employees), SNaive = SNAIVE(Total_Employees), Drift = SNAIVE(Total_Employees ~ drift()) ) # 计算3步预测精度 cv_accuracy <- model_fits %>% forecast(h = 3) %>% accuracy(All_Employees) %>% arrange(RMSE)
补充说明
- 初始窗口长度不要低于24个月(2个完整年度周期),否则季节类模型的估计结果不具备参考性
- 若运行中仍有个别拟合警告,可使用
fable包内置的容错拟合逻辑,自动跳过单折拟合失败的情况,不会中断整体计算 - 时间序列交叉验证的结果是多期滚动测试的平均误差,天然会比单次固定训练集划分的测试误差高,属于正常现象,两类结果的RMSE差异在30%以内均属合理范围
- 提示中的未使用连接警告是远程文件读取后的连接回收提示,不影响计算结果,无需额外处理
内容的提问来源于stack exchange,提问作者Russ Conte
相关产品推荐
相关产品推荐

