如何在R中创建一个滑动窗口,将数据划分为测试和训练样本以测试预测的准确性?

时间:2017-07-05 18:50:39

标签: r forecasting

我们正在使用R中的forecast包来读取3周的每小时数据(3 * 7 * 24个数据点)并对接下来的24小时进行预测。这是一个多季节性的时间序列。

我们预测模型运行得很好,似乎表现不错。现在,我们希望量化我们的数据方法/预测算法的准确性。为此,我们希望在accuracy包中使用forecast函数。我们知道accuracy函数有效,因此f是预测,x是实际观察向量,然后accuracy(f,x)会为我们提供此预测的几个精度测量值。

我们有过去几个月的数据,我们希望编写一个滑动窗口算法,选择(3 * 7 * 24)小时值,然后预测接下来的24小时。然后,将这些值与第二天/ 24小时的实际数据进行比较,显示准确度,然后将窗口滑动(24点/小时)/次日并重复。

样本数据生成如下:

library("forecast")

time <- 1:(12*168)
set.seed(1)
ds <- msts(sin(2*pi*time/24)+c(1,1,1.2,0.8,1,0,0)[((time-1)%/%24)%%7+1]+ time/400+rnorm(length(time),0,0.2),seasonal.periods=c(24,168))
plot(ds)
head(ds)
tail(ds)
length(ds)
length(time)

预测程序如下:

model <- tbats(ds[1:504])
fcst <- forecast(model,h=24,level=90)
accuracy(fcst,ds[505:528])     ##Test accuracy of forecast against next/actual 24 values

现在,我们希望将“窗口”滑动24并重复相同的过程,也就是说,用于构建模型的下一组值将为ds[25:528],并且将针对{{ds[529:552]测试它们的准确性。 1}} ......等等。我们怎样才能实现这个目标?

另外,有没有更好的方法来测试我们场景的预测算法的整体准确性?

1 个答案:

答案 0 :(得分:1)

我会通过创建表示滑动窗口前边缘的时间向量,然后使用# set a couple of parameters we'll use to slice the series into chunks: # window width (w) and the time step at which you want to end the first # training set w = 24 ; start = 504 # now use those parameters to make a vector of the time steps at which each # window will end steps <- seq(start + w, length(ds), by = w) # using lapply, iterate the forecasting-and-scoring process over the # windows that created cv_list <- lapply(steps, function(x) { train <- ds[1:(x - w)] test <- ds[(x - w + 1):x] model <- tbats(train) fcst <- forecast(model, h = w, level = 90) accuracy(fcst, test) }) 在这些边缘暗示的窗口上迭代预测和评分过程来完成此操作。像...

> cv_list[[1]]
                       ME      RMSE       MAE        MPE     MAPE      MASE
Training set 0.0001587681 0.3442898 0.2689754 34.3957362 84.30841 0.9560206
Test set     0.2619029897 0.8961109 0.7868256 -0.6832273 36.64301 2.7966186
                   ACF1
Training set 0.02588145
Test set             NA

第一个窗口的示例输出:

rmse <- mean(unlist(lapply(cv_list, '[[', "Test set","RMSE")))

如果您想要整个列表的分数摘要,您可以执行类似......

的操作
[1] 1.011177

......产生这个:

zipinfo = zipfile.ZipInfo("{}.csv".format(i))
zipper.writestr(zipinfo, myfile.read())