时间序列 - 数据分割和模型评估

Jot*_* eN 17 r time-series r-caret

我试图使用机器学习来根据时间序列数据进行预测.在其中一个stackoverflow问题(R中的CARET包中的createTimeSlices函数)是使用createTimeSlices进行模型训练和参数调整的交叉验证的示例:

    library(caret)
    library(ggplot2)
    library(pls)
    data(economics)
    myTimeControl <- trainControl(method = "timeslice",
                                  initialWindow = 36,
                                  horizon = 12,
                                  fixedWindow = TRUE)

    plsFitTime <- train(unemploy ~ pce + pop + psavert,
                        data = economics,
                        method = "pls",
                        preProc = c("center", "scale"),
                        trControl = myTimeControl)
Run Code Online (Sandbox Code Playgroud)

我的理解是:

  1. 我需要将数据拆分为训练和测试集.
  2. 使用训练集进行参数调整.
  3. 在测试集上评估获得的模型(使用R2,RMSE等)

因为我的数据是时间序列,我想我不能使用bootstraping将数据分成训练和测试集.所以,我的问题是:我是对的吗?如果是这样 - 如何使用createTimeSlices进行模型评估?

Sha*_*bho 38

请注意,您发布的原始问题负责timeSlicing,您无需手动创建timeSlices.

但是,以下是如何使用它createTimeSlices来分割数据,然后将其用于训练和测试模型.

第0步:设置数据并trainControl:(来自您的问题)

library(caret)
library(ggplot2)
library(pls)

data(economics)
Run Code Online (Sandbox Code Playgroud)

第1步:为数据索引创建timeSlices:

timeSlices <- createTimeSlices(1:nrow(economics), 
                   initialWindow = 36, horizon = 12, fixedWindow = TRUE)
Run Code Online (Sandbox Code Playgroud)

这将创建一个训练和测试时间列表.

> str(timeSlices,max.level = 1)
## List of 2
## $ train:List of 431
##   .. [list output truncated]
## $ test :List of 431
##   .. [list output truncated]
Run Code Online (Sandbox Code Playgroud)

为了便于理解,我将它们保存在单独的变量中:

trainSlices <- timeSlices[[1]]
testSlices <- timeSlices[[2]]
Run Code Online (Sandbox Code Playgroud)

第2步:第一步的培训trainSlices:

plsFitTime <- train(unemploy ~ pce + pop + psavert,
                    data = economics[trainSlices[[1]],],
                    method = "pls",
                    preProc = c("center", "scale"))
Run Code Online (Sandbox Code Playgroud)

第3步:测试第一个trainSlices:

pred <- predict(plsFitTime,economics[testSlices[[1]],])
Run Code Online (Sandbox Code Playgroud)

第4步:绘图:

true <- economics$unemploy[testSlices[[1]]]

plot(true, col = "red", ylab = "true (red) , pred (blue)", ylim = range(c(pred,true)))
points(pred, col = "blue") 
Run Code Online (Sandbox Code Playgroud)

然后,您可以对所有切片执行此操作:

for(i in 1:length(trainSlices)){
  plsFitTime <- train(unemploy ~ pce + pop + psavert,
                      data = economics[trainSlices[[i]],],
                      method = "pls",
                      preProc = c("center", "scale"))
  pred <- predict(plsFitTime,economics[testSlices[[i]],])


  true <- economics$unemploy[testSlices[[i]]]
  plot(true, col = "red", ylab = "true (red) , pred (blue)", 
            main = i, ylim = range(c(pred,true)))
  points(pred, col = "blue") 
}
Run Code Online (Sandbox Code Playgroud)

如前所述,这种timeSlicing是由原始函数在一个步骤中完成的:

> myTimeControl <- trainControl(method = "timeslice",
+                               initialWindow = 36,
+                               horizon = 12,
+                               fixedWindow = TRUE)
> 
> plsFitTime <- train(unemploy ~ pce + pop + psavert,
+                     data = economics,
+                     method = "pls",
+                     preProc = c("center", "scale"),
+                     trControl = myTimeControl)
> plsFitTime
Partial Least Squares 

478 samples
  5 predictors

Pre-processing: centered, scaled 
Resampling: Rolling Forecasting Origin Resampling (12 held-out with a fixed window) 

Summary of sample sizes: 36, 36, 36, 36, 36, 36, ... 

Resampling results across tuning parameters:

  ncomp  RMSE  Rsquared  RMSE SD  Rsquared SD
  1      1080  0.443     796      0.297      
  2      1090  0.43      845      0.295      

RMSE was used to select the optimal model using  the smallest value.
The final value used for the model was ncomp = 1. 
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!!

  • 正确.该脚本的作者还说,他们将在下一版本中改进文档. (2认同)

P. *_*nry 5

Shambho 的回答提供了一个很好的例子,说明了如何将插入符号包与 TimeSlices 一起使用,但是,它在建模技术方面可能会产生误导。因此,为了不误导想要使用 caret 包对时间序列进行预测建模的未来读者(这里我不是指自回归模型),我想强调一些事情。

时间序列数据的问题在于,如果不小心,前瞻偏差很容易。在这种情况下,经济学数据集在它们的经济报告日期而不是它们的发布日期对齐了数据,这在实际应用程序中从来不是这样(经济数据点有不同的时间戳)。就发布日期而言,失业数据可能比其他指标晚两个月,这会在 Shambho 的示例中引入模型偏差。

接下来,这个例子只是描述性统计,而不是预测性(预测),因为我们要预测的数据(失业)没有正确滞后。它只是基于相同经济报告日期的预测变量来训练一个模型来最好地解释失业率的变化(在这种情况下也是一个平稳的时间序列,在建模过程中会产生各种问题)。

最后,本示例中的 12 个月范围不是真正的多期预测,因为 Hyndman 在他的示例中是这样做的。

Hyndman 关于时间序列的交叉验证