web-dev-qa-db-fra.com

Séries chronologiques - fractionnement des données et évaluation du modèle

J'ai essayé d'utiliser l'apprentissage automatique pour faire des prédictions basées sur des données de séries chronologiques. Dans l'une des questions de stackoverflow ( fonction createTimeSlices dans le package CARET dans R ) est un exemple d'utilisation de createTimeSlices pour la validation croisée pour la formation du modèle et le réglage des paramètres:

    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)

Ma compréhension est:

  1. J'ai besoin de diviser les données de mai à l'ensemble de formation et de test.
  2. Utilisez l'ensemble de formation pour le réglage des paramètres.
  3. Évaluer le modèle obtenu sur l'ensemble de test (en utilisant R2, RMSE, etc.)

Parce que mes données sont des séries chronologiques, je suppose que je ne peux pas utiliser le bootstraping pour diviser les données en ensemble de formation et de test. Alors, mes questions sont: ai-je raison? Et si oui - Comment utiliser createTimeSlices pour l'évaluation du modèle?

18
Jot eN

Notez que la question d'origine que vous avez postée s'occupe du timeSlicing et que vous n'avez pas à créer timeSlices à la main.

Cependant, voici comment utiliser createTimeSlices pour fractionner les données, puis les utiliser pour former et tester un modèle.

Étape 0: configuration des données et trainControl :( de votre question)

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

data(economics)

Étape 1: Création des tranches de temps pour l'index des données:

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

Cela crée une liste des tranches de temps de formation et de test.

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

Pour faciliter la compréhension, je les enregistre dans une variable distincte:

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

Étape 2: Formation sur le premier des trainSlices:

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

Étape 3: test sur la première des trainSlices:

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

Étape 4: Tracer:

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

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

Vous pouvez ensuite le faire pour toutes les tranches:

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

Comme mentionné précédemment, ce type de découpage temporel est effectué par votre fonction d'origine en une seule étape:

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

J'espère que cela t'aides!!

38
Shambho

La réponse de Shambho fournit un exemple décent de la façon d'utiliser le package caret avec TimeSlices, cependant, il peut être trompeur en termes de technique de modélisation. Donc, afin de ne pas induire en erreur les futurs lecteurs qui souhaitent utiliser le package caret pour la modélisation prédictive sur des séries chronologiques (et ici je ne parle pas de modèles autorégressifs), je veux souligner quelques éléments.

Le problème avec les données de séries chronologiques est que le biais d'anticipation est facile si l'on ne fait pas attention. Dans ce cas, l'ensemble de données économiques a aligné les données à leurs dates de rapport économique et non à leur date de publication, ce qui n'est jamais le cas dans les applications réelles réelles (les points de données économiques ont des horodatages différents). Les données sur le chômage peuvent avoir deux mois de retard sur les autres indicateurs en termes de date de publication, ce qui introduirait alors un biais de modèle dans l'exemple de Shambho.

Ensuite, cet exemple n'est que des statistiques descriptives et non prédictif (prévision) car les données que nous voulons prévoir (chômage) ne sont pas correctement décalées. Il se contente de former un modèle pour mieux expliquer la variation du chômage (qui est également dans ce cas une série chronologique stationnaire créant toutes sortes de problèmes dans le processus de modélisation) basée sur des variables prédictives aux mêmes dates de rapport économique.

Enfin, l'horizon de 12 mois dans cet exemple n'est pas une véritable prévision multi-période comme Hyndman le fait dans ses exemples.

Hyndman sur la validation croisée pour les séries chronologiques

5
P. Garnry

En fait, vous le pouvez!

Tout d'abord, permettez-moi de vous donner n article scientifique sur le sujet .

Dans R:

En utilisant le package caret, createResample peut être utilisé pour simplifier bootstrap échantillons et createFolds peut être utilisé pour générer des regroupements équilibrés de validation croisée à partir d'un ensemble de données. Vous voudrez donc probablement utiliser createResample. Voici un exemple de son utilisation:

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)

Les valeurs que vous voyez dans la fonction createResample sont les données et le nombre de partitions à créer, dans ce cas 2. Vous pouvez également spécifier si les résultats doivent être stockés sous forme de liste avec list = TRUE ou list = FALSE.

De plus, caret contient une fonction appelée createTimeSlices qui peut créer les indices pour ce type de fractionnement.

Les trois paramètres de ce type de fractionnement sont:

  • initialWindow: le nombre initial de valeurs consécutives dans chaque échantillon d'ensemble d'apprentissage
  • horizon: nombre de valeurs consécutives dans l'échantillon de l'ensemble de tests
  • fixedWindow: logique: si FALSE, l'ensemble de formation commence toujours au premier échantillon et la taille de l'ensemble de formation variera en fonction des divisions de données.

Usage:

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)

Sources:

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. Relation entre le fractionnement des données et trainControl

2
Hack-R