如何在R中反向移动时间序列预测区间以检验其合理性?
反向预测(回测)检验预测区间的简便方法
嘿,这个需求太实用了——用回测(也就是反向预测过去时段)来验证预测区间的合理性,不用每次手动切割数据集确实能省不少事!结合你用的forecast包,给你两个简便的方案:
方法一:用tsCV()自动做时间序列交叉验证
forecast包自带的tsCV()函数就是专门干这个的!它会自动帮你完成滚动窗口的拟合与预测,不需要手动写循环切数据。核心思路是:用每一段历史数据拟合模型,预测接下来的1步(或多步),然后把所有预测结果和实际值对比,就能检验预测区间的覆盖效果。
举个适配你代码的例子:
library(forecast) # 先把数据转成时间序列对象(如果还不是的话) ts_data <- ts(dat1$V2) # 自定义一个拟合+预测的函数,返回带区间的预测结果 arima_forecast_func <- function(y, h) { # 完全复用你原有的Arima拟合逻辑 fit <- Arima(log(y), order = c(1, 1, 1), include.constant = TRUE) # 返回h步预测结果(包含区间) forecast(fit, h = h) } # 执行交叉验证:h=1表示每次预测1步,你也可以改成30步之类的多步预测 cv_results <- tsCV(ts_data, arima_forecast_func, h = 1) # 后续可以统计覆盖概率:看实际值落在预测区间内的比例是否符合预期(比如95%置信区间应该接近95%) # 如果你要可视化,可以提取每个预测的上下限,和实际值对比
方法二:手动滚动预测(更灵活可控)
如果你需要更精细的控制(比如指定回测的时间段、调整窗口大小),可以写个简化的循环,比手动反复切割数据集要高效得多:
library(forecast) ts_data <- ts(dat1$V2) N <- length(ts_data) # 设定回测的起始点:比如用前19个数据预测第20个,一直到用前N-1个预测第N个 start_backtest <- 20 # 初始化存储结果的向量 actual_vals <- numeric(N - start_backtest + 1) lower_bound <- numeric(N - start_backtest + 1) upper_bound <- numeric(N - start_backtest + 1) for (i in start_backtest:N) { # 取前i-1个数据拟合模型 fit <- Arima(log(ts_data[1:(i-1)]), order = c(1, 1, 1), include.constant = TRUE) # 预测1步 fc <- forecast(fit, h = 1) # 注意:因为拟合的是log转换后的序列,要把区间反log转换回原尺度 actual_vals[i - start_backtest + 1] <- ts_data[i] lower_bound[i - start_backtest + 1] <- exp(fc$lower) upper_bound[i - start_backtest + 1] <- exp(fc$upper) } # 可视化对比实际值和预测区间 plot(actual_vals, type = "l", col = "black", ylab = "实际值", main = "回测:实际值 vs 预测区间") lines(lower_bound, col = "red", lty = 2) lines(upper_bound, col = "red", lty = 2) points(actual_vals, pch = 16)
关键提醒
因为你是对log(dat1$V2)拟合的模型,所以预测区间必须做反log转换,否则得到的是log尺度的区间,和原始数据的实际值没法直接对比,这点一定要注意!
内容的提问来源于stack exchange,提问作者Y. Z.
相关产品推荐
相关产品推荐

