Come montare un modello ARIMAX con R?


33

Ho quattro diverse serie temporali di misurazioni orarie:

  1. Il consumo di calore all'interno di una casa
  2. La temperatura fuori casa
  3. La radiazione solare
  4. La velocità del vento

Voglio essere in grado di prevedere il consumo di calore all'interno della casa. C'è una chiara tendenza stagionale, sia su base annuale, sia su base giornaliera. Poiché esiste una chiara correlazione tra le diverse serie, voglio adattarle usando un modello ARIMAX. Questo può essere fatto in R, usando la funzione arimax dal pacchetto TSA.

Ho provato a leggere la documentazione su questa funzione e a leggere le funzioni di trasferimento, ma finora il mio codice:

regParams = ts.union(ts(dayy))
transferParams = ts.union(ts(temp))
model10 = arimax(heat,order=c(2,1,1),seasonal=list(order=c(0,1,1),period=24),xreg=regParams,xtransf=transferParams,transfer=list(c(1,1))
pred10 = predict(model10, newxreg=regParams)

mi da: inserisci qui la descrizione dell'immagine

dove la linea nera è il dato reale misurato e la linea verde è il mio modello montato in confronto. Non solo non è un buon modello, ma chiaramente qualcosa non va.

Devo ammettere che la mia conoscenza dei modelli ARIMAX e delle funzioni di trasferimento è limitata. Nella funzione arimax (), (per quanto ho capito), xtransf è la serie temporale esogena che voglio usare (usando le funzioni di trasferimento) per prevedere le mie serie storiche principali. Ma qual è la differenza tra xreg e xtransf davvero?

Più in generale, cosa ho fatto di sbagliato? Vorrei essere in grado di ottenere una misura migliore rispetto a quella ottenuta da lm (calore ~ ​​temp radi vento * tempo).

Modifiche: in base ad alcuni dei commenti, ho rimosso il trasferimento e aggiunto invece xreg:

regParams = ts.union(ts(dayy), ts(temp), ts(time))
model10 = arimax(heat,order=c(2,1,1),seasonal=list(order=c(0,1,1),period=24),xreg=regParams)

dove dayy è il "numero dell'anno" e l'ora è l'ora del giorno. La temperatura è di nuovo la temperatura esterna. Questo mi dà il seguente risultato:

inserisci qui la descrizione dell'immagine

che è meglio, ma non quasi quello che mi aspettavo di vedere.

Risposte:


34

Avrai un po 'di problemi a modellare una serie con 2 livelli di stagionalità usando un modello ARIMA. Fare questo bene dipende fortemente dall'impostazione corretta delle cose. Hai già considerato un modello lineare semplice? Sono molto più veloci e più facili da montare rispetto ai modelli ARIMA e se si utilizzano variabili fittizie per i diversi livelli di stagionalità, sono spesso abbastanza precise.

  1. Suppongo che tu abbia dati orari, quindi assicurati che il tuo oggetto TS sia impostato con una frequenza di 24.
  2. È possibile modellare altri livelli di stagionalità utilizzando variabili fittizie. Ad esempio, potresti voler un set di manichini 0/1 che rappresentano il mese dell'anno.
  3. Includi le variabili fittizie xregnell'argomento, insieme a tutte le covariate (come la temperatura).
  4. Adatta il modello con la funzione arima nella base R. Questa funzione può gestire i modelli ARMAX attraverso l'uso xregdell'argomento.
  5. Prova le funzioni Arima e auto.arima nel pacchetto di previsione. auto.arima è piacevole perché troverà automaticamente buoni parametri per il tuo modello arima. Tuttavia, ci vorrà SEMPRE per adattarsi al tuo set di dati.
  6. Prova la funzione tslm nel pacchetto arima, usando variabili fittizie per ogni livello di stagionalità. Si adatterà molto più velocemente rispetto al modello Arima e potrebbe anche funzionare meglio nella tua situazione.
  7. Se il 4/5/6 non funziona, ALLORA iniziano a preoccuparsi delle funzioni di trasferimento. Devi strisciare prima di poter camminare.
  8. Se stai pianificando di prevedere in futuro, dovrai prima prevedere le variabili xreg. Questo è facile per i manichini stagionali, ma dovrai pensare a come fare un bel tempo. Forse usi la mediana dei dati storici?

Ecco un esempio di come mi avvicinerei a questo:

#Setup a fake time series
set.seed(1)
library(lubridate)
index <- ISOdatetime(2010,1,1,0,0,0)+1:8759*60*60
month <- month(index)
hour <- hour(index)
usage <- 1000+10*rnorm(length(index))-25*(month-6)^2-(hour-12)^2
usage <- ts(usage,frequency=24)

#Create monthly dummies.  Add other xvars to this matrix
xreg <- model.matrix(~as.factor(month))[,2:12]
colnames(xreg) <- c('Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')

#Fit a model
library(forecast)
model <- Arima(usage, order=c(0,0,0), seasonal=list(order=c(1,0,0), period=24), xreg=xreg)
plot(usage)
lines(fitted(model),col=2)

#Benchmark against other models
model2 <- tslm(usage~as.factor(month)+as.factor(hour))
model3 <- tslm(usage~as.factor(month))
model4 <- rep(mean(usage),length(usage))

#Compare the 4 models
library(plyr) #for rbind.fill
ACC <- rbind.fill(  data.frame(t(accuracy(model))),
                    data.frame(t(accuracy(model2))),
                    data.frame(t(accuracy(model3))),
                    data.frame(t(accuracy(model4,usage)))
                )
ACC <- round(ACC,2)
ACC <- cbind(Type=c('Arima','LM1','Monthly Mean','Mean'),ACC)
ACC[order(ACC$MAE),]

Qual è la funzione fornita (). Se lo uso, ottengo risultati decisamente migliori rispetto a predict (model10, newxreg = regParams).
utdiscante

@utdiscant: predict()viene utilizzato per le previsioni, mentre fitted()restituisce l'adattamento del modello nel periodo storico. Se desideri un aiuto più specifico, dovresti pubblicare un esempio riproducibile con un po 'di codice.
Zach,

@utdiscant: inoltre, se usi dayy come xreg, corri il rischio di overfitting, dato che hai solo 24 osservazioni al giorno. Potresti ottenere risultati di previsione migliori se utilizzi il mese dell'anno.
Zach,

@utdiscant: Inoltre, i tuoi xreg basati sul tempo devono essere variabili fittizie . Il modo in cui lo hai modellato ora è che ti aspetti heatdi aumentare linearmente con l'ora del giorno, quindi di tornare indietro quando l'ora torna a 1. Se usi variabili fittizie, ogni ora del giorno avrà il suo effetto. Esegui il mio codice di esempio e presta molta attenzione a come costruisco il mio oggetto xreg.
Zach,

Un aspetto negativo delle funzioni ARIMA nei pacchetti statse forecastè che non si adattano alle funzioni di trasferimento prober. La documentazione della stats::arimafunzione indica quanto segue: Se è incluso un termine xreg, una regressione lineare (con un termine costante se include.mean è vera e non vi sono differenze) è dotata di un modello ARMA per il termine di errore. Quindi, se in realtà è necessario adattare le funzioni di trasferimento, sembra che la TSA::arimaxfunzione sia la strada da percorrere R.
Christoffer,

8

Sto usando R per caricare previsioni per un po 'e posso suggerirti di usare il forecastpacchetto e le sue preziose funzioni (come auto.arima).

È possibile creare un modello ARIMA con il seguente comando:

model = arima(y, order, xreg = exogenous_data)

con il ytuo pronostico (suppongo dayy), orderl'ordine del tuo modello (considerando la stagionalità) e la exogenous_datatua temperatura, radiazione solare, ecc. La funzione auto.arimati aiuta a trovare l'ordine del modello ottimale. Puoi trovare un breve tutorial sul pacchetto `forecast ' qui .


Ciò che deve essere previsto è il calore (il consumo di calore della casa).
utdiscante

3

Personalmente non capisco le funzioni di trasferimento, ma penso che tu abbia ottenuto xtransfe xreginvertito. Almeno nella base di R arimaè xregche contiene le tue variabili esogene. Ho l'impressione che una funzione di trasferimento descriva come (i dati ritardati influiscono sui valori futuri) piuttosto che cosa .

Proverei a usare xregper le tue variabili esogene, magari usando arimase arimaxrichiede una funzione di trasferimento. Il problema è che il tuo modello è quotidiano, ma i tuoi dati hanno una stagionalità sia giornaliera che annuale, e non sono sicuro in questo momento se una prima differenza (la order=(*, 1, *)) se ne occuperà o meno. (Certamente non otterrai previsioni magiche per tutto l'anno da un modello che considera solo la stagionalità quotidiana.)

PS Cos'è timequello che usi nel tuo lm? Ora letterale o un numero di osservazione 1-up? Penso che potresti ottenere qualcosa usando un modello a effetti misti ( lmernel lme4pacchetto), anche se non ho capito se farlo spieghi correttamente l'autocorrelazione che si verificherà in una serie temporale. Se non viene tenuto in considerazione, cosa lmche non accade, potresti ottenere un adattamento interessante, ma il tuo concetto di quanto sia precisa la tua previsione sarà troppo ottimista.


Ho sia l'ora della misurazione, sia il "giorno dell'anno" della misurazione.
utdiscante
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.