Previsioni a un passo con il pacchetto dynlm R


11

Ho adattato un modello con diverse variabili indipendenti, una delle quali è il ritardo della variabile dipendente, usando il pacchetto dynlm.

Supponendo che io abbia previsioni di un passo avanti per le mie variabili indipendenti, come posso ottenere previsioni di un passo avanti per le mie variabili dipendenti?

Ecco un esempio:

library(dynlm)

y<-arima.sim(model=list(ar=c(.9)),n=10) #Create AR(1) dependant variable
A<-rnorm(10) #Create independant variables
B<-rnorm(10)
C<-rnorm(10)
y<-y+.5*A+.2*B-.3*C #Add relationship to independant variables 
data=cbind(y,A,B,C)

#Fit linear model
model<-dynlm(y~A+B+C+L(y,1),data=data)

#Forecast
A<-c(A,rnorm(1)) #Assume we already have 1-step forecasts for A,B,C
B<-c(B,rnorm(1))
C<-c(C,rnorm(1))
y=window(y,end=end(y)+c(1,0),extend=TRUE)
newdata<-cbind(y,A,B,C)
predict(model,newdata)

Ed ecco un esempio usando il pacchetto dyn, che funziona.

library(dyn)

#Fit linear model
model<-dyn$lm(y~A+B+C+lag(y,-1),data=data)

#Forecast
predict(model,newdata)the dyn packages, which works:

L'uso del solo dynlmpacchetto non fornirà previsioni per le variabili dipendenti. Fornire previsioni per le variabili dipendenti richiederà un modello per spiegarle e probabilmente dati aggiuntivi. Ti suggerisco di leggere qualcosa sulla regressione multivariata come "Analisi statistica multivariata applicata" di Johnson and Wichern. o un corso sulle previsioni: duke.edu/~rnau/411home.htm
deps_stats

1
@deps_stats La variabile dipendente è ciò che voglio prevedere. Suppongo di avere già previsioni per le mie variabili indipendenti. Nel mio codice di esempio, y è la variabile dipendente che sto tentando di prevedere e A, B, C sono le variabili indipendenti, per le quali ho già delle previsioni. Se esegui il codice di esempio che ho pubblicato, capirai la natura del mio problema.
Zach,

@Zach: Nice Kaggle rating! (Ho cliccato sul link nel tuo profilo con il mouse sopra)
Hugh Perkins,

Risposte:


13

Congratulazioni, hai trovato un bug. La previsione per dynlmcon i nuovi dati viene interrotta se si utilizzano variabili ritardate. Per vedere perché guardare l'output di

predict(model)
predict(model,newdata=data)

I risultati dovrebbero essere gli stessi, ma non lo sono. Senza newdataargomento, la predictfunzione prende sostanzialmente l' modelelemento dynlmdall'output. Con newdataargomento predicttenta di formare una nuova matrice di modello da newdata. Poiché ciò implica l'analisi della formula fornita dynlme la formula ha funzione L, che è definita solo internamente in funzione dynlm, si forma la matrice del modello errata. Se provi a eseguire il debug, vedrai che la variabile dipendente ritardata non viene ritardata nel caso in cui l' newdataargomento sia fornito.

Quello che puoi fare è ritardare la variabile dipendente e includerla nel file newdata. Ecco il codice che illustra questo approccio. Lo uso set.seedquindi sarebbe facilmente riproducibile.

library(dynlm)

set.seed(1)
y<-arima.sim(model=list(ar=c(.9)),n=10) #Create AR(1) dependant variable
A<-rnorm(10) #Create independant variables
B<-rnorm(10)
C<-rnorm(10)
y<-y+.5*A+.2*B-.3*C #Add relationship to independant variables 
data=cbind(y,A,B,C)

#Fit linear model
model<-dynlm(y~A+B+C+L(y,1),data=data)

Ecco il comportamento buggy:

> predict(model)
       2        3        4        5        6        7        8        9       10 
3.500667 2.411196 2.627915 2.813815 2.468595 1.733852 2.114553 1.423225 1.470738 
> predict(model,newdata=data)
        1         2         3         4         5         6         7         8         9        10 
2.1628335 3.7063579 2.9781417 2.1374301 3.2582376 1.9534558 1.3670995 2.4547626 0.8448223 1.8762437 

Forma il newdata

#Forecast fix.
A<-c(A,rnorm(1)) #Assume we already have 1-step forecasts for A,B,C
B<-c(B,rnorm(1))
C<-c(C,rnorm(1))

newdata<-ts(cbind(A,B,C),start=start(y),freq=frequency(y))

newdata<-cbind(lag(y,-1),newdata)
colnames(newdata) <- c("y","A","B","C")

Confronta le previsioni con l'adattamento del modello:

> predict(model)
       2        3        4        5        6        7        8        9       10 
3.500667 2.411196 2.627915 2.813815 2.468595 1.733852 2.114553 1.423225 1.470738 
> predict(model,newdata=newdata)
       1        2        3        4        5        6        7        8        9       10       11 
      NA 3.500667 2.411196 2.627915 2.813815 2.468595 1.733852 2.114553 1.423225 1.470738 1.102367 

Come puoi vedere per i dati storici, la previsione coincide e l'ultimo elemento contiene la previsione a un passo.


Come puoi gestire il caso in cui hai due ritardi nella stessa formula? lag(y,-1)+lag(y,-2)?
Hugh Perkins,

1
Bene, allora questa soluzione non funziona. Devi scrivere la tua funzione di previsione.
mpiktas,

Ah, questo è quello che ho fatto in effetti :-P
Hugh Perkins,

1
Hai considerato di inviarlo agli autori di dynlm? È una situazione bizzarra, che non puoi prevedere usando dynlm.
mpiktas,

Hmmm, stai dicendo che non monitoreranno magicamente lo stackoverflow e risolveranno i bug? Immagino sia probabilmente vero!
Hugh Perkins,

2

Seguendo la richiesta di @md-azimul-haque, ho analizzato il mio codice sorgente di 4 anni e ho trovato la seguente funzione chiamata in modo appropriato. Non sei sicuro se questo è ciò che @ md-azimul-haque sta cercando?

# pass in training data, test data,
# it will step through one by one
# need to give dependent var name, so that it can make this into a timeseries
predictDyn <- function( model, train, test, dependentvarname ) {
    Ntrain <- nrow(train)
    Ntest <- nrow(test)
    # can't rbind ts's apparently, so convert to numeric first
    train[,dependentvarname] <- as.numeric(train[,dependentvarname])
    test[,dependentvarname] <- NA
    testtraindata <- rbind( train, test )
    testtraindata[,dependentvarname] <- ts( as.numeric( testtraindata[,dependentvarname] ) )
    for( i in 1:Ntest ) {
       cat("predicting i",i,"of",Ntest,"\n")
       result <- predict(model,newdata=testtraindata,subset=1:(Ntrain+i-1))
       testtraindata[Ntrain+i,dependentvarname] <- result[Ntrain + i + 1 - start(result)][1]
    }
    testtraindata <- testtraindata[(Ntrain+1):(Ntrain + Ntest),dependentvarname]
    names(testtraindata) <- 1:Ntest
    return( testtraindata )
}
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.