dias | D1 | D2 | D3 | D4 | D5 | D6 |
---|---|---|---|---|---|---|
Segunda | 1 | 0 | 0 | 0 | 0 | 0 |
Terça | 0 | 1 | 0 | 0 | 0 | 0 |
Quarta | 0 | 0 | 1 | 0 | 0 | 0 |
Quinta | 0 | 0 | 0 | 1 | 0 | 0 |
Sexta | 0 | 0 | 0 | 0 | 1 | 0 |
Sábado | 0 | 0 | 0 | 0 | 0 | 1 |
Domingo | 0 | 0 | 0 | 0 | 0 | 0 |
Segunda | 1 | 0 | 0 | 0 | 0 | 0 |
ME607 - Séries Temporais
Instituto de Matemática, Estatística e Computação Científica (IMECC),
Universidade Estadual de Campinas (UNICAMP).
dias | D1 | D2 | D3 | D4 | D5 | D6 |
---|---|---|---|---|---|---|
Segunda | 1 | 0 | 0 | 0 | 0 | 0 |
Terça | 0 | 1 | 0 | 0 | 0 | 0 |
Quarta | 0 | 0 | 1 | 0 | 0 | 0 |
Quinta | 0 | 0 | 0 | 1 | 0 | 0 |
Sexta | 0 | 0 | 0 | 0 | 1 | 0 |
Sábado | 0 | 0 | 0 | 0 | 0 | 1 |
Domingo | 0 | 0 | 0 | 0 | 0 | 0 |
Segunda | 1 | 0 | 0 | 0 | 0 | 0 |
Estacoes | D1 | D2 | D3 |
---|---|---|---|
Primaveira | 1 | 0 | 0 |
Verão | 0 | 1 | 0 |
Outono | 0 | 0 | 1 |
Inverno | 0 | 0 | 0 |
Primaveira | 1 | 0 | 0 |
Verão | 0 | 1 | 0 |
Dependo do que queremos prever, o numero de dias úteis (ou dias de negociação) pode influenciar em, por exemplo, o volume de vendas mensal.
Podemos pensar que, por exemplo, o número de vendas depende dos gastos em publicidade. Contudo, às vezes os gastos em publicidade do mês anterior poderiam ter um efeito nas vendas do mês atual. Nesse sentido, incluir variáveis defasadas pode ajudar a melhorar o modelo.
A páscoa não acontece todo ano no mesmo periodo, páscoa pode afetar diferentes negócios (turismo, por exemplo). Incluir no modelo uma variável que tome conta desse fator pode ser interessante. Nestes casos podemos:
Uma regressão que inclui termos de Fourier, é chamada “modelo de regressao harmônica”.
Contruiremos um modelo da forma \[Beer_t = \beta_0 + \beta_1 t + \beta_2 D_{2,t} + \beta_3 D_{3,t} + \beta_4 D_{4,t} + \epsilon_t,\] em que \(D_{i,t} = 1\) se \(t \in\) Trimestre \(i\) e 0, caso contrário.
Series: Beer
Model: TSLM
Residuals:
Min 1Q Median 3Q Max
-42.9029 -7.5995 -0.4594 7.9908 21.7895
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 441.80044 3.73353 118.333 < 2e-16 ***
trend() -0.34027 0.06657 -5.111 2.73e-06 ***
season()year2 -34.65973 3.96832 -8.734 9.10e-13 ***
season()year3 -17.82164 4.02249 -4.430 3.45e-05 ***
season()year4 72.79641 4.02305 18.095 < 2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 12.23 on 69 degrees of freedom
Multiple R-squared: 0.9243, Adjusted R-squared: 0.9199
F-statistic: 210.7 on 4 and 69 DF, p-value: < 2.22e-16
Series: Beer
Model: TSLM
Residuals:
Min 1Q Median 3Q Max
-42.9029 -7.5995 -0.4594 7.9908 21.7895
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 446.87920 2.87321 155.533 < 2e-16 ***
trend() -0.34027 0.06657 -5.111 2.73e-06 ***
fourier(K = 2)C1_4 8.91082 2.01125 4.430 3.45e-05 ***
fourier(K = 2)S1_4 -53.72807 2.01125 -26.714 < 2e-16 ***
fourier(K = 2)C2_4 -13.98958 1.42256 -9.834 9.26e-15 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 12.23 on 69 degrees of freedom
Multiple R-squared: 0.9243, Adjusted R-squared: 0.9199
F-statistic: 210.7 on 4 and 69 DF, p-value: < 2.22e-16
augment(modelo_dummy) %>%
ggplot(aes(x = Quarter)) +
geom_line(aes(y = Beer, colour = "Data")) +
geom_line(aes(y = .fitted, colour = "Fitted")) +
scale_colour_manual(values = c(Data = "black", Fitted = "red")) + ylab("Megalitros") + xlab("Trimestre") + ggtitle("Produção trimestral de cerveja australiana") +
guides(colour = guide_legend(title = "Séries"))
augment(modelo_fourier) %>%
ggplot(aes(x = Quarter)) +
geom_line(aes(y = Beer, colour = "Data")) +
geom_line(aes(y = .fitted, colour = "Fitted")) +
scale_colour_manual(values = c(Data = "black", Fitted = "blue")) + ylab("Megalitros") + xlab("Trimestre") + ggtitle("Produção trimestral de cerveja australiana") +
guides(colour = guide_legend(title = "Séries"))
# A tibble: 5 × 6
.model term estim…¹ std.e…² stati…³ p.value
<chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 TSLM(Beer ~ trend() + season()) (Intercept) 442. 3.73 118. 2.02e-81
2 TSLM(Beer ~ trend() + season()) trend() -0.340 0.0666 -5.11 2.73e- 6
3 TSLM(Beer ~ trend() + season()) season()year2 -34.7 3.97 -8.73 9.10e-13
4 TSLM(Beer ~ trend() + season()) season()year3 -17.8 4.02 -4.43 3.45e- 5
5 TSLM(Beer ~ trend() + season()) season()year4 72.8 4.02 18.1 6.68e-28
# … with abbreviated variable names ¹estimate, ²std.error, ³statistic
# A tibble: 1 × 3
.model bp_stat bp_pvalue
<chr> <dbl> <dbl>
1 TSLM(Beer ~ trend() + season()) 9.53 0.0230
# A tibble: 1 × 3
.model lb_stat lb_pvalue
<chr> <dbl> <dbl>
1 TSLM(Beer ~ trend() + season()) 10.4 0.0157
# A tibble: 5 × 6
.model term estim…¹ std.e…² stati…³ p.value
<chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 TSLM(Beer ~ trend() + fourier(K = 2)) (Inter… 447. 2.87 156. 1.39e-89
2 TSLM(Beer ~ trend() + fourier(K = 2)) trend() -0.340 0.0666 -5.11 2.73e- 6
3 TSLM(Beer ~ trend() + fourier(K = 2)) fourie… 8.91 2.01 4.43 3.45e- 5
4 TSLM(Beer ~ trend() + fourier(K = 2)) fourie… -53.7 2.01 -26.7 4.10e-38
5 TSLM(Beer ~ trend() + fourier(K = 2)) fourie… -14.0 1.42 -9.83 9.26e-15
# … with abbreviated variable names ¹estimate, ²std.error, ³statistic
# A tibble: 1 × 3
.model bp_stat bp_pvalue
<chr> <dbl> <dbl>
1 TSLM(Beer ~ trend() + fourier(K = 2)) 9.53 0.0230
# A tibble: 1 × 3
.model lb_stat lb_pvalue
<chr> <dbl> <dbl>
1 TSLM(Beer ~ trend() + fourier(K = 2)) 10.4 0.0157
O K = m/2
em fourier()
especifica quantos pares de \(\sin()\) e \(\cos()\) utilizaremos na regressão. Como utilizamos o máximo (\(m = 4 \rightarrow K = 2\)), teremos exatamente os mesmos \(\hat{y}\)
[,1] [,2]
[1,] 441.4602 441.4602
[2,] 406.4602 406.4602
[3,] 422.9580 422.9580
[4,] 513.2358 513.2358
[5,] 440.0991 440.0991
[6,] 405.0991 405.0991
Mas, como fazer se estamos interessados em \(\hat{y}_{T+1|T}, \cdots, \hat{y}_{T+h|T}\)?
Em geral, quando trabalhamos com modelos da forma \[y_t = \beta_0 + \beta_1 x_{1,t} + \cdots + \beta_k x_{k,t} + e_t\] nunca conhecemos os valores de \(x_1, x_2, ..., x_k\) no futuro, exceto quando \(x_i\) é deterministico!.
Pense no modelo \[y_t = \beta_0 + \beta_1 x_{1,t} + \cdots + \beta_k x_{k,t} + e_t\] em que \(x_1 = t\), \(x_2 = t^2\), \(x_3 = D_{Fevereiro}\), \(x_4 = D_{Março}\), …. \(x_k = D_{Dezembro}\).
Basta obter \(\hat{\beta}\) (utilizando a informação disponível até o tempo \(T\)), utilizar os valores futuros das variáveis explicativas ( \(x_{1, T + h}, \ldots, x_{k, T + h}\) ) e fazer a previsão!.
Utilizando o dataset aus_production
do pacote fpp3
, faremos a previsão \(h = 12\) passos à frente da produção de cerveja (Beer
) na Austrália.
Series: Beer
Model: TSLM
Residuals:
Min 1Q Median 3Q Max
-42.1193 -7.7552 -0.5074 7.7665 22.3373
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 439.41993 3.87255 113.471 < 2e-16 ***
trend() -0.31359 0.07303 -4.294 5.98e-05 ***
season()year2 -34.79753 4.11473 -8.457 4.51e-12 ***
season()year3 -17.56209 4.17414 -4.207 8.09e-05 ***
season()year4 71.75149 4.17478 17.187 < 2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 12.34 on 65 degrees of freedom
Multiple R-squared: 0.9213, Adjusted R-squared: 0.9164
F-statistic: 190.1 on 4 and 65 DF, p-value: < 2.22e-16
# A fable: 12 x 4 [1Q]
# Key: .model [1]
.model Quarter Beer .mean
<chr> <qtr> <dist> <dbl>
1 TSLM(Beer ~ trend() + season()) 2010 Q3 N(400, 168) 400.
2 TSLM(Beer ~ trend() + season()) 2010 Q4 N(489, 168) 489.
3 TSLM(Beer ~ trend() + season()) 2011 Q1 N(417, 168) 417.
4 TSLM(Beer ~ trend() + season()) 2011 Q2 N(381, 168) 381.
5 TSLM(Beer ~ trend() + season()) 2011 Q3 N(398, 170) 398.
6 TSLM(Beer ~ trend() + season()) 2011 Q4 N(487, 170) 487.
7 TSLM(Beer ~ trend() + season()) 2012 Q1 N(415, 170) 415.
8 TSLM(Beer ~ trend() + season()) 2012 Q2 N(380, 170) 380.
9 TSLM(Beer ~ trend() + season()) 2012 Q3 N(397, 172) 397.
10 TSLM(Beer ~ trend() + season()) 2012 Q4 N(486, 172) 486.
11 TSLM(Beer ~ trend() + season()) 2013 Q1 N(414, 172) 414.
12 TSLM(Beer ~ trend() + season()) 2013 Q2 N(379, 172) 379.
No exemplo anterior, vimos que fazer previsão quando as variáveis explicativas são determinísticas resume-se a:
Contudo, muito raramente o modelo terá apenas variáveis determinísticas!. Na prática, o modelo terá variaveis explicativas \(x_{k+1}, \ldots, x_{k+p}\) cujos valores no tempo \(T+h\) não são conhecidos no tempo \(T\) 😨.
O modelo que estou utilizando tem variáveis que não são determinísticas, e agora?
Assumimos diferentes cenários para as variáveis explicativas no modelo:
Em todos os casos temos apenas cenários, não há garantia que isso acontecerá mas, se acotecer, temos um valor esperado de como irá se comportar o fenômeno de interesse ao longo do tempo.
modelo <- us_change %>% model(lm = TSLM(Consumption ~ Income + Savings + Unemployment))
# Criando os cenários
cenarios <- scenarios(
caso1 = new_data(us_change, 4) |> # pega o dataset e cria 4 novas observacoes
mutate(Income = c(1, 1.1, 1.2, 1.3), # Criando cenário para Income
Savings = c(0.5, 0.52, 0.54, 0.56), # Criando cenário para Savings
Unemployment = c(0, 0.05, 0.10, 0.15)), # Criando cenário para Unemployment
caso2 = new_data(us_change, 4) |> # pega o dataset e cria 4 novas observacoes
mutate(Income = -c(1, 1.1, 1.2, 1.3), # Criando cenário para Income
Savings = -c(0.5, 0.52, 0.54, 0.56), # Criando cenário para Savings
Unemployment = -c(0, 0.05, 0.10, 0.15)))
fc <- forecast(modelo, new_data = cenarios)
fc
# A fable: 8 x 8 [1Q]
# Key: .scenario, .model [2]
.scenario .model Quarter Consumption .mean Income Savings Unemployment
<chr> <chr> <qtr> <dist> <dbl> <dbl> <dbl> <dbl>
1 caso1 lm 2019 Q3 N(1, 0.098) 0.996 1 0.5 0
2 caso1 lm 2019 Q4 N(1.1, 0.099) 1.06 1.1 0.52 0.05
3 caso1 lm 2020 Q1 N(1.1, 0.099) 1.11 1.2 0.54 0.1
4 caso1 lm 2020 Q2 N(1.2, 0.099) 1.17 1.3 0.56 0.15
5 caso2 lm 2019 Q3 N(-0.46, 0.1) -0.464 -1 -0.5 0
6 caso2 lm 2019 Q4 N(-0.52, 0.1) -0.523 -1.1 -0.52 -0.05
7 caso2 lm 2020 Q1 N(-0.58, 0.1) -0.582 -1.2 -0.54 -0.1
8 caso2 lm 2020 Q2 N(-0.64, 0.1) -0.641 -1.3 -0.56 -0.15
O que foi feito?
# A tibble: 4 × 6
.model term estimate std.error statistic p.value
<chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 lm (Intercept) 0.266 0.0341 7.81 3.57e-13
2 lm Income 0.757 0.0396 19.1 1.91e-46
3 lm Savings -0.0537 0.00292 -18.4 2.55e-44
4 lm Unemployment -0.313 0.0678 -4.62 7.06e- 6
\[\widehat{\text{Consumption}}_{T+h} = 0.266 + 0.757 \text{Income}_{T+h} -0.0537 \text{Savings}_{T+h} -0.313 \text{Unemployment}_{T+h}\]
Quando construimos cenários, estamos definindo valores hipotéticos para os diferentes valores de \(\text{Income}_{T+h}\), \(\text{Savings}_{T+h}\) e \(\text{Unemployment}_{T+h}\). Assim, basta substituir esse valores na Equação e pronto!.
Sabemos que existem várias formas de incluir não lineariedades nos modelos de regressão:
Todas essas técnicas continuam sendo válidas quando trabalhamos com modelos de regressão em um contexto de séries temporais. Contudo, existem também outras formas de lidar com a não lineariedade.
Em geral, queremos modelos da forma \(y = f(x) + e\)
Em lugar de termos \(f(x) = \beta_0 + \beta_1 x\), podemos fazer \(f()\) linear por partes. Ou seja, incluimos pontos (que chamaremos de knots ou nós) nos quais a pendente de \(f()\) pode mudar. Isto pode ser feito fazendo
Em geral, podemos fazer:
\[x_1 = x, \quad x_2 = (x - c_1)_{+}, \quad, \cdots, x_k = (x-c_k)_{+}.\]
Um modelo de regressão dessa forma é chamado de regressão por splines.
O dataset boston_marathon
do pacote fpp3
contém informações sobre o tempo (em segundos) dos ganhadores da maratona ao longo dos anos de 5 categorias diferentes.
Rows: 123
Columns: 2
$ Year <int> 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1904, 1905, 1906, 19…
$ Minutos <dbl> 175.1667, 162.0000, 174.6333, 159.7333, 149.3833, 163.2000, 16…
# A fable: 36 x 4 [1Y]
# Key: .model [3]
.model Year Minutos .mean
<chr> <dbl> <dist> <dbl>
1 linear 2020 N(123, 22) 123.
2 linear 2021 N(123, 22) 123.
3 linear 2022 N(122, 22) 122.
4 linear 2023 N(122, 22) 122.
5 linear 2024 N(122, 22) 122.
6 linear 2025 N(121, 22) 121.
7 linear 2026 N(121, 22) 121.
8 linear 2027 N(121, 22) 121.
9 linear 2028 N(120, 22) 120.
10 linear 2029 N(120, 22) 120.
# … with 26 more rows
Quando trabalhamos com um modelo com splines, podemos passar no argumento knots
tanto as posições exatas dos nós, quanto o número de nós. Nesse último caso, a posição do nó será calculada automaticamente.
Procedimentos automáticos ajudam, mas não estão isentos de erro.
Carlos Trucíos (IMECC/UNICAMP) | ME607 - Séries Temporais | ctruciosm.github.io