[英]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)
我的理解是:
因為我的數據是時間序列的,所以我想我不能使用引導將數據拆分為訓練集和測試集。 所以,我的問題是:我是對的嗎? 如果是這樣 - 如何使用 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 在他的示例中所做的那樣。
其實,你可以!
首先,讓我給你一篇關於這個主題的學術文章。
在 R 中:
使用包caret
, createResample
可用於制作簡單的引導樣本, 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 = TRUE
或list = 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.