5.10 Cross-validation per serie storiche

Una versione più sofisticata rispetto all’uso di un training set e di un test set è la cross-validation per serie storiche. In questa procedura, ci sono una serie di test set, ognuno dei quali consiste in una singola osservazione. Il training set corrispondente consiste solo di osservazioni che si sono verificate prima dell’osservazione che forma il test set. Quindi, nessuna osservazione futura può essere utilizzata per costruire la previsione. Poiché non è possibile ottenere una previsione affidabile sulla base di un piccolo training set, le prime osservazioni non sono considerate come test set.

Il seguente diagramma illustra la serie di sottocampioni traning/test, dove le osservazioni blu formano gli insiemi di stima e le osservazioni arancioni formano i test set.

#> Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
#> ℹ Please use `linewidth` instead.
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.

L’accuratezza della previsione viene calcolata facendo la media sui test set. Questa procedura è talvolta conosciuta come “valutazione su previsione rolling” perché l’“origine” su cui si basa la previsione si sposta in avanti nel tempo.

Le previsioni a un passo avanti potrebbero non essere così rilevanti come le previsioni a più passi. In questo caso, la procedura di cross validation basata su previsioni rolling può essere modificata per consentire l’uso di errori a più passi. Si supponga di essere interessati a modelli che producano buone previsioni \(4\)-passi in avanti. Allora il diagramma corrispondente è:

Nell’esempio seguente, si confronta l’accuratezza ottenuta tramite la cross validation per serie storiche con l’accuratezza residua. La funzione stretch_tsibble() viene usata per creare molti training set. In questo esempio, si parte utilizzando un training set di lunghezza .init=3, e si aumenta la dimensione dei training set successivi di .step=1.

# Time series cross-validation accuracy
google_2015_tr <- google_2015 %>%
  stretch_tsibble(.init = 3, .step = 1) %>%
  relocate(Date, Symbol, .id)
google_2015_tr
#> # A tsibble: 31,875 x 10 [1]
#> # Key:       Symbol, .id [250]
#>    Date       Symbol   .id  Open  High   Low Close Adj_Close  Volume   day
#>    <date>     <chr>  <int> <dbl> <dbl> <dbl> <dbl>     <dbl>   <dbl> <int>
#>  1 2015-01-02 GOOG       1  526.  528.  521.  522.      522. 1447600     1
#>  2 2015-01-05 GOOG       1  520.  521.  510.  511.      511. 2059800     2
#>  3 2015-01-06 GOOG       1  512.  513.  498.  499.      499. 2899900     3
#>  4 2015-01-02 GOOG       2  526.  528.  521.  522.      522. 1447600     1
#>  5 2015-01-05 GOOG       2  520.  521.  510.  511.      511. 2059800     2
#>  6 2015-01-06 GOOG       2  512.  513.  498.  499.      499. 2899900     3
#>  7 2015-01-07 GOOG       2  504.  504.  497.  498.      498. 2065100     4
#>  8 2015-01-02 GOOG       3  526.  528.  521.  522.      522. 1447600     1
#>  9 2015-01-05 GOOG       3  520.  521.  510.  511.      511. 2059800     2
#> 10 2015-01-06 GOOG       3  512.  513.  498.  499.      499. 2899900     3
#> # ℹ 31,865 more rows

La colonna .id fornisce una nuova chiave che indica i vari training set. La funzione accuracy() può essere usata per valutare l’accuratezza delle previsioni attraverso i training set.

# TSCV accuracy
google_2015_tr %>%
  model(RW(Close ~ drift())) %>%
  forecast(h = 1) %>%
  accuracy(google_2015)
# Training set accuracy
google_2015 %>%
  model(RW(Close ~ drift())) %>%
  accuracy()
Metodo di valutazione RMSE MAE MAPE MASE
Cross-validation 11.27 7.26 1.19 1.02
Training 11.15 7.16 1.18 1.00

Come previsto, le misure di accuratezza basate sui residui sono più piccole, poiché le “previsioni” corrispondenti sono basate su un modello adattato all’intero set di dati, piuttosto che essere vere previsioni.

Un buon modo per scegliere il miglior modello di previsione è quello di trovare il modello con il più piccolo RMSE calcolato utilizzando la cross validation per serie storiche.

Esempio: accuratezza dell’orizzonte di previsione con cross-validation

Il sottoinsieme google_2015 ottenuto a partire dai dati gafa_stock, rappresentato in figura 5.9, contiene i prezzi giornalieri delle azioni Google sul mercato NASDAQ per tutti i giorni di contrattazione nel 2015.

Il codice sotto valuta la performance delle previsioni da 1 ad 8 passi avanti ottenute con il metodo del drift. Il grafico corrispondente mostra che l’errore di previsione cresce al crescere dell’orizzonte temporale considerato, come del resto ci si poteva aspettare.

google_2015_tr <- google_2015 %>%
  stretch_tsibble(.init = 3, .step = 1)
fc <- google_2015_tr %>%
  model(RW(Close ~ drift())) %>%
  forecast(h = 8) %>%
  group_by(.id) %>%
  mutate(h = row_number()) %>%
  ungroup() %>%
  as_fable(response = "Close", distribution = Close)
fc %>%
  accuracy(google_2015, by = c("h", ".model")) %>%
  ggplot(aes(x = h, y = RMSE)) +
  geom_point()
RMSE in funzione dell'orizzonte di previsione per il metodo drift applicato ai prezzi di chiusura delle azioni Google.

Figura 5.24: RMSE in funzione dell’orizzonte di previsione per il metodo drift applicato ai prezzi di chiusura delle azioni Google.