簡體   English   中英

時間序列 - 數據拆分和模型評估

[英]Time-series - data splitting and model evaluation

我嘗試使用機器學習根據時間序列數據進行預測。 在 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)

我的理解是:

  1. 我需要將可能的數據拆分為訓練和測試集。
  2. 使用訓練集進行參數調整。
  3. 在測試集上評估獲得的模型(使用 R2、RMSE 等)

因為我的數據是時間序列的,所以我想我不能使用引導將數據拆分為訓練集和測試集。 所以,我的問題是:我是對的嗎? 如果是這樣 - 如何使用 createTimeSlices 進行模型評估?

請注意,您發布的原始問題會處理時間切片,您不必手動創建時間切片。

但是,這里是如何使用createTimeSlices來拆分數據,然后使用它來訓練和測試模型。

第 0 步:設置數據和trainControl :(來自您的問題)

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

data(economics)

第 1 步:為數據索引創建時間片:

timeSlices <- createTimeSlices(1:nrow(economics), 
                   initialWindow = 36, horizon = 12, fixedWindow = TRUE)

這將創建一個訓練和測試時間片列表。

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

為了便於理解,我將它們保存在單獨的變量中:

trainSlices <- timeSlices[[1]]
testSlices <- timeSlices[[2]]

第 2 步:在第一個trainSlices上進行訓練:

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

第 3 步:在第一個testSlices上進行測試:

pred <- predict(plsFitTime,economics[testSlices[[1]],])

第 4 步:繪圖:

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

plot(true, col = "red", ylab = "true (red) , pred (blue)", ylim = range(c(pred,true)))
points(pred, col = "blue") 

然后,您可以對所有切片執行此操作:

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") 
}

如前所述,這種時間切片是由您的原始函數一步完成的:

> 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. 

希望這可以幫助!!

Shambho 的回答提供了如何將插入符號包與 TimeSlices 一起使用的不錯示例,但是,它在建模技術方面可能會產生誤導。 因此,為了不誤導希望使用 caret 包對時間序列進行預測建模的未來讀者(這里我不是指自回歸模型),我想強調一些事情。

時間序列數據的問題在於,如果不小心,很容易出現前瞻偏差。 在這種情況下,經濟數據集在其經濟報告日期而不是其發布日期對齊數據,這在實際應用中從未出現過(經濟數據點具有不同的時間戳)。 就發布日期而言,失業數據可能比其他指標晚兩個月,這將在 Shambho 的示例中引入模型偏差。

接下來,這個例子只是描述性統計,而不是預測(預測),因為我們想要預測(失業)的數據沒有正確滯后。 它只是訓練一個模型,以根據同一經濟報告日期的預測變量最好地解釋失業率的變化(在這種情況下也是一個固定的時間序列,在建模過程中產生各種問題)。

最后,本示例中的 12 個月范圍並不是真正的多期預測,正如 Hyndman 在他的示例中所做的那樣。

Hyndman 關於時間序列的交叉驗證

其實,你可以!

首先,讓我給你一篇關於這個主題的學術文章

在 R 中:

使用包caretcreateResample可用於制作簡單的引導樣本, createFolds可用於從一組數據生成平衡的交叉驗證分組。 所以你可能想要使用createResample 這是它的用法示例:

data(oil)
createDataPartition(oilType, 2)

x <- rgamma(50, 3, .5)
inA <- createDataPartition(x, list = FALSE)

plot(density(x[inA]))
rug(x[inA])

points(density(x[-inA]), type = "l", col = 4)
rug(x[-inA], col = 4)

createResample(oilType, 2)

createFolds(oilType, 10)
createFolds(oilType, 5, FALSE)

createFolds(rnorm(21))

createTimeSlices(1:9, 5, 1, fixedWindow = FALSE)
createTimeSlices(1:9, 5, 1, fixedWindow = TRUE)
createTimeSlices(1:9, 5, 3, fixedWindow = TRUE)
createTimeSlices(1:9, 5, 3, fixedWindow = FALSE)

您在createResample函數中看到的值是數據和要創建的分區數,在本例中為 2。您可以另外指定結果是否應存儲為list = TRUElist = FALSE的列表。

此外, caret包含一個名為createTimeSlices的函數,可以為這種類型的拆分創建索引。

這種拆分的三個參數是:

  • initialWindow :每個訓練集樣本中連續值的初始個數
  • horizon :測試集樣本中連續值的數量
  • fixedWindow :一個邏輯:如果為 FALSE,則訓練集始終從第一個樣本開始,並且訓練集的大小將隨着數據拆分而變化。

用法:

createDataPartition(y, 
                    times = 1,
                    p = 0.5,
                    list = TRUE,
                    groups = min(5, length(y)))
createResample(y, times = 10, list = TRUE)
createFolds(y, k = 10, list = TRUE, returnTrain = FALSE)
createMultiFolds(y, k = 10, times = 5)
createTimeSlices(y, initialWindow, horizon = 1, fixedWindow = TRUE)

資料來源:

http://caret.r-forge.r-project.org/splitting.html

http://eranraviv.com/blog/bootstrapping-time-series-r-code/

http://rgm3.lab.nig.ac.jp/RGM/R_rdfile?f=caret/man/createDataPartition.Rd&d=R_CC

插入符號。 數據拆分與trainControl的關系

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM