Função de transferência de intervenção ARIMA - Como visualizar o efeito

11

Tenho uma série temporal mensal com uma intervenção e gostaria de quantificar o efeito dessa intervenção no resultado. Sei que a série é bastante curta e o efeito ainda não está concluído.

Os dados

cds <- structure(c(2580L, 2263L, 3679L, 3461L, 3645L, 3716L, 3955L, 3362L,
                   2637L, 2524L, 2084L, 2031L, 2256L, 2401L, 3253L, 2881L,
                   2555L, 2585L, 3015L, 2608L, 3676L, 5763L, 4626L, 3848L,
                   4523L, 4186L, 4070L, 4000L, 3498L),
                 .Dim=c(29L, 1L),
                 .Dimnames=list(NULL, "CD"),
                 .Tsp=c(2012, 2014.33333333333, 12), class="ts")

insira a descrição da imagem aqui

A metodologia

1) A série pré-intervenção (até outubro de 2013) foi utilizada com a auto.arimafunção. O modelo sugerido foi ARIMA (1,0,0) com média diferente de zero. O gráfico da ACF parecia bom.

pre <- window(cds, start=c(2012, 01), end=c(2013, 09))

mod.pre <- auto.arima(log(pre))

# Coefficients:
#          ar1  intercept
#       0.5821     7.9652
# s.e.  0.1763     0.0810
# 
# sigma^2 estimated as 0.02709:  log likelihood=7.89
# AIC=-9.77   AICc=-8.36   BIC=-6.64

2) Dado o gráfico da série completa, a resposta de pulso foi escolhida abaixo, com T = outubro de 2013,

insira a descrição da imagem aqui

que de acordo com cryer e chan podem ser ajustados da seguinte forma com a função arimax:

mod.arimax <- arimax(log(cds), order=c(1, 0, 0),
                     seasonal=list(order=c(0, 0, 0), frequency=12),
                     include.mean=TRUE,
                     xtransf=data.frame(Oct13=1 * (seq(cds) == 22)),
                     transfer=list(c(1, 1)))
mod.arimax

# Series: log(cds) 
# ARIMA(1,0,0) with non-zero mean 
# 
# Coefficients:
#          ar1  intercept  Oct13-AR1  Oct13-MA0  Oct13-MA1
#       0.7619     8.0345    -0.4429     0.4261     0.3567
# s.e.  0.1206     0.1090     0.3993     0.1340     0.1557
# 
# sigma^2 estimated as 0.02289:  log likelihood=12.71
# AIC=-15.42   AICc=-11.61   BIC=-7.22

Os resíduos disso pareceram OK:

insira a descrição da imagem aqui

O enredo dos dados ajustados e reais:

plot(fitted(mod.arimax), col="red", type="b")
lines(window(log(cds), start=c(2012, 02)), type="b")

insira a descrição da imagem aqui

As questões

1) Esta metodologia está correta para a análise de intervenção?

2) Posso analisar a estimativa / SE dos componentes da função de transferência e dizer que o efeito da intervenção foi significativo?

3) Como se pode visualizar o efeito da função de transferência (plot it?)

4) Existe uma maneira de estimar quanto a intervenção aumentou a produção após 'x' meses? Eu acho que para isso (e talvez # 3) estou perguntando como trabalhar com uma equação do modelo - se isso fosse regressão linear simples com variáveis ​​dummy (por exemplo) eu poderia executar cenários com e sem a intervenção e medir o impacto - mas não tenho certeza de como trabalhar com esse tipo de modelo.

ADICIONAR

Por solicitação, aqui estão os resíduos das duas parametrizações.

Primeiro do ajuste:

fit <- arimax(log(cds), order=c(1, 0, 0),
              xtransf=
              data.frame(Oct13a=1 * (seq_along(cds) == 22),
                         Oct13b=1 * (seq_along(cds) == 22)),
              transfer=list(c(0, 0), c(1, 0)))

plot(resid(fit), type="b")

insira a descrição da imagem aqui

Então, a partir deste ajuste

mod.arimax <- arimax(log(cds), order=c(1, 0, 0),
                     seasonal=list(order=c(0, 0, 0), frequency=12),
                     include.mean=TRUE,
                     xtransf=data.frame(Oct13=1 * (seq(cds) == 22)),
                     transfer=list(c(1, 1))) 

mod.arimax
plot(resid(mod.arimax), type="b")

insira a descrição da imagem aqui

B_Miner
fonte
Tudo bem se eu fornecer uma solução usando o software SAS?
forecaster
Claro, eu ficaria curioso se você criar um modelo melhor.
B_Miner
Ok, o modelo é um pouco melhor do que o proposto originalmente, mas é semelhante ao @javlacalle.
forecaster

Respostas:

12

Um modelo AR (1) com a intervenção definida na equação dada na pergunta pode ser ajustado como mostrado abaixo. Observe como o argumento transferé definido; você também precisa de uma variável indicadora xtransfpara cada uma das intervenções (o pulso e a mudança transitória):

require(TSA)
cds <- structure(c(2580L, 2263L, 3679L, 3461L, 3645L, 3716L, 3955L, 3362L,
                   2637L, 2524L, 2084L, 2031L, 2256L, 2401L, 3253L, 2881L,
                   2555L, 2585L, 3015L, 2608L, 3676L, 5763L, 4626L, 3848L,
                   4523L, 4186L, 4070L, 4000L, 3498L),
                 .Dim = c(29L, 1L),
                 .Dimnames = list(NULL, "CD"),
                 .Tsp = c(2012, 2014.33333333333, 12),
                 class = "ts")

fit <- arimax(log(cds), order = c(1, 0, 0), 
              xtransf = data.frame(Oct13a = 1 * (seq_along(cds) == 22), 
                                   Oct13b = 1 * (seq_along(cds) == 22)),
              transfer = list(c(0, 0), c(1, 0)))
fit
# Coefficients:
#          ar1  intercept  Oct13a-MA0  Oct13b-AR1  Oct13b-MA0
#       0.5599     7.9643      0.1251      0.9231      0.4332
# s.e.  0.1563     0.0684      0.1911      0.1146      0.2168
# sigma^2 estimated as 0.02131:  log likelihood = 14.47,  aic = -18.94

Você pode testar a significância de cada intervenção observando a estatística t dos coeficientes e . Para maior comodidade, você pode usar a função .ω 1ω0ω1coeftest

require(lmtest)
coeftest(fit)
#            Estimate Std. Error  z value  Pr(>|z|)    
# ar1        0.559855   0.156334   3.5811 0.0003421 ***
# intercept  7.964324   0.068369 116.4896 < 2.2e-16 ***
# Oct13a-MA0 0.125059   0.191067   0.6545 0.5127720    
# Oct13b-AR1 0.923112   0.114581   8.0564 7.858e-16 ***
# Oct13b-MA0 0.433213   0.216835   1.9979 0.0457281 *  
# ---
# Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Nesse caso, o pulso não é significativo no nível de significância de . Seu efeito já pode ser capturado pela mudança transitória.5%

O efeito da intervenção pode ser quantificado da seguinte forma:

intv.effect <- 1 * (seq_along(cds) == 22)
intv.effect <- ts(
  intv.effect * 0.1251 + 
  filter(intv.effect, filter = 0.9231, method = "rec", sides = 1) * 0.4332)
intv.effect <- exp(intv.effect)
tsp(intv.effect) <- tsp(cds)

Você pode plotar o efeito da intervenção da seguinte maneira:

plot(100 * (intv.effect - 1), type = "h", main = "Total intervention effect")

Efeito de intervenção total

O efeito é relativamente persistente porque é próximo de (se fosse igual a , observaríamos uma mudança permanente de nível). 1 ω 2 1ω21ω21

Numericamente, esses são os aumentos estimados quantificados em cada momento causado pela intervenção em outubro de 2013:

window(100 * (intv.effect - 1), start = c(2013, 10))
#           Jan      Feb      Mar      Apr      May Jun Jul Aug Sep      Oct
# 2013                                                              74.76989
# 2014 40.60004 36.96366 33.69046 30.73844 28.07132                         
#           Nov      Dec
# 2013 49.16560 44.64838

A intervenção aumenta o valor da variável observada em outubro de 2013 em cerca de . Nos períodos subsequentes, o efeito permanece, mas com um peso decrescente.75%

Também poderíamos criar as intervenções manualmente e passá-las para stats::arimaregressores externos. As intervenções são um pulso mais uma mudança transitória com o parâmetro e podem ser construídas da seguinte maneira.0.9231

xreg <- cbind(
  I1 = 1 * (seq_along(cds) == 22), 
  I2 = filter(1 * (seq_along(cds) == 22), filter = 0.9231, method = "rec", 
              sides = 1))
arima(log(cds), order = c(1, 0, 0), xreg = xreg)
# Coefficients:
#          ar1  intercept      I1      I2
#       0.5598     7.9643  0.1251  0.4332
# s.e.  0.1562     0.0671  0.1563  0.1620
# sigma^2 estimated as 0.02131:  log likelihood = 14.47,  aic = -20.94

As mesmas estimativas dos coeficientes acima são obtidas. Aqui, corrigimos para . A matriz é o tipo de variável dummy que você pode precisar para experimentar diferentes cenários. Você também pode definir valores diferentes para e comparar seu efeito. 0,9231 ω 2ω20.9231xregω2

Essas intervenções são equivalentes a um outlier aditivo (AO) e a uma mudança transitória (CT) definida no pacote tsoutliers. Você pode usar este pacote para detectar esses efeitos, como mostra a resposta do @forecaster, ou para criar os regressores usados ​​anteriormente. Por exemplo, neste caso:

require(tsoutliers)
mo <- outliers(c("AO", "TC"), c(22, 22))
oe <- outliers.effects(mo, length(cds), delta = 0.9231)
arima(log(cds), order = c(1, 0, 0), xreg = oe)
# Coefficients:
#          ar1  intercept    AO22    TC22
#       0.5598     7.9643  0.1251  0.4332
# s.e.  0.1562     0.0671  0.1563  0.1620
# sigma^2 estimated as 0.02131:  log likelihood=14.47
# AIC=-20.94   AICc=-18.33   BIC=-14.1

Editar 1

Vi que a equação que você deu pode ser reescrita como:

(ω0+ω1)ω0ω2B1ω2BPt

e pode ser especificado como você fez transfer=list(c(1, 1)).

Como mostrado abaixo, essa parametrização leva, neste caso, a estimativas de parâmetros que envolvem um efeito diferente em comparação com a parametrização anterior. Isso me lembra o efeito de uma discrepância inovadora, em vez de um pulso, mais uma mudança transitória.

fit2 <- arimax(log(cds), order=c(1, 0, 0), include.mean = TRUE, 
  xtransf=data.frame(Oct13 = 1 * (seq(cds) == 22)), transfer = list(c(1, 1)))
fit2
# ARIMA(1,0,0) with non-zero mean 
# Coefficients:
#          ar1  intercept  Oct13-AR1  Oct13-MA0  Oct13-MA1
#       0.7619     8.0345    -0.4429     0.4261     0.3567
# s.e.  0.1206     0.1090     0.3993     0.1340     0.1557
# sigma^2 estimated as 0.02289:  log likelihood=12.71
# AIC=-15.42   AICc=-11.61   BIC=-7.22

Não estou muito familiarizado com a notação de pacote, TSAmas acho que o efeito da intervenção agora pode ser quantificado da seguinte forma:

intv.effect <- 1 * (seq_along(cds) == 22)
intv.effect <- ts(intv.effect * 0.4261 + 
  filter(intv.effect, filter = -0.4429, method = "rec", sides = 1) * 0.3567)
tsp(intv.effect) <- tsp(cds)
window(100 * (exp(intv.effect) - 1), start = c(2013, 10))
#              Jan         Feb         Mar         Apr         May Jun Jul Aug
# 2014  -3.0514633   1.3820052  -0.6060551   0.2696013  -0.1191747            
#      Sep         Oct         Nov         Dec
# 2013     118.7588947 -14.6135216   7.2476455

plot(100 * (exp(intv.effect) - 1), type = "h", 
  main = "Intervention effect (parameterization 2)")

parametrização do efeito de intervenção 2

O efeito pode ser descrito agora como um aumento acentuado em outubro de 2013, seguido de uma diminuição na direção oposta; então o efeito da intervenção desaparece rapidamente, alternando efeitos positivos e negativos da queda de peso.

Esse efeito é um tanto peculiar, mas pode ser possível em dados reais. Neste ponto, eu examinaria o contexto dos seus dados e os eventos que podem ter afetado os dados. Por exemplo, houve uma mudança de política, campanha de marketing, descoberta ... que pode explicar a intervenção em outubro de 2013. Nesse caso, é mais sensato que esse evento tenha um efeito sobre os dados como descrito anteriormente ou como descobrimos com a parametrização inicial?

Segundo a AIC, o modelo inicial seria preferido por ser mais baixo ( contra ). O gráfico da série original não sugere uma correspondência clara com as mudanças bruscas envolvidas na medição da segunda variável de intervenção.- 15,4218.9415.42

Sem conhecer o contexto dos dados, eu diria que um modelo AR (1) com uma mudança transitória com o parâmetro seria apropriado para modelar os dados e medir a intervenção.0.9

Editar 2

O valor de determina a rapidez com que o efeito da intervenção cai para zero, então esse é o parâmetro-chave no modelo. Podemos inspecionar isso ajustando o modelo para um intervalo de valores de . Abaixo, o AIC é armazenado para cada um desses modelos.ω 2ω2ω2

omegas <- seq(0.5, 1, by = 0.01)
aics <- rep(NA, length(omegas))
for (i in seq(along = omegas)) {
  tc <- filter(1 * (seq_along(cds) == 22), filter = omegas[i], method = "rec", 
               sides = 1)
  tc <- ts(tc, start = start(cds), frequency = frequency(cds))
  fit <- arima(log(cds), order = c(1, 0, 0), xreg = tc)
  aics[i] <- AIC(fit)
}
omegas[which.min(aics)]
# [1] 0.88

plot(omegas, aics, main = "AIC for different values of the TC parameter")

AIC para diferentes valores de ômega

O AIC mais baixo é encontrado para (de acordo com o valor estimado anteriormente). Este parâmetro envolve um efeito relativamente persistente, mas transitório. Podemos concluir que o efeito é temporário, pois com valores superiores a a AIC aumenta (lembre-se de que no limite , a intervenção se torna uma mudança permanente de nível).0,9 ω 2 = 1ω2=0.880.9ω2=1

A intervenção deve ser incluída nas previsões. Obter previsões para períodos que já foram observados é um exercício útil para avaliar o desempenho das previsões. O código abaixo supõe que a série termine em outubro de 2013. As previsões são obtidas incluindo a intervenção com o parâmetro .ω2=0.9

Primeiro, modelo AR (1) com a intervenção como regressor (com o parâmetro ):ω2=0.9

tc <- filter(1 * (seq.int(length(cds) + 12) == 22), filter = 0.9, method = "rec", 
             sides = 1)
tc <- ts(tc, start = start(cds), frequency = frequency(cds))
fit <- arima(window(log(cds), end = c(2013, 10)), order = c(1, 0, 0), 
             xreg = window(tc, end = c(2013, 10)))

As previsões podem ser obtidas e exibidas da seguinte forma:

p <- predict(fit, n.ahead = 19, newxreg = window(tc, start = c(2013, 11)))

plot(cbind(window(cds, end = c(2013, 10)), exp(p$pred)), plot.type = "single", 
     ylab = "", type = "n")
lines(window(cds, end = c(2013, 10)), type = "b")
lines(window(cds, start = c(2013, 10)), col = "gray", lty = 2, type = "b")
lines(exp(p$pred), type = "b", col = "blue")
legend("topleft",
       legend = c("observed before the intervention",
           "observed after the intervention", "forecasts"),
       lty = rep(1, 3), col = c("black", "gray", "blue"), bty = "n")

valores observados e previstos

As primeiras previsões correspondem relativamente bem aos valores observados (linha pontilhada cinza). As previsões restantes mostram como a série continuará o caminho para a média original. No entanto, os intervalos de confiança são grandes, refletindo a incerteza. Portanto, devemos ter cuidado e revisar o modelo à medida que novos dados são registrados.

95%Intervalos de confiança de podem ser adicionados ao gráfico anterior da seguinte maneira:

lines(exp(p$pred + 1.96 * p$se), lty = 2, col = "red")
lines(exp(p$pred - 1.96 * p$se), lty = 2, col = "red")
javlacalle
fonte
Isso é ótimo, obrigado! Eu tive alguns acompanhamentos, se você não se importa. 1) O processo que segui está correto? 2) Você consideraria o ajuste do modelo "bom o suficiente" para usar as estimativas para quantificar o efeito da intervenção? 3) Não devo usar minha parametrização, ou seja, transfer = list (c (1,1)) como equivalente e obter resultados bem próximos? O exemplo que eu estava seguindo de um livro sugeriu que eu deveria ser capaz de, mas neste exemplo, os resultados não estão perto ...
B_Miner
@B_Miner Você está certo, eu editei minha resposta.
Javlacalle
Concordo com você que, nos dois modelos, a primeira parametrização (talvez com o pulso não significativo removido) seria o melhor ajuste. Por que as duas parametrizações não produzem o mesmo modelo, quando acredito que deveriam, é um mistério. Vou enviar um email ao desenvolvedor do pacote (que também escreveu o livro que menciona sua equivalência).
B_Miner
Os dados são o número de certificados de depósitos abertos por mês. A intervenção foi um aumento na taxa de juros média, que aumentou a partir de 13 de outubro. O nível da taxa de juros permaneceu relativamente constante desde 13 de outubro. Pareceu-me que, após o aumento, a demanda pelo produto começou a diminuir. Não tenho certeza se ele retornará à média anterior ou se estabilizará em algum nível elevado (do anterior).
B_Miner
B_miner, com base nos dados que não podemos realmente concluir, se a demanda se estabilizar para uma nova média.
forecaster
4

As vezes menos é mais. Com 30 observações em mãos, enviei os dados para o AUTOBOX, um software que ajudei a desenvolver. Submeto a seguinte análise na esperança de obter a recompensa de +200 (apenas brincando!). Plotamos os Valores Reais e Limpados sugerindo visualmente o impacto da "atividade recente". insira a descrição da imagem aqui. O modelo que foi desenvolvido automaticamente é mostrado aqui. insira a descrição da imagem aquie aqui insira a descrição da imagem aqui. Os resíduos dessa série bastante simples de deslocamento de nível são apresentados aqui insira a descrição da imagem aqui. As estatísticas do modelo estão aqui insira a descrição da imagem aqui. Em resumo, houve intervenções que poderiam ser identificadas empiricamente, renderizando um processo ARIMA; dois pulsos e uma mudança de nível insira a descrição da imagem aqui. O gráfico Real / Ajuste e Previsão destaca ainda mais a análise.insira a descrição da imagem aqui

Eu, pelo menos, gostaria de ver o gráfico dos resíduos dos modelos especificados anteriormente e, na minha opinião, modelos potencialmente especificados em excesso.

IrishStat
fonte
Eu não estou familiarizado com a Autobox, mas o ruído faz parte do modelo igual ao que eu originalmente: uma média diferente de zero e um AR (1)?
B_Miner
Esta saída está dizendo que a única "intervenção" no período de 13 de outubro até o período atual é um pulso único para 13 de outubro e, em seguida, a série retorna ao seu nível médio normal?
B_Miner
Eu adicionei os resíduos de ambas as parametrizações. A meu ver, parece que o primeiro que listei (o originalmente adequado para javlacalle) é melhor. Aceita?
B_Miner
1) A parte de ruído é um AR (1) com um não-média zero
IrishStat
1) A parte do ruído é um AR (1) com uma média diferente de zero; 2) Existem 2 intervenções período 22 e período 3 e após 13 de outubro, ele retorna a um novo nível que começou no 13 de setembro; 3) Dada a escolha entre as duas que você mencionou, concordo, MAS prefiro o modelo AUTOBOX por sua simplicidade e eficiência. Você pode descobrir mais sobre a AUTOBOX em autobox.com/cms
IrishStat
3

Com base em minha postagem semelhante à sua pergunta anterior, usei a função tso no pacote tsoutliers no e ele detectou automaticamente uma mudança temporária em outubro de 2013. Observe que a mudança temporária é diferente do deslocamento da rampa na função de transferência, que é o que você procura. Eu não acho que exista um pacote / função que eu saiba que seria capaz de visualizar a função de transferência. Espero que isso forneça algumas idéias. Não usei a transformação de log, modelei-a diretamente. O pacote tsoutliers pode ser pensado como uma detecção automática de intervenção.R

Abaixo está o código:

cds<- structure(c(2580L, 2263L, 3679L, 3461L, 3645L, 3716L, 3955L, 
                  3362L, 2637L, 2524L, 2084L, 2031L, 2256L, 2401L, 3253L, 2881L, 
                  2555L, 2585L, 3015L, 2608L, 3676L, 5763L, 4626L, 3848L, 4523L, 
                  4186L, 4070L, 4000L, 3498L), .Dim = c(29L, 1L), .Dimnames = list(
                    NULL, "CD"), .Tsp = c(2012, 2014.33333333333, 12), class = "ts")
arimatr <- tsoutliers::tso(cds,args.tsmethod=list(d=0,D=0))
plot(arimatr)
arimatr

Abaixo está a estimativa, houve um aumento de ~ 2356,3 unidades em outubro de 2013 com um erro padrão de ~ 481,8 e, posteriormente, teve um efeito decadente. A função identificou automaticamente AR (1). Eu tive que fazer algumas iterações e fazer a diferença sazonal e não sazonal para 0, o que é refletido no método args.tsmet na função tso.

Series: cds 
ARIMA(1,0,0) with non-zero mean 

Coefficients:
         ar1  intercept       TC22
      0.5969  3034.6560  2356.2914
s.e.  0.1495   206.5202   481.7981

sigma^2 estimated as 209494:  log likelihood=-219.03
AIC=446.06   AICc=447.73   BIC=451.53

Outliers:
  type ind    time coefhat tstat
1   TC  22 2013:10    2356 4.891

Abaixo está o gráfico, tsoutlier é o único pacote que eu conheço que pode imprimir mudanças temporárias tão bem em um gráfico.

insira a descrição da imagem aqui

Esperamos que esta análise tenha respondido às suas 2, 3 e 4 perguntas, embora usando uma metodologia diferente. Especialmente a plotagem e os coeficientes forneceram o efeito dessa intervenção e o que teria acontecido se você não tivesse essa intervenção.

Também espero que alguém possa replicar esse gráfico / análise usando a modelagem da função de transferência em R.

previsor
fonte
Obrigado. Sim, esse gráfico é o que eu gostaria de fazer com o modelo arimax - veja com e sem a intervenção (e subtraia). Eu acho que a função de filtro em R pode ser usada para gerar o valor da função de transferência para cada mês (e depois plotar para visualizar), mas não consigo descobrir como fazê-lo para uma função de intervenção de pulso arbitrária.
B_Miner