12.7 Tratamento de séries temporais

12.7.1 Estatísticas móveis

Estatísticas móveis são úteis para suavizar curvas e auxiliar na modelagem de dados temporais.

  • Médias móveis são calculadas pela função ma() de forecast (Rob J. Hyndman and Khandakar 2008) e rollmean() de zoo (Zeileis and Grothendieck 2005b)
  • zoo também fornece a função rollapply(), além de outras funções específicas de estatísticas móveis.
  • slider (Vaughan 2023) fornece funções estáveis de janela móvel para qualquer tipo de dados R.
  • tsibble (E. Wang, Cook, and Hyndman 2020b) fornece as funções slide_tsibble() para estatísticas móveis e tile_tsibble() para janelas móveis não sobrepostas.
  • tbrf (Time-Based Rolling Functions) (Schramm 2020) fornece funções de estatísticas móveis com base em janelas de data e hora, em vez de observações com \(n\) defasagens.
  • roll (Foster 2020) fornece funções eficiente de estatísticas móveis e de expansão para dados de séries temporais.
  • runner (Kałędkowski 2024) permite controlar o comprimento da janela, o atraso da janela e os índices de tempo, permitindo aplicar qualquer função R em janelas móveis em séries temporais com espaçamento igual e desigual.
  • runstats (Karas and Urbanek 2019) fornece métodos computacionais rápidos para algumas estatísticas móveis.
  • Para data.table (Barrett et al. 2024), froll() pode ser usada para estatísticas móveis de alto desempenho.

Segundo a documentação, forecast::ma() implementa a equação

\[\begin{equation} \widehat{T}_t = \frac{1}{m} \sum_{j=-k}^{k} y_{t+j} \tag{12.1} \end{equation}\]

onde \(m\) é a ordem, \(k=\lceil \frac{m-1}{2} \rceil\) e \(t=1+k,\ldots,n-k\). O número de valores de \(\widehat{T}_t\) não NA é \(n-2k\) (por quê?). “[Q]uando uma ordem (\(m\)) par é especificada, a média das observações incluirá mais uma observação do futuro do que do passado (k é arredondado para cima). Se centre for TRUE, será calculada a média do valor de duas médias móveis (onde k é arredondado para cima e para baixo, respectivamente), centralizando a média móvel.”

Não há detalhes da implementação na documentação de zoo::rollmean().

Exemplo 12.4 Pode-se calcular a média móvel de variadas ordens da sequência 5 6 2 5 3 3 4 1 4 4.

set.seed(42); x <- rpois(10,3)
for(m in 2:9){
  fc <- forecast::ma(x,m)
  print(paste0('m = ', m))
  print(round(zoo::coredata(fc),3))
}
## [1] "m = 2"
##  [1]   NA 4.75 3.75 3.75 3.50 3.25 3.00 2.50 3.25   NA
## [1] "m = 3"
##  [1]    NA 4.333 4.333 3.333 3.667 3.333 2.667 3.000 3.000    NA
## [1] "m = 4"
##  [1]    NA    NA 4.250 3.625 3.500 3.250 2.875 3.125    NA    NA
## [1] "m = 5"
##  [1]  NA  NA 4.2 3.8 3.4 3.2 3.0 3.2  NA  NA
## [1] "m = 6"
##  [1]    NA    NA    NA 3.917 3.417 3.167 3.250    NA    NA    NA
## [1] "m = 7"
##  [1]    NA    NA    NA 4.000 3.429 3.143 3.429    NA    NA    NA
## [1] "m = 8"
##  [1]    NA    NA    NA    NA 3.562 3.375    NA    NA    NA    NA
## [1] "m = 9"
##  [1]    NA    NA    NA    NA 3.667 3.556    NA    NA    NA    NA

Exemplo 12.5 Considere a série temporal fpp2::h02.

library(fpp2)
plot(h02)
sm1 <- forecast::ma(h02, order = 12)
sm2 <- zoo::rollmean(h02, k = 12)
lines(sm1, col = 'red2', lwd = 2)
lines(sm2, col = 'blue2', lwd = 2)
legend('topleft', legend = c('Original','forecast::ma','zoo::rollmean'), 
       fill = c('black','red2','blue2'), cex = .8)

Pode-se implementar a média móvel a partir da Eq. (12.1).

# versão 1: ordem ímpar
mm <- function(x, m){
  n <- length(x)
  k <- ceiling((m-1)/2)
  Tt <- vector(length = n)
  for(i in (1+k):(n-k)){
    Tt[i] <- sum(x[(i-k):(i+k)])/m
  }
  return(Tt)
}
mm(h02, 3)
##   [1] 0.0000000 0.4209533 0.4418693 0.4756903 0.5325213 0.5883800 0.5329970 0.4492290 0.3557920 0.3643190 0.3840477 0.4185746
##  [13] 0.4564620 0.4978710 0.5262769 0.5661968 0.6450291 0.7059946 0.6367716 0.5221135 0.4095759 0.4233441 0.4376251 0.4693983
##  [25] 0.5125930 0.5563889 0.5976347 0.6446888 0.7652110 0.8273371 0.7400252 0.5877055 0.4714274 0.4957696 0.5072337 0.5364430
##  [37] 0.5904949 0.6389561 0.6828138 0.7056310 0.7481011 0.7859079 0.6972261 0.6103144 0.5183128 0.5469766 0.5591118 0.5911204
##  [49] 0.6509828 0.6964475 0.7606707 0.7850614 0.8521552 0.8926462 0.7975635 0.6751258 0.5553244 0.5840463 0.5956626 0.6389582
##  [61] 0.6738164 0.7238614 0.7562269 0.7792404 0.8548290 0.8688218 0.7605818 0.5986431 0.4923848 0.5252227 0.5596552 0.6067957
##  [73] 0.6453481 0.7034898 0.7469043 0.7777470 0.8548783 0.8551519 0.7618303 0.6051699 0.5172049 0.5377160 0.5640352 0.6122339
##  [85] 0.6542288 0.7180711 0.7525306 0.7975084 0.8584550 0.8946075 0.7945032 0.6862578 0.5798894 0.6220702 0.6390289 0.7045862
##  [97] 0.7735687 0.8365210 0.8789382 0.9126365 0.9652959 0.9892145 0.8645515 0.7204847 0.6035980 0.6342373 0.6702417 0.7491981
## [109] 0.8161231 0.8490327 0.8822180 0.9064219 0.9690138 0.9984752 0.8558257 0.7423405 0.6105621 0.6750513 0.6840052 0.7518238
## [121] 0.8196873 0.8756918 0.9331475 1.0004425 1.0487321 1.0892570 0.9112551 0.7875389 0.6322037 0.6963217 0.7332988 0.8126993
## [133] 0.8648423 0.9518763 0.9881804 1.0156566 1.0455159 1.0625722 0.9197389 0.7665915 0.6283323 0.6857389 0.7382097 0.8225409
## [145] 0.8779978 0.9726356 1.0507313 1.0953818 1.1415737 1.1347327 1.0071161 0.8490427 0.7189963 0.7613763 0.7973058 0.8845082
## [157] 0.9510868 1.0436298 1.1034358 1.1771600 1.2180953 1.2146550 1.0085223 0.8069730 0.6402447 0.6727810 0.7360053 0.8039490
## [169] 0.9076987 0.9918563 1.0427587 1.0903370 1.1123290 1.1802117 0.9928460 0.8415950 0.6445783 0.7180017 0.7483387 0.8298957
## [181] 0.9106433 0.9765563 1.0712033 1.0906667 1.1321147 1.1504700 0.9803750 0.8418233 0.6213037 0.6704720 0.7149840 0.8457787
## [193] 0.9567658 1.0477817 1.0997267 1.1281650 1.1500341 1.1866881 1.0527840 0.8770660 0.7463813 0.7645257 0.8020930 0.0000000
coredata(forecast::ma(h02, order = 3))
##   [1]        NA 0.4209533 0.4418693 0.4756903 0.5325213 0.5883800 0.5329970 0.4492290 0.3557920 0.3643190 0.3840477 0.4185746
##  [13] 0.4564620 0.4978710 0.5262769 0.5661968 0.6450291 0.7059946 0.6367716 0.5221135 0.4095759 0.4233441 0.4376251 0.4693983
##  [25] 0.5125930 0.5563889 0.5976347 0.6446888 0.7652110 0.8273371 0.7400252 0.5877055 0.4714274 0.4957696 0.5072337 0.5364430
##  [37] 0.5904949 0.6389561 0.6828138 0.7056310 0.7481011 0.7859079 0.6972261 0.6103144 0.5183128 0.5469766 0.5591118 0.5911204
##  [49] 0.6509828 0.6964475 0.7606707 0.7850614 0.8521552 0.8926462 0.7975635 0.6751258 0.5553244 0.5840463 0.5956626 0.6389582
##  [61] 0.6738164 0.7238614 0.7562269 0.7792404 0.8548290 0.8688218 0.7605818 0.5986431 0.4923848 0.5252227 0.5596552 0.6067957
##  [73] 0.6453481 0.7034898 0.7469043 0.7777470 0.8548783 0.8551519 0.7618303 0.6051699 0.5172049 0.5377160 0.5640352 0.6122339
##  [85] 0.6542288 0.7180711 0.7525306 0.7975084 0.8584550 0.8946075 0.7945032 0.6862578 0.5798894 0.6220702 0.6390289 0.7045862
##  [97] 0.7735687 0.8365210 0.8789382 0.9126365 0.9652959 0.9892145 0.8645515 0.7204847 0.6035980 0.6342373 0.6702417 0.7491981
## [109] 0.8161231 0.8490327 0.8822180 0.9064219 0.9690138 0.9984752 0.8558257 0.7423405 0.6105621 0.6750513 0.6840052 0.7518238
## [121] 0.8196873 0.8756918 0.9331475 1.0004425 1.0487321 1.0892570 0.9112551 0.7875389 0.6322037 0.6963217 0.7332988 0.8126993
## [133] 0.8648423 0.9518763 0.9881804 1.0156566 1.0455159 1.0625722 0.9197389 0.7665915 0.6283323 0.6857389 0.7382097 0.8225409
## [145] 0.8779978 0.9726356 1.0507313 1.0953818 1.1415737 1.1347327 1.0071161 0.8490427 0.7189963 0.7613763 0.7973058 0.8845082
## [157] 0.9510868 1.0436298 1.1034358 1.1771600 1.2180953 1.2146550 1.0085223 0.8069730 0.6402447 0.6727810 0.7360053 0.8039490
## [169] 0.9076987 0.9918563 1.0427587 1.0903370 1.1123290 1.1802117 0.9928460 0.8415950 0.6445783 0.7180017 0.7483387 0.8298957
## [181] 0.9106433 0.9765563 1.0712033 1.0906667 1.1321147 1.1504700 0.9803750 0.8418233 0.6213037 0.6704720 0.7149840 0.8457787
## [193] 0.9567658 1.0477817 1.0997267 1.1281650 1.1500341 1.1866881 1.0527840 0.8770660 0.7463813 0.7645257 0.8020930        NA

Exercício 12.8 Implemente uma função que calcule a média móvel para ordens pares e ímpares, conforme Eq (12.1).

12.7.2 Decomposição

A partir de “[u]ma pesquisa preliminar de gráficos de séries mensais fundamentais como compensações bancárias, produção de ferro, preços de commodities e novas licenças de construção”, (Persons 1919, 8) considera que cada série temporal “é um composto que consiste em quatro tipos de flutuações”:

  1. Uma tendência de longo prazo ou tendência secular;
  2. Um movimento cíclico ou em forma de onda sobreposto à tendência secular;
  3. Um movimento sazonal dentro do ano com uma forma característica para cada série;
  4. Variações residuais devido a desenvolvimentos que afetam séries individuais.

Diferença entre ciclo e sazonalidade

Segundo o artigo Cyclic and seasonal time series de Rob Hyndman, “sazonalidade é sempre de um período fixo e conhecido”, enquanto “um padrão cíclico existe quando os dados apresentam altas e baixas que não são de período fixo”. Ainda segundo Hyndman, “[e]m geral a duração média dos ciclos é maior que a duração de um padrão sazonal, e a magnitude dos ciclos tende a ser mais variável que a magnitude dos padrões sazonais”.

Diferença entre tendência estocástica e determinística

De acordo com a Seção 10.4 Stochastic and deterministic trends de (Rob J. Hyndman and Athanasopoulos 2021), “[h]á uma suposição implícita com tendências determinísticas de que a inclinação da tendência não vai mudar ao longo do tempo. Por outro lado, tendências estocásticas podem mudar, e o crescimento estimado é assumido apenas como o crescimento médio ao longo do período histórico, não necessariamente a taxa de crescimento que será observada no futuro. Consequentemente, é mais seguro prever com tendências estocásticas, especialmente para horizontes de previsão mais longos, pois os intervalos de previsão permitem maior incerteza no crescimento futuro”.

12.7.2.1 stats::decompose()

A função stats::decompose() por David Meyer está baseada em (Kendall and Stuart 1983). Decompõe uma série temporal em componentes de tendência, sazonais (aditivos ou multiplicativos) e residuais (irregulares) usando médias móveis. Os modelos aditivo e multiplicativo são respectivamente

\[\begin{equation} y_t = T_t + S_t + R_t \tag{12.2} \end{equation}\]

\[\begin{equation} y_t = T_t S_t R_t \tag{12.3} \end{equation}\]

A biblioteca statsmodel (Seabold and Perktold 2010) do Python fornece ferramentas para decompor uma série temporal via médias móveis.

library(fpp2)
plot(stats::decompose(h02))

A partir da Seção 3.4 Classical Decomposition de (Rob J. Hyndman and Athanasopoulos 2021) apresenta-se o algortimo de decomposição aditiva.


Decomposição aditiva

Passo 1
Calcule \(\widehat{T}_t\) conforme Eq. (12.1).

Passo 2
Calcule a série sem tendência: \(\widehat{SST}_t = y_t-\widehat{T}_t\).

Passo 3
Calcule a média dos valores sem tendência para cada ciclo. Ajuste para garantir soma zero. Replique os períodos para todos os anos, resultando em \(\widehat{S}_t\).

Passo 4
O componente restante é calculado subtraindo os componentes sazonais e de ciclo de tendência estimados: \(\widehat{R}_t= y_t - \widehat{T}_t - \widehat{S}_t\).


Exemplo 12.6 Reproduzindo os passos da decomposição aditiva.

# Passo 0 - série original
yt <- fpp2::h02
f <- frequency(yt) # ciclo
s <- start(yt)     # início
e <- end(yt)       # fim
# Passo 1 - média móvel
Tt <- forecast::ma(yt, order = f)
# Passo 2 - série sem tendência
SSTt <- yt-Tt
# Passo 3 - média padronizada por ciclo
mc <- vector(length = f) # média por ciclo
for(i in 1:f){
  fltr <- seq(from = i, by = f, length.out = ceiling(length(yt)/f))
  ifelse((s[2]+i-1) > f, indx <- (s[2]+i-1) %% f, indx <- (s[2]+i-1))
  mc[indx] <- mean(SSTt[fltr], na.rm = TRUE)
}
if(s[2] == 1){
 indx <- 1:f
} else{
  indx <- c((s[2]:f),1:(s[2]-1))
}
mc0 <- mc-mean(mc) # média padronizada por ciclo
St <- rep(mc0[indx], ceiling(length(yt)/f)) # replicando para todos os anos
St <- ts(St, start = s, end = e, frequency = f)
# Passo 4
Rt <- yt-Tt-St
# Gráficos
par(mfrow=c(2,2))
plot(yt, type = 'l', main = 'Série original')
plot(Tt, type = 'l', main = 'Tendência')
plot(St, type = 'l', main = 'Sazonalidade')
plot(Rt, type = 'l', main = 'Resíduo')

# Comparando com decompose()
d <- decompose(yt)
all.equal(d$x, yt)        # série original
## [1] TRUE
all.equal(d$trend, Tt)    # tendência
## [1] TRUE
all.equal(d$seasonal, St) # sazonalidade
## [1] TRUE
all.equal(d$random, Rt)   # resíduo
## [1] TRUE

Exercício 12.9 Considere a decomposição aditiva.

  1. Implemente em Python.
  2. Compare com statsmodel.
  3. Compare com stats::decompose().

12.7.2.2 stats::stl()

A função stats::stl() (Seasonal Trend Loess) é baseada em (Cleveland et al. 1990), e também decompõe uma série temporal em componentes de tendência, sazonais e irregulares, porém utilizando stats::loess() (LOcally Estimated Scatterplot Smoothing).

A biblioteca statsmodel (Seabold and Perktold 2010) do Python fornece ferramentas para decompor uma série temporal via LOESS.

autoplot(stats::stl(h02, 'per'))

12.7.2.3 X-13ARIMA-SEATS

(Sax and Eddelbuettel 2018) apresentam a biblioteca seasonal, cuja função principal seas() aplica os procedimentos automáticos X-13ARIMA-SEATS para realizar um ajuste sazonal bastante geral. De acordo com (U.S. Census Bureau 2023), o programa de ajuste sazonal X-13ARIMA-SEATS é uma versão aprimorada da Variante X-11 do Programa de Ajustamento Sazonal do Método II do Censo18 (Shiskin, Young, and Musgrave 1967). Para uma abordagem mais didática recomenda-se (Dagum and Bianconcini 2016).

A biblioteca statsmodel (Seabold and Perktold 2010) do Python fornece ferramentas para identificação automática da ordem do ARIMA sazonais usando ARIMA x12/x13, bem como para a execução da análise X13-ARIMA para dados mensais ou trimestrais.

library(seasonal)
par(mfrow=c(1,2))
autoplot(seasonal::seas(h02)) # X-13ARIMA-SEATS (padrão)

autoplot(seasonal::seas(h02, x11 = '')) # X-11

12.7.3 Diferenças

Differencing provides a simple aproach to removing, rather than highlighting, trends in time-series data. (Diggle 1990, 31)

O número de diferenças necessárias para eliminar a tendência indica a ordem \(d\) do \(ARIMA(p,d,q)\).

A primeira diferença de uma série temporal \(y_{t}\) (backward difference operator) é definida por \[\begin{equation} \nabla y_{t} = y_{t} - y_{t-1} \tag{12.4} \end{equation}\]

A segunda diferença de uma série temporal \(y_{t}\) é definida por \[\begin{equation} \nabla^{2}y_{t} = \nabla(\nabla y_{t}) = \nabla y_{t} - \nabla y_{t-1} = y_{t} - 2y_{t-1} + y_{t-2} \tag{12.5} \end{equation}\]

A função base::diff retorna diferenças adequadamente defasadas e iteradas.

d <- base::diff(h02)
d2 <- base::diff(h02, differences = 2)
plot(h02, main = 'Original')

plot(d, main = 'Uma diferença')

plot(d2, main = 'Duas diferenças')

12.7.3.1 Operador Backshift

The backward shift operator: a convenient notational shorthand. (Diggle 1990, 72)

\[\begin{equation} B^m y_{t} = y_{t-m} \tag{12.6} \end{equation}\]

Note que \(\nabla y_t = (1-B)y_{t}\) e \(\nabla^2 y_t = (1-2B+B^2)y_{t}\).

Exercício 12.10 Veja a Seção Backshift notation de (Rob J. Hyndman and Athanasopoulos 2021).

Exercício 12.11 Expanda as seguintes expressões ou modelos.

  1. \(B^{3}y_t\)
  2. \((1-B^{2})y_t\)
  3. \((1-B)^{2}y_t\)

Exercício 12.12 Escreva em notação backshift.

  1. \(y_t + y_{t-1} + y_{t-2}\)
  2. \(y_t - 2y_{t-3} + y_{t-12}\)
  3. \(y_{t-3} + 2y_{t-6} + y_{t-12}\)

12.7.4 Suavizadores de Tukey

As a fitting process, it leads to the general relation data = fit PLUS residuals which here can be written given data = smooth PLUS rough. (Tukey 1977, 208)

A função stats::smooth() aplica os suavizadores (de mediana) de Tukey 3, 3R, S, 3RSS e 3RS3R conforme (Tukey 1977, 205–36).

  • 3 é a notação curta de Tukey para medianas móveis de comprimento 3
  • 3R 3 Repetido até convergência (3-ing it to the death) (Tukey 1977, 230)
  • S divisão de trechos horizontais de comprimento 2 ou 3
  • SR divisão até convergência (split it to the death)

Exemplo 12.7 Será considerado o conjunto de 13 observações discutido na Seção 7.A Medians of 3 de (Tukey 1977, 210).

Dado 3 Resto 3 3R Resto 3R
4 NA NA NA NA
7 7 0 NA NA
9 7 2 7 2
3 4 -1 4 -1
4 4 1 4 0
11 11 0 11 0
12 12 0 12 0
1304 12 1292 12 1292
10 15 -5 12 -2
15 12 3 13 3
12 13 -1 13 -1
13 13 0 NA NA
17 NA NA NA NA
tk210 <- c(4,7,9,3,4,11,12,1304,10,15,12,13,17)
(s3 <- stats::smooth(tk210, '3')) # suavizado por mediana de 3
## 3 Tukey smoother resulting from  stats::smooth(x = tk210, kind = "3") 
##  used 1 iterations
##  [1]  7  7  7  4  4 11 12 12 15 12 13 13 13
stats::smooth(s3, '3') # suavizado por mediana de 3 pela segunda vez
## 3 Tukey smoother resulting from  stats::smooth(x = s3, kind = "3") 
##  used 1 iterations
##  [1]  7  7  7  4  4 11 12 12 12 13 13 13 13
stats::smooth(tk210, '3R') # 3R
## 3R Tukey smoother resulting from  stats::smooth(x = tk210, kind = "3R") 
##  used 2 iterations
##  [1]  7  7  7  4  4 11 12 12 12 13 13 13 13

Exercício 12.13 Considere os conjuntos de dados de produção de carvão e depósitos suspensos descritos por (Tukey 1977, 212).

  1. Obtenha a suavização por mediana de 3.
  2. Obtenha 3R.
  3. Faça o gráfico dos pontos originais e suavizados.
  4. Verifique quantas suavizações são necessárias para a convergência.
coal <- read.csv('https://filipezabala.com/data/coal.csv')
depo <- read.csv('https://filipezabala.com/data/deposits.csv')

12.7.5 Filtro de Kalman

An important class of theoretical and practical problems in communication and control is of a statistical nature. Such problems are: (i) Prediction of random signals; (ii) separation of random signals from random noise; (iii) detection of signals of known form (pulses, sinusoids) in the presence of random noise. (R. Kálmán 1960, 35)

O filtro de Kalman “é um procedimento recursivo para calcular o estimador ótimo do vetor de estado no tempo \(t\), com base nas informações disponíveis no tempo \(t\)19 (Harvey 1989, 104).

Conforme asserta a Lei da Eponímia de Stigler (Stigler 1980), o método foi desenvolvido e redescoberto em diferentes momentos da história, desde os achados de Thorvald N. Thiele (Thiele 1880) – que de acordo com (Lauritzen 1981) formulou e analisou o procedimento atualmente conhecido como filtro de Kalman – passando por Ruslan L. Stratonovich (Stratonovich 1957), Peter Swerling (Swerling 1958), dentre outros, até chegar aos populares trabalhos de Rudolf E. Kálmán (R. Kálmán 1960) e Richard S. Bucy (R. E. Kálmán and Bucy 1961). Para uma perspectiva bayesiana, veja (West and Harrison 2006) e (Gurajala et al. 2021).

Serão adotadas a estrutura e notação de (Harvey 1989), que admite que para certos enfoques “é necessário apenas entender o que o filtro faz, e não como ele faz”20, e reforça que “aqueles interessados principalmente nos aspectos práticos da modelagem de séries temporais estruturais (…) não precisam dominar todos os detalhes técnicos do filtro de Kalman aqui apresentados”21.

12.7.5.1 Suavizador de Kalman

The aim of filtering is to find the expected value of the state vector, \(\boldsymbol{\alpha}_t\), conditional on the information available at time \(t\), that is \(E(\boldsymbol{\alpha}_t | \boldsymbol{Y}_t)\). The aim of smoothing is to take account of the information made available after time \(t\). The mean of the distribution of \(\boldsymbol{\alpha}_t\), conditional on all the sample, may be written as \(E(\boldsymbol{\alpha}_t | \boldsymbol{Y}_T)\) and is known as a smoothed estimate. The corresponding estimator is called a smoother. Since the smoother is based on more information than the filtered estimator, it will have a MSE which, in general, is smaller than that of the filtered estimator; it cannot be greater. (Harvey 1989, 149–50)

12.7.5.2 Pacote dlm

Hence modelling may be phrased in terms of Dynamic Models defined generally as “sequences of sets of models”. (West and Harrison 1989, 6)

O pacote dlm (Petris 2009, 2010) fornece rotinas para máxima verossimilhança, filtragem e suavização de Kalman e análise bayesiana de modelos de espaço de estados lineares normais, também conhecidos como Modelos Lineares Dinâmicos (Petris, Petrone, and Campagnoli 2009). As funções dlm::dlmFilter() e dlm::dlmSmooth() aplicam respectivamente o filtro e o suavizador de Kalman para calcular valores filtrados/suavizados dos vetores de estado, juntamente com suas matrizes de covariância.

Exemplo 12.8 Considere a série do fluxo anual do rio Nilo medida em \(10^8 m^3\) entre 1871 e 1970, apresentada por (Cobb 1978, 249) e disponível em datasets::Nile.

library(dlm)
y <- datasets::Nile
# função que pega um vetor de mesmo comprimento de par e retorna um objeto da classe dlm (build)
dlm_Build <- function(par) {
  dlm::dlmModPoly(1, dV = exp(par[1]), dW = exp(par[2]))
}
dlm_MLE <- dlm::dlmMLE(y, rep(0,2), dlm_Build) # estimativa de máxima verossimilhança do DLM
dlm_Mod <- dlm_Build(dlm_MLE$par) # cria o filtro de Kalman (polinônio DLM de n-ésima ordem)
dlm_Filter <- dlm::dlmFilter(y, dlm_Mod) # aplica o filtro de Kalman nos dados
dlm_Smooth <- dlm::dlmSmooth(dlm_Filter) # aplica o suavizador de Kalman nos dados filtrados
plot(cbind(y, dlm_Filter$m[-1], dlm_Smooth$s[-1]), 
     plot.type = 's', col=c('black','red2','blue2'), 
     ylab='Nível', xlab ='Tempo', main='Rio Nilo', lwd=c(1,1.5,1.5))
legend('topright', legend = c('Original','Fitrada','Suavizada'), 
       fill = c('black','red2','blue2'), cex = .8)

Exercício 12.14 Considere o Exemplo 12.8.

  1. Compare com o suavizador de Tukey de sua preferência.
  2. Calcule o MSE das séries filtrada e suavizada e relação à série original, bem como do suavizador do item a.
  3. Veja esta discussão sobre a diferença entre filtro e suavizador de Kalman. Avalie os tópicos discutidos, pontuando positivamente os que se destacam.

12.7.6 Outros filtros

O pacote mFilter (Balcilar 2019) fornece filtros para séries temporais, tais como

library(mFilter)
plot(mFilter::bwfilter(Nile)) # filtro de Butterworth (1930)

plot(mFilter::hpfilter(Nile)) # filtro de Hodrick-Prescott (1997)

plot(mFilter::bkfilter(Nile)) # filtro de Baxter-King (1999)

plot(mFilter::cffilter(Nile)) # filtro de Christiano-Fitzgerald (2003)

Exercício 12.15 Considere os filtros discutidos.

  1. Investigue os demais métodos do pacote mFilter, rodando os exemplos.
  2. Encontre implementações em Python e compare as referências e resultados.

12.7.7 Valores faltantes e imputação

A função forecast::na.interp() usa, por padrão, interpolação linear para séries não sazonais. Para séries sazonais, uma decomposição STL robusta é primeiro computada. Então, uma interpolação linear é aplicada aos dados ajustados sazonalmente, e o componente sazonal é adicionado novamente.

fc <- forecast::na.interp(gold)
plot(fc, main = 'Série gold com valores imputados em vermelho')
na <- which(is.na(forecast::gold))
points(na, fc[na], col = 'red')

O pacote imputeTS (Moritz and Bartz-Beielstein 2017) apresenta funções para imputação (substituição) de valores ausentes em séries temporais univariadas. Oferece várias funções de imputação e gráficos de dados ausentes. Os algoritmos de imputação disponíveis incluem: ‘Média’, ‘LOCF’, ‘Interpolação’, ‘Média Móvel’, ‘Decomposição Sazonal’, ‘Suavização de Kalman em modelos de Séries Temporais Estruturais’ e ‘Suavização de Kalman em modelos ARIMA’.

library(imputeTS)
imp <- imputeTS::na_kalman(tsAirgap)
ggplot_na_imputations(tsAirgap, imp, tsAirgapComplete)

12.7.8 Detecção de outliers

O pacote tsoutliers (López-de-Lacalle 2024) traz funções para detecção de outliers em séries temporais seguindo o procedimento de (Chen and Liu 1993). Outliers inovadores, outliers aditivos, mudanças de nível, mudanças temporárias e mudanças de nível sazonais são considerados.

plot(tsoutliers::tso(Nile))

plot(tsoutliers::tso(h02))

O pacote anomalous (Rob J. Hyndman, Wang, and Laptev 2024) possui métodos que calculam características em diversas séries temporais, podendo incluir correlação de defasagem, força da sazonalidade, entropia espectral, etc. Então, uma decomposição de componentes principais é usada nas características, e vários métodos de detecção de outliers bivariados são aplicados aos dois primeiros componentes principais. Isso permite que as séries mais incomuns, com base em seus vetores de características, sejam identificadas.

library(anomalous)
z <- ts(matrix(rnorm(3000), ncol=100), freq=4)
y <- tsmeasures(z)
biplot.features(y)

anom <- anomaly(y)

Referências

Balcilar, Mehmet. 2019. mFilter: Miscellaneous Time Series Filters. https://CRAN.R-project.org/package=mFilter.
Barrett, Tyson, Matt Dowle, Arun Srinivasan, Jan Gorecki, Michael Chirico, and Toby Hocking. 2024. Data.table: Extension of ‘Data.frame‘. https://CRAN.R-project.org/package=data.table.
Baxter, Marianne, and Robert G King. 1999. “Measuring Business Cycles: Approximate Band-Pass Filters for Economic Time Series.” Review of Economics and Statistics 81 (4): 575–93. https://www.nber.org/system/files/working_papers/w5022/w5022.pdf.
Butterworth, Stephen et al. 1930. “On the Theory of Filter Amplifiers.” Wireless Engineer 7 (6): 536–41. https://www.changpuak.ch/electronics/downloads/On_the_Theory_of_Filter_Amplifiers.pdf.
Chen, Chung, and Lon-Mu Liu. 1993. “Joint Estimation of Model Parameters and Outlier Effects in Time Series.” Journal of the American Statistical Association 88 (421): 284–97. https://wiki.cecm.usp.br/~felipeh/2290724.pdf.
Christiano, Lawrence J, and Terry J Fitzgerald. 2003. “The Band Pass Filter.” International Economic Review 44 (2): 435–65. https://onlinelibrary.wiley.com/doi/pdf/10.1111/1468-2354.t01-1-00076.
Cleveland, Robert B, William S Cleveland, Jean E McRae, Irma Terpenning, et al. 1990. “STL: A Seasonal-Trend Decomposition.” Journal of Official Statistics 6 (1): 3–73. https://www.nniiem.ru/file/news/2016/stl-statistical-model.pdf.
Cobb, George W. 1978. The problem of the Nile: Conditional solution to a changepoint problem.” Biometrika 65 (2): 243–51. https://doi.org/10.1093/biomet/65.2.243.
Dagum, Estela Bee, and Silvia Bianconcini. 2016. Seasonal Adjustment Methods and Real Time Trend-Cycle Estimation. Springer. http://ndl.ethernet.edu.et/bitstream/123456789/64243/1/389.pdf.
Diggle, Peter J. 1990. Time Series: A Biostatistical Introduction. Oxford University Press. https://academic.oup.com/book/53018.
Foster, Jason. 2020. Roll: Rolling and Expanding Statistics. https://CRAN.R-project.org/package=roll.
Gurajala, Ramakrishna, Praveen B Choppala, James Stephen Meka, and Paul D Teal. 2021. “Derivation of the Kalman Filter in a Bayesian Filtering Perspective.” In 2021 2nd International Conference on Range Technology (ICORT), 1–5. IEEE. https://www.jamesstephen.in/papers/8.pdf.
Harvey, Andrew C. 1989. Forecasting, Structural Time Series Models and the Kalman Filter. Cambridge University Press.
Hodrick, Robert J, and Edward C Prescott. 1997. “Postwar US Business Cycles: An Empirical Investigation.” Journal of Money, Credit, and Banking, 1–16. https://www.jstor.org/stable/pdf/2953682.pdf.
———. 2021. Forecasting: Principles and Practice, 3rd Ed. OTexts. https://otexts.com/fpp3/.
Hyndman, Rob J, and Yeasmin Khandakar. 2008. “Automatic Time Series Forecasting: The Forecast Package for R.” Journal of Statistical Software 27 (3): 1–22. https://doi.org/10.18637/jss.v027.i03.
Hyndman, Rob J, Earo Wang, and Nikolay Laptev. 2024. Anomalous: Unusual Time Series Detection. https://github.com/robjhyndman/anomalous.
Kałędkowski, Dawid. 2024. Runner: Running Operations for Vectors. https://CRAN.R-project.org/package=runner.
Kálmán, RE. 1960. A New Approach to Linear Filtering and Prediction Problems.” Journal of Basic Engineering 82 (1): 35–45. https://doi.org/10.1115/1.3662552.
Kálmán, Rudolph E, and Richard S Bucy. 1961. “New Results in Linear Filtering and Prediction Theory.” https://people.duke.edu/~hpgavin/SystemID/References/KalmanBucy-ASME-JBE-1961.pdf.
Karas, Marta, and Jacek Urbanek. 2019. Runstats: Fast Computation of Running Statistics for Time Series. https://CRAN.R-project.org/package=runstats.
———. 1983. “The Advanced Theory of Statistics - Volume 3.”
Lauritzen, Steffen L. 1981. “Time Series Analysis in 1880: A Discussion of Contributions Made by TN Thiele.” International Statistical Review/Revue Internationale de Statistique, 319–31. https://doi.org/https://doi.org/10.2307/1402616.
López-de-Lacalle, Javier. 2024. Tsoutliers: Detection of Outliers in Time Series. https://CRAN.R-project.org/package=tsoutliers.
Moritz, Steffen, and Thomas Bartz-Beielstein. 2017. imputeTS: Time Series Missing Value Imputation in R.” The R Journal 9 (1): 207–18. https://doi.org/10.32614/RJ-2017-009.
Persons, Warren Milton. 1919. “Indices of Business Conditions.” The Review of Economics and Statistics, 5–107. https://www.jstor.org/stable/i333288.
Petris, Giovanni. 2009. “Dlm: An r Package for Bayesian Analysis of Dynamic Linear Models.” https://cran.r-project.org/web/packages/dlm/vignettes/dlm.pdf.
———. 2010. “An R Package for Dynamic Linear Models.” Journal of Statistical Software 36 (12): 1–16. https://www.jstatsoft.org/v36/i12/.
Petris, Giovanni, Sonia Petrone, and Patrizia Campagnoli. 2009. Dynamic Linear Models with r. useR! Springer-Verlag, New York.
Sax, Christoph, and Dirk Eddelbuettel. 2018. “Seasonal Adjustment by X-13ARIMA-SEATS in R.” Journal of Statistical Software 87 (11): 1–17. https://doi.org/10.18637/jss.v087.i11.
Schramm, Michael. 2020. Tbrf: Time-Based Rolling Functions. https://CRAN.R-project.org/package=tbrf.
Seabold, Skipper, and Josef Perktold. 2010. “Statsmodels: Econometric and Statistical Modeling with Python.” In 9th Python in Science Conference. https://www.statsmodels.org/.
Shiskin, Julius, Allan H. Young, and Joohn C. Musgrave. 1967. The x-11 Variant of the Census Method II Seasonal Adjustment Program. 15. US Department of Commerce, Bureau of the Census. https://books.google.com.py/books?hl=pt-BR&lr=&id=XQDRsNL2QasC&oi=fnd&pg=PA1&dq=Shiskin,+Young+e+Musgrave+1967&ots=YqK2TpNfhU&sig=hJthMKOhfh4gUpDXikst3Kwl0cw&redir_esc=y#v=onepage&q=Shiskin%2C%20Young%20e%20Musgrave%201967&f=false.
Stigler, Stephen M. 1980. “Stigler’s Law of Eponymy.” Transactions of the New York Academy of Sciences 39 (1 Series II): 147–57.
Stratonovich, R. L. 1957. “A Method for the. Computation of Quantum Distribution Functions (Em Russo).” In Reports of the Academy of Sciences, 115:1097–1100. 6. Russian Academy of Sciences. https://www.mathnet.ru/php/archive.phtml?wshow=paper&jrnid=dan&paperid=22296&option_lang=eng.
Swerling, Peter. 1958. “Optimum Linear Estimation for Random Processes as the Limit of Estimates Based on Sampled Data.” In 1958 IRE Wescon Convention Record, 158–63. 29. https://apps.dtic.mil/sti/tr/pdf/AD0606275.pdf.
Thiele, Thorvald Nicolai. 1880. Om Anvendelse Af Mindste Kvadraters Methode i Nogle Tilfaelde, Hvor En Komplikation Af Visse Slags Uensartede Tilfaeldige Fejlkilder Giver Fejlene En" Systematisk" Karakter. B. Lunos Kgl. Hof.-Bogtrykkeri. https://archive.org/details/surlacompensati00thiegoog.
Tukey, John W. 1977. Exploratory Data Analysis. Addison-Wesley Publishing Company.
U.S. Census Bureau. 2023. X-13ARIMA-SEATS Reference Manual (version 1.1). Center for Statistical Research & Methodology. https://www2.census.gov/software/x-13arima-seats/x13as/windows/documentation/docx13as.pdf.
Vaughan, Davis. 2023. Slider: Sliding Window Functions. https://CRAN.R-project.org/package=slider.
Wang, Earo, Dianne Cook, and Rob J Hyndman. 2020b. “A New Tidy Data Structure to Support Exploration and Modeling of Temporal Data.” Journal of Computational and Graphical Statistics 29 (3): 466–78. https://doi.org/10.1080/10618600.2019.1695624.
West, Mike, and Jeff Harrison. 1989. Bayesian Forecasting and Dynamic Models. Springer Science & Business Media. https://books.google.com.br/books/about/Bayesian_Forecasting_and_Dynamic_Models.html?id=NmfaBwAAQBAJ&redir_esc=y.
———. 2006. Bayesian Forecasting and Dynamic Models. Springer Science & Business Media.
———. 2005b. “Zoo: S3 Infrastructure for Regular and Irregular Time Series.” Journal of Statistical Software 14 (6): 1–27. https://doi.org/10.18637/jss.v014.i06.

  1. The X-11 Variant of The Census Method II Seasonal Adjustment Program.↩︎

  2. The Kalman filter is a recursive procedure for computing the optimal estimator of the state vector at time \(t\), based on the information available at time \(t\). (Harvey 1989, 104)↩︎

  3. For those who are primarily interested in carrying out applied work with structural time series models, ti should perhaps be stressed that the Kalman filter is simply a statistical algorithm, and it is only necessary to understand what the filter does, rather than how it does it. The same is true of the frequency-domain methods which can be used to construct the likelihood function. (Harvey 1989,xi)↩︎

  4. [T]hose interested primarily in the practical aspects of structural time series modelling will be reassured to know that they do not have to master all the technical details of the Kalman filter set out here. (Harvey 1989, 100)↩︎