2014-07-15 13 views
12

Ho provato a utilizzare l'apprendimento automatico per effettuare la predizione basata sui dati delle serie temporali. In una della questione StackOverflow (createTimeSlices function in CARET package in R) è un esempio di utilizzo di createTimeSlices per la convalida incrociata per la formazione del modello e dei parametri di sintonia:Serie storica: suddivisione dei dati e valutazione del modello

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) 

mia comprensione è:

  1. Ho bisogno di dividere i dati da maggio a allenamento e set di prova.
  2. Utilizzare il set di allenamento per la sintonizzazione dei parametri.
  3. analizzare completamente ottenuto modello sul set di prova (usando R2, RMSE, ecc)

Perché il mio trattamento è di serie temporali, suppongo che non posso usare bootstraping per spliting dati in formazione e test set. Quindi, le mie domande sono: ho ragione? E se è così - Come usare createTimeSlices per la valutazione del modello?

+1

Sarebbe utile se si è definito cosa si intende per "valutazione del modello". – topepo

+0

Ho modificato la mia domanda. Forse in questo momento è più facile da capire? –

+1

1. il pacchetto 'pls' deve essere installato 2. se si è interessati solo all'ordine dei campioni (non al mese o all'anno in particolare), è possibile fornire loro un ID numerico e si può ancora usare il bootstrap 3. perché non usare qualcosa di semplice come un glm? –

risposta

27

Si noti che la domanda originale che è stata inviata, si occupa di timeSlicing e non è necessario creare timeSlices a mano.

Tuttavia, ecco come utilizzare createTimeSlices per suddividere i dati e quindi utilizzarli per addestrare e testare un modello.

Fase 0: Impostazione dei dati e trainControl: (dalla tua domanda)

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

data(economics) 

Fase 1: Creare le porzione di tempo per l'indice dei dati:

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

Questo crea una lista di formazione e test timeSlices.

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

Per una maggiore comprensione, io li sto salvando in variabile separata:

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

Fase 2: Formazione sul primo del trainSlices:

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

Fase 3: Test su il primo degli trainSlices:

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

Fase 4: Tracciato:

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

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

È quindi possibile fare questo per tutte le fette:

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

Come accennato in precedenza, questo tipo di timeslicing è fatto dalla funzione originale in un unico passaggio:

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

Spero che questo aiuti !!

+0

Quindi, se sto utilizzando il controllo del treno di emergenza, non è necessario suddividere i dati in training e test set prima? –

+2

corretto. L'autore della sceneggiatura dice anche che stanno migliorando la documentazione di questo nella prossima versione. – Shambho

+0

Davvero una risposta fantastica - molte grazie, ho imparato molto! – d8aninja

2

In realtà, è possibile!

Innanzitutto, vorrei darti a scholarly article on the topic.

In R:

Usando il pacchetto caret, createResample può essere usato per fare i campioni semplice bootstrap e createFolds può essere utilizzato per generare bilanciati raggruppamenti di validazione incrociata da un insieme di dati. Quindi probabilmente vorrai usare createResample. Ecco un esempio del suo utilizzo:

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) 

I valori che vedi nella funzione di createResample sono i dati e il numero di partizioni per creare, in questo caso 2. È possibile inoltre specificare se i risultati devono essere conservati come elencare con list = TRUE o list = FALSE.

Inoltre, caret contiene una funzione denominata createTimeSlices che può creare gli indici per questo tipo di suddivisione.

I tre parametri per questo tipo di scissione sono:

  • initialWindow: il numero iniziale di valori consecutivi in ​​ciascun campione di addestramento
  • horizon: Il numero di valori consecutivi nel campione di test set
  • fixedWindow: Una logica: se FALSE, il set di allenamento inizia sempre dal primo campione e la dimensione del set di allenamento varia in base alle suddivisioni dei dati.

utilizzo:

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) 

Fonti:

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. Relationship between data splitting and trainControl

+0

Potresti fare un esempio in R? –

+0

@JoteN Sure. Ci sono esempi in questi due collegamenti, ma li aggiungerò direttamente alla soluzione. –

+0

@JoteN In realtà, sì, suppongo che abbiano fornito esempi di esempio con il codice delle altre funzioni, quindi abbiamo discusso di createResample e appena mostrato il risultato. Ho trovato un esempio e l'esempio di utilizzo generale per te. –

4

La risposta di Shambho fornisce un esempio decente di come utilizzare il pacchetto caret con TimeSlices, tuttavia, può essere fuorviante in termini di tecnica di modellazione. Quindi, per non confondere i futuri lettori che vogliono utilizzare il pacchetto di caret per la modellazione predittiva su serie temporali (e qui non intendo i modelli autoregressivi), voglio evidenziare alcune cose.

Il problema con i dati delle serie temporali è che il bias di previsione è facile se non si presta attenzione.In questo caso, il set di dati economici ha allineato i dati alle loro date di reporting economico e non alla loro data di rilascio, il che non è mai il caso in applicazioni live reali (i punti di dati economici hanno timestamp diversi). I dati sulla disoccupazione potrebbero essere due mesi indietro rispetto agli altri indicatori in termini di data di rilascio, che introdurrebbe quindi un errore di modello nell'esempio di Shambho.

Successivamente, questo esempio è solo statistica descrittiva e non predittiva (previsione) poiché i dati che si desidera prevedere (disoccupazione) non sono ritardati correttamente. Si limita a formare un modello per spiegare al meglio la variazione della disoccupazione (che anche in questo caso è una serie temporale stazionaria che crea ogni sorta di problemi nel processo di modellazione) basata su variabili predittive alle stesse date del rapporto economico.

Infine, l'orizzonte di 12 mesi in questo esempio non è una vera previsione multi-periodo come Hyndman fa nei suoi esempi.

Hyndman on cross-validation for time-series