Previsões passo a frente com o pacote dynlm R

11

Eu ajustei um modelo com várias variáveis ​​independentes, uma das quais é o atraso da variável dependente, usando o pacote dynlm.

Supondo que eu tenha previsões de um passo à frente para minhas variáveis ​​independentes, como faço para obter previsões de um passo à frente para minhas variáveis ​​dependentes?

Aqui está um exemplo:

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)

E aqui está um exemplo usando o pacote dyn, que funciona.

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:
Zach
fonte
Usar apenas o dynlmpacote não fornecerá previsões para suas variáveis ​​dependentes. O fornecimento de previsões para suas variáveis ​​dependentes exigirá um modelo para explicá-las e provavelmente dados adicionais. Sugiro que você leia algo sobre regressão multivariada, como "Análise Estatística Multivariada Aplicada", de Johnson e Wichern. ou um curso sobre previsão: duke.edu/~rnau/411home.htm
deps_stats 31/01
1
@deps_stats A variável dependente é o que eu quero prever. Estou assumindo que já tenho previsões para minhas variáveis ​​independentes. No meu exemplo de código, y é a variável dependente que estou tentando prever e A, B, C são as variáveis ​​independentes, para as quais já tenho previsões. Se você executar o código de exemplo que eu publiquei, entenderá a natureza do meu problema.
Zach
@Zach: Nice Kaggle classificação! (Eu cliquei através do link no seu perfil do mouse-over)
Hugh Perkins

Respostas:

13

Parabéns, você encontrou um bug. A previsão para dynlmnovos dados é interrompida se variáveis ​​atrasadas forem usadas. Para ver por que olhar para a saída de

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

Os resultados devem ser os mesmos, mas não são. Sem newdataargumento, a predictfunção basicamente pega o modelelemento da dynlmsaída. Com newdataargumento predicttenta formar nova matriz de modelo a partir de newdata. Como isso envolve a análise da fórmula fornecida dynlme a fórmula possui uma função L, definida apenas internamente na função dynlm, a matriz do modelo incorreta é formada. Se você tentar depurar, verá que a variável dependente defasada não está sendo defasada no caso de newdataargumento ser fornecido.

O que você pode fazer é atrasar a variável dependente e incluí-la no newdata. Aqui está o código que ilustra essa abordagem. Eu uso set.seedpara que seja facilmente reproduzível.

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)

Aqui está o comportamento do 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 

Forme o 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")

Compare a previsão com o ajuste do modelo:

> 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 

Como você pode ver nos dados históricos, a previsão coincide e o último elemento contém a previsão de um passo à frente.

mpiktas
fonte
Como você pode lidar com o caso em que você tem dois atrasos na mesma fórmula? lag(y,-1)+lag(y,-2)?
Hugh Perkins
1
Bem, então esta solução não funciona. Você precisa escrever sua própria função de previsão.
Mvctas #
Ah, foi o que eu fiz de fato :-P
Hugh Perkins
1
Você considerou enviá-lo aos autores do dynlm? É uma situação bizarra, que você não pode prever usando dynlm.
Mvctas #
Hummm, você está dizendo que eles não vão monitorar magicamente o stackoverflow e corrigir bugs? Eu acho que isso provavelmente é verdade!
Hugh Perkins
2

Após a solicitação do @ md-azimul-haque, procurei no meu código fonte de 4 anos e encontrei a seguinte função com o nome apropriado. Não tenho certeza se é isso que o @ md-azimul-haque está procurando?

# 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 )
}
Hugh Perkins
fonte