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:
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?
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!!
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
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'apprentissagehorizon
: nombre de valeurs consécutives dans l'échantillon de l'ensemble de testsfixedWindow
: 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