Временные ряды - разделение данных и оценка модели

Я попытался использовать машинное обучение для прогнозирования на основе данных временных рядов. В одном из вопросов stackoverflow (createTimeSlices в пакете CARET в R) приведен пример использования 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)

Мое понимание:

  • Мне нужно разделить данные на тренировку и тестовый набор.
  • Используйте набор тренировок для настройки параметров.
  • Оценить полученную модель на тестовом наборе (используя R2, ​​RMSE и т.д.)

Поскольку мои данные являются временными рядами, я полагаю, что я не могу использовать bootstraping для разделения данных на обучение и набор тестов. Итак, мои вопросы: я прав? И если так - Как использовать createTimeSlices для оценки модели?

Ответ 1

Обратите внимание, что исходный вопрос, который вы опубликовали, позаботится о timeSlicing, и вам не нужно создавать timeSlices вручную.

Однако, вот как использовать 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: Тестирование первого из trainSlices:

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. 

Надеюсь, это поможет!

Ответ 2

Ответ Shambho дает достойный пример того, как использовать пакет Caret с TimeSlices, однако он может вводить в заблуждение с точки зрения техники моделирования. Поэтому, чтобы не вводить в заблуждение будущих читателей, которые хотят использовать пакет каретки для интеллектуального моделирования на временных рядах (и здесь я не имею в виду авторегрессионные модели), я хочу выделить несколько вещей.

Проблема с временными рядами данных заключается в том, что смещение вперед-назад легко, если не быть осторожным. В этом случае набор экономических данных сопоставляет данные по дате их экономической отчетности, а не к дате их выпуска, что никогда не имеет место в реальных реальных приложениях (точки экономических данных имеют разные отметки времени). Данные по безработице могут за два месяца отставать от других показателей с точки зрения даты выпуска, что затем приводило бы модельный уклон в примере Шамбо.

Далее, этот пример - это только описательная статистика, а не прогнозная (прогнозирование), потому что данные, которые мы хотим прогнозировать (безработица), не отставали должным образом. Он просто готовит модель, чтобы лучше объяснить вариации безработицы (которая также в этом случае представляет собой стационарный временной ряд, создающий всевозможные проблемы в процессе моделирования) на основе переменных-предикторов в те же даты экономических отчетов.

Наконец, 12-месячный горизонт в этом примере не является истинным многопериодным прогнозированием, как это делает Hyndman в своих примерах.

Hyndman по кросс-валидации для временных рядов

Ответ 3

Собственно, вы можете!

Во-первых, позвольте мне дать научную статью по этой теме.

В 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

CARET. Связь между разделением данных и trainControl