小样本时间序列2年预测:ARIMA应用问题及替代方案咨询
先帮你梳理下当前ARIMA代码里的核心问题,再给你推荐几个适合小数据集的预测方法:
1. 你的ARIMA代码核心错误
你的数据第一个观测日期是2016-03-12(对应structure(c(16801)),但创建时间序列对象时,你指定了start=c(2016,01)——这会让R误以为第一个数据点是2016年1月的观测,直接导致时间序列的索引和实际日期完全错位。auto.arima会基于错误的时间索引去识别季节性和趋势,模型拟合自然会出问题,预测结果也就不可靠了。
另外,你的数据正好是48个月度观测(4年),end=c(2019,12)是对的,但起始点必须修正为start=c(2016,3)。
2. 修正后的ARIMA代码
先把数据转换成正确的时间序列对象再建模:
# 先将你的原始数据转为data.frame(假设未命名为df) df <- structure(list(BelegDat = structure(c(16801, 16832, 16861, 16892, 16922, 16953, 16983, 17014, 17045, 17075, 17106, 17136, 17167, 17198, 17226, 17257, 17287, 17318, 17348, 17379, 17410, 17440, 17471, 17501, 17532, 17563, 17591, 17622, 17652, 17683, 17713, 17744, 17775, 17805, 17836, 17866, 17897, 17928, 17956, 17987, 18017, 18048, 18078, 18109, 18140, 18170, 18201, 18231), class = "Date"), Value = c(37, 28, 37, 47, 37, 28, 37, 37, 19, 37, 37, 28, 40, 30, 40, 50, 40, 30, 40, 40, 20, 40, 40, 30, 30, 40, 30, 30, 40, 30, 30, 50, 30, 50, 20, 20, 60, 20, 60, 40, 20, 10, 40, 20, 20, 10, 44, 33)), row.names = c(NA, -48L), class = "data.frame") # 创建正确的时间序列对象 myts <- ts(df$Value, start = c(2016, 3), end = c(2019, 12), frequency = 12) # 拟合ARIMA模型并预测 fit <- auto.arima(myts) pred <- forecast(fit, h = 24) plot(pred)
修正后时间序列索引和实际日期匹配,auto.arima能正确识别季节性模式,预测结果会更合理。
适合小数据集的其他预测方法
你只有48个观测(4年数据),下面这些方法对小样本更友好:
1. 指数平滑模型(ETS)
ETS模型专门针对时间序列设计,不依赖复杂统计假设,能自动识别趋势和季节性,对小数据适配性很强:
library(forecast) # 拟合ETS模型 fit_ets <- ets(myts) # 预测未来24个月 pred_ets <- forecast(fit_ets, h = 24) plot(pred_ets)
可以对比ARIMA和ETS的预测结果,选更贴合你数据模式的那个。
2. Facebook Prophet
Prophet是Facebook开发的工具,对缺失值、季节性和异常值鲁棒性极强,即使数据量不大也能给出稳定的预测:
library(prophet) # 转换为Prophet要求的格式(ds=日期,y=值) df_prophet <- df %>% rename(ds = BelegDat, y = Value) # 拟合模型 fit_prophet <- prophet(df_prophet) # 创建未来24个月的日期序列 future <- make_future_dataframe(fit_prophet, periods = 24, freq = "month") # 生成预测 pred_prophet <- predict(fit_prophet, future) # 可视化预测结果 plot(fit_prophet, pred_prophet) # 查看季节性分解细节 prophet_plot_components(fit_prophet, pred_prophet)
3. 季节性朴素预测(Seasonal Naive)
如果你的数据有明显的季节性(比如每年同月数值相近),这个简单方法非常有效——直接用上一年同月的值作为预测值:
fit_snaive <- snaive(myts) pred_snaive <- forecast(fit_snaive, h = 24) plot(pred_snaive)
它计算快、解释性强,适合强季节性但无明显趋势的数据。
4. 移动平均模型
如果数据没有明显趋势和季节性,可以尝试用最近几个月的平均值预测未来:
# 3个月移动平均 fit_ma <- ma(myts, order = 3) # 生成预测 pred_ma <- forecast(ts(fit_ma, start = c(2016,3), frequency=12), h=24) plot(pred_ma)
最后建议你先通过ggseasonplot(myts)或decompose(myts)检查数据的季节性和趋势,再选择最合适的模型。同时可以用样本内验证(比如用前3年数据训练,预测第4年并对比实际值)来评估模型准确性。
内容的提问来源于stack exchange,提问作者Ivan M.




