1º Exercício LED

Author

Prof. Dinilson Pedroza Jr.

Quarto

Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see https://quarto.org.

Instruções:

Responda às questões em um documento Quarto. Explique antes de cada chunk o que será feito e porque será feito. Além disso, comente as linhas de cada chunk. As séries solicitadas como exemplo podem ser simuladas, a menos que haja menção em contrário. Esse exercício pode ser feito em duplas.

Previsões com Modelo ARIMA.

1º Questão:

Explique com um exemplo no R o que são séries temporais. Nessa ilustração, utilize duas séries: uma simulada e outra com dados reais. Lembre-se de observar os procedimentos vistos em sala de aula.

#Primeiramente, vamos acionar todos os pacotes que, possivelmente, iremos necessitar:
library(zoo)

Attaching package: 'zoo'
The following objects are masked from 'package:base':

    as.Date, as.Date.numeric
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.2     ✔ tibble    3.3.0
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.1.0     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(sidrar)
library(lmtest)
Warning: package 'lmtest' was built under R version 4.5.2
library(tseries)
Warning: package 'tseries' was built under R version 4.5.2
Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 
library(quantmod)
Warning: package 'quantmod' was built under R version 4.5.2
Loading required package: xts

######################### Warning from 'xts' package ##########################
#                                                                             #
# The dplyr lag() function breaks how base R's lag() function is supposed to  #
# work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or       #
# source() into this session won't work correctly.                            #
#                                                                             #
# Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #
# conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop           #
# dplyr from breaking base R's lag() function.                                #
#                                                                             #
# Code in packages is not affected. It's protected by R's namespace mechanism #
# Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning.  #
#                                                                             #
###############################################################################

Attaching package: 'xts'

The following objects are masked from 'package:dplyr':

    first, last

Loading required package: TTR
library(forecast)
rm(list = ls())
#Uma série temporal pode ser difinida como uma sequência de valores numéricos organizados cronologicamente, em um intervalo de tempo definido.
#Agora vamos simular uma série temporal usando o componente autorregressivo:

set.seed(123) #fixando os valores aleatórios
phi <- 0.8 #definindo nosso componente autorregresseivo
n <- 100 #determinando a quantidade de elementos da série

ts_simulada <- arima.sim(model = list(ar = phi), n = n) #usando a função arima.sim para simular nossa série temporal

ts_simulada #visualizando a série temporal
Time Series:
Start = 1 
End = 100 
Frequency = 1 
  [1] -2.34381284 -0.62123535 -0.07052406 -0.35149073  0.61393308  1.36927995
  [7]  1.91700504  2.22224429  2.33171308  1.80345876  1.13680434  0.52897247
 [13] -0.27152900 -0.42514048 -1.60550874  0.88454898  1.91560118  0.40937236
 [19] -0.07538695 -0.52696491  0.35839319  0.20334549  0.41599490  0.30424917
 [25]  0.20052888  1.52902538  0.99744932  2.31443006  0.30279125  0.82684675
 [31]  0.78533164  0.84420688  1.05500499  0.34168054 -0.05986295 -1.06646575
 [37] -1.92496382 -1.23644242 -0.54094416 -0.37975110  0.61846659  2.54485796
 [43]  1.54485520 -1.07328472  0.14711075 -0.59151216 -1.16121835  0.09659669
 [49] -0.20749565 -1.38671423 -0.92806791 -0.88134569 -0.69931236 -0.17416949
 [55] -0.50999562  0.23638005 -0.03138252  0.30667595  1.34217977  1.50892531
 [61]  0.88120866  1.85377455  2.47652349  2.52961575  2.26242434  1.18203339
 [67]  2.30627916  1.24476374  3.18314399  4.07912582  3.02760029  1.39565934
 [73]  0.40612090  0.58178043  0.21873247 -0.17255663 -1.08966387 -0.91675882
 [79] -1.51831152 -2.88259116 -2.68629945 -1.23004295 -1.55938132 -0.63954073
 [85] -2.12951530 -1.75917420 -0.88793216 -0.40919236 -0.22167770 -0.81804817
 [91] -1.50414288 -2.22744309 -1.66430788 -2.27892092 -2.31369418 -2.10704753
 [97]  0.15822398 -0.52537072 -0.18491000 -0.06996715
#Vamos criar uma série temporal com valores reais 

pim <- get_sidra(api="/t/8888/n1/all/v/11601/p/all/c544/129314/d/v11601%201") #baixamos a tabela através do seu API
All others arguments are desconsidered when 'api' is informed
#devemos filtrar nosso data frame, selecionando apenas as informações que nos interessam
pim_fill <- pim %>%
  select(mes = `Mês (Código)`,
         valor = Valor) %>%
  mutate(mes = as.numeric(mes),
         valor = as.numeric(valor)) %>%
  arrange(mes)

pim_ts <- ts(pim_fill$valor, #criando nossa ts a partir da coluna valores do df
             start = c(2002, 01), #iniciando em janeiro de 2002
             frequency = 12) #com frequência mensal
pim_ts #visualizando a série temporal
       Jan   Feb   Mar   Apr   May   Jun   Jul   Aug   Sep   Oct   Nov   Dec
2002   0.0   2.2  -0.3   0.2   0.0   0.3   0.4  -0.9   0.4   0.4  -0.1  -0.3
2003   0.4  -0.4  -0.2  -0.2  -1.5   0.6  -0.9   1.4   2.9   0.5   1.0  -1.5
2004   2.0   1.5   0.6   0.8   0.9   0.4   0.7   1.1   0.4  -0.6   0.0   0.6
2005   0.5  -1.4   1.0   0.0   3.5  -2.1  -0.6   0.1  -0.7  -0.5   0.9   1.7
2006   0.4   0.8  -0.6   0.5   0.7  -1.2   0.8  -0.1  -1.2   0.9   1.3   0.6
2007  -0.2   1.3   1.3   1.0   0.2   0.6  -0.3   1.4  -1.1   2.8  -0.9   0.3
2008   1.7  -0.3   0.2   0.1   0.8   1.3   0.5  -1.1   1.1  -2.7  -6.1 -11.1
2009   2.1   2.3   0.5   1.3   1.2   1.4   1.3   1.6   1.4   2.2   1.3   0.4
2010   1.5  -0.2   2.3   0.4  -0.3  -0.4  -0.6  -0.2   0.2  -0.3   0.7   0.5
2011   0.3   1.2   0.3  -2.6   3.1  -1.8  -0.2  -0.8  -1.6  -1.1   0.5   2.6
2012  -4.2   0.8  -0.4  -0.1   0.5   0.2   1.4   2.2  -2.0   1.5  -1.3   0.6
2013   1.0  -2.9   2.0   1.6  -0.2   0.4  -0.6   0.3   0.5  -1.1   0.5  -3.5
2014   1.8   0.4  -0.4  -0.8  -1.0  -2.8   2.5   0.4   0.2   0.1  -0.9  -2.8
2015   0.5  -0.9  -0.4  -1.9  -1.1  -0.8  -1.8   0.4  -2.3  -0.1  -1.7  -1.5
2016   0.9  -1.1   0.6   0.0   0.4  -1.4   0.7  -1.9   1.1  -1.4   1.0   1.7
2017   0.7   1.2  -1.6   0.0   0.4   1.0   0.2   0.1   0.3   1.0   0.4   2.7
2018  -2.3  -0.6   1.4   0.4 -10.9  12.4  -0.2  -0.9  -2.9   1.4  -0.1  -0.2
2019  -0.5   0.3  -0.6   0.5   0.0  -0.9  -0.5   1.0   0.0   2.3  -2.4  -1.4
2020   1.4   0.6  -7.7 -19.8   7.8  10.0   9.2   2.9   2.7   1.5   0.4  -0.5
2021   0.7  -1.5  -2.1  -1.8   1.1  -0.4  -1.3  -0.1  -0.3  -0.5   0.0   1.5
2022  -0.1   0.9  -0.8   0.6  -0.5  -0.1   1.2  -1.6  -1.5   1.5   0.0   0.0
2023   0.0  -0.2   0.8  -0.4   0.6  -0.4  -0.5   0.4  -0.4   0.4   1.1   1.5
2024  -1.2   0.2   0.5  -0.4  -1.2   4.4  -1.4  -0.3   1.0   0.0  -0.7  -0.4
2025   0.2   0.0   1.8  -0.7  -0.5   0.1  -0.1   0.7  -0.4                  

2ª Questão:

Pegue uma série de dados da COVID no Brasil e monte um gráfico com os dados originais e uma média móvel. Explique em detalhes o significado de média móvel. Use o ggplot2 para fazer o gráfico.

#Média Móvel pode ser definida como a média dos últimos valores de uma série dentro de uma janela que se desloca ao longo do tempo.
#Agora vamos usar os dados da covid
covid <- read.csv("covid.csv", header = T)

#Devemos adicionar uma coluna de datas para, após isso criar nossa ts:
covid$semana <- seq(
  as.Date ("2025-01-01"),
  by = "week",
  length.out = nrow(covid),
)

covid_mm <- covid %>%
  mutate(mm = rollmean(casos, k = 3, fill = NA, align = "right"))

ggplot(covid_mm, aes(x = semana)) +
  geom_line(aes(y = casos), colour = "hotpink", lwd = 1.2) +
  geom_line(aes(y = mm), colour = "purple", lwd = 1.2) +
  labs(
    title = "Série com Média Móvel",
    x = "Data",
    y = "Valor"
  )
Warning: Removed 2 rows containing missing values or values outside the scale range
(`geom_line()`).

3ª Questão:

Explique o que são os componentes autorregressivo e de média móvel, no contexto de um modelo ARMA. Faça gráficos ilustrando os dois conceitos.

#O componente autorregressivo, dentro do contexto do modelo ARMA, represente a depêndencia dos valores atuais dos valores passados. Ou seja, a influência que observações anteriores exercem sobre a observação presente.

set.seed(123) #fixando os valores aleatórios
phi <- 0.9 #definindo nosso componente autorregresseivo
n <- 100 #determinando a quantidade de elementos da série

ar_sim <- arima.sim(model = list(ar = phi), n = n) 

plot(ar_sim, 
     mean = "Simulação do componenete ar", ylab = "", col = "orange", lwd = 2)
Warning in plot.window(xlim, ylim, log, ...): "mean" is not a graphical
parameter
Warning in title(main = main, xlab = xlab, ylab = ylab, ...): "mean" is not a
graphical parameter
Warning in axis(1, ...): "mean" is not a graphical parameter
Warning in axis(2, ...): "mean" is not a graphical parameter
Warning in box(...): "mean" is not a graphical parameter

#Ao contrário do componente ar, a média móvel não vai usar a influência dos valores passados nos valores presentes, mas sim a influência dos erros ocorridos em períodos anteriores para determinar o valor atual da série.

set.seed(123) #fixando os valores aleatórios
theta <- 0.7 #definindo nosso componente de média móvel
n <- 100 #determinando a quantidade de elementos da série

ma_sim <- arima.sim(model = list(ma = phi), n = n) 

#plotando nosso gráfico usando a função plot do r base:
plot(ma_sim, 
     mean = "Simulação do componenete ar", ylab = "", col = "yellow", lwd = 2)
Warning in plot.window(xlim, ylim, log, ...): "mean" is not a graphical
parameter
Warning in title(main = main, xlab = xlab, ylab = ylab, ...): "mean" is not a
graphical parameter
Warning in axis(1, ...): "mean" is not a graphical parameter
Warning in axis(2, ...): "mean" is not a graphical parameter
Warning in box(...): "mean" is not a graphical parameter

4ª Questão:

Explique a importância da estacionariedade em uma série temporal. Dê exemplos no R.

#A estacionariedade, ou ruído branco, como tambem é conhecida, permite que uma série temporal tenha comportamento estável ao longo do tempo, com média, variância e autocorrelação constantes. Sem a estacionariedade da série não podemos fazer previsões com o modelo ARIMA de forma precisa.

rb <- rnorm(100) #simulando uma série estacionária com 100 elementos

#plotando o nosso gráfico do ruído branco
plot(rb, mean = "Ruído Branco", type = "l", col = "lightblue", lwd = 2, ylab = "" )
Warning in plot.window(...): "mean" is not a graphical parameter
Warning in plot.xy(xy, type, ...): "mean" is not a graphical parameter
Warning in axis(side = side, at = at, labels = labels, ...): "mean" is not a
graphical parameter
Warning in axis(side = side, at = at, labels = labels, ...): "mean" is not a
graphical parameter
Warning in box(...): "mean" is not a graphical parameter
Warning in title(...): "mean" is not a graphical parameter

#usamos type = "l", para determinar que nosso gráfico será linear

5ª Questão:

O que é autocorrelação em uma série temporal? Explique, em linhas gerais, como funciona o teste Dickey-Fuller para detectar estacionariedade. Dê exemplos no R.

#Autocorrelação é a medida que expressa a relação entre os valores atuais de uma série temporal e seus valores defasados. Autocorrelações altas indicam forte dependência do passado. Autocorrelações baixas indicam fraca dependência temporal.
#Através do test Dickey-Fuller podemos determinar se uma série temporal é estacionária ou não. Ele vai verificar se uma ts possui raiz unitária, testando a hipótese nula de que o coeficiente do termo defasado é igual a zero. Se essa hipótese não for rejeitada, conclui-se que a série é não estacionária. Se o teste rejeitar a hipótese nula, geralmente quando o p-valor é menor que 0,05, entende-se que não há raiz unitária e, portanto, a série é estacionária.
#Vamos usar a série temporal da primeira questão
pim_ts <- ts(pim_fill$valor, 
             start = c(2002, 01), 
             frequency = 12)

#aplicando o teste adf
adf.test(pim_ts)
Warning in adf.test(pim_ts): p-value smaller than printed p-value

    Augmented Dickey-Fuller Test

data:  pim_ts
Dickey-Fuller = -7.6944, Lag order = 6, p-value = 0.01
alternative hypothesis: stationary
#podemos observar que p = 0.01, logo p<0.05. Essa série é considerada estacionária.

6º Questão:

Explique, fazendo uma pequena historiografia, o que são modelos ARIMA. Fale, brevemente, sobre alternativas a esses modelos.

#Os modelos ARIMA surgiram como uma das principais ferramentas da estatística moderna para a realização de previsões. O nome ARIMA significa:
##ar (componente autorregressivo): grau de dependência dos valores atuais com os valores anteriores;
##i (componete de integração ou diferenciação): é responsável por remover tendências e tornar a série estacionária;
##ma (componente de média móvel): o valor atual depende dos erros do passado;
#A proposta desses modelos foi unificar técnicas anteriores em um único procedimento estruturado: identificar se a série é estacionária, aplicar diferenciações quando necessário e ajustar um modelo que combina memória do passado com comportamento do erro.

7ª Questão:

Realize previsões sobre a inflação no Brasil, montando para tal um modelo ARIMA. Compare as estatísticas de um modelo gerado pela função auto.arima, do pacote forecast, com um modelo que você mesmo deduziu. Para comparar os modelos, use o Critério de Akaike e os Erros médios. Faça gráficos e produza uma tabela em CSV com os resultados de suas previsões.

ipca <- get_sidra(api = "/t/1737/n1/all/v/63/p/last%2036/d/v63%202")
All others arguments are desconsidered when 'api' is informed
#baixamos a tabela através do seu API

#devemos filtrar nosso data frame, selecionando apenas as informações que nos interessam
ipca_fill <- ipca %>%
  select(mes = `Mês (Código)`,
         valor = Valor) %>%
  mutate(mes = as.numeric(mes),
         valor = as.numeric(valor))

#criando a série temporal a partir do nosso data frame
ipca_ts <- ts(ipca_fill$valor,
              start = c(2022, 11),
              frequency = 12)

#aplicando o teste adf, para checar se nossa série é estacionária ou não
adf.test(ipca_ts)

    Augmented Dickey-Fuller Test

data:  ipca_ts
Dickey-Fuller = -3.0346, Lag order = 3, p-value = 0.1706
alternative hypothesis: stationary
#observamos que p>0,05, logo, a série não é estacionária

#criando o gráfico para essa série
plot(ipca_ts, main = "variação do IPCA (01/1980-10/2025)", col = "magenta", xlab = "mes", ylab = "IPCA")

#Agora, vamos diferenciá-la para torná-la estacionária
ipca_diff <- diff(ipca_ts)

#Após a diferenciação, devemos aplicar o teste adf novamente
adf.test(ipca_diff)
Warning in adf.test(ipca_diff): p-value smaller than printed p-value

    Augmented Dickey-Fuller Test

data:  ipca_diff
Dickey-Fuller = -4.3073, Lag order = 3, p-value = 0.01
alternative hypothesis: stationary
#Agora nossa série já se encontra estacionária com apenas 1 diferenciação (d = 1)

#vamos ver como fica o gráfico da série diferenciada:
plot(ipca_diff, main = "variação do IPCA (01/1980-10/2025) - série diferenciada", col = "cyan", xlab = "mes", ylab = "IPCA")

#Agora, podemos determinar a função de autocorrelação
acf(ipca_diff)

#observando o gráfico, podemos determinar que q = 1

#determinando a função de autocorrelação parcial
pacf(ipca_diff)

#observando o gráfico, podemos determinar que p = 1

#agora que já temos nossos 3 parâmetros, podemos simular nosso modelo ARIMA(1,1,1)
ipca_111 <- Arima(ipca_ts, order = c(1,1,1))
summary(ipca_111)
Series: ipca_ts 
ARIMA(1,1,1) 

Coefficients:
         ar1      ma1
      0.1872  -1.0000
s.e.  0.1708   0.1075

sigma^2 = 0.07951:  log likelihood = -5.93
AIC=17.87   AICc=18.64   BIC=22.54

Training set error measures:
                      ME      RMSE       MAE      MPE    MAPE      MASE
Training set -0.03865223 0.2699758 0.1914682 54.37901 140.557 0.9358932
                    ACF1
Training set -0.08170351
#AIC = 17.87; ME = -0.038; ar = 0.187; ma = -1.0

#comparando com a função auto.arima
auto.arima(ipca_ts)
Series: ipca_ts 
ARIMA(0,0,0)(0,1,0)[12] 

sigma^2 = 0.06459:  log likelihood = -1.18
AIC=4.36   AICc=4.54   BIC=5.53
#AIC = 4.36; ar = 0; ma = 0

#vamos realizar a previsão para os próximos 6 meses
prev_ipca <- forecast(ipca_111, h = 6)

prev_ipca
         Point Forecast        Lo 80     Hi 80      Lo 95     Hi 95
Nov 2025      0.3308426 -0.035452120 0.6971373 -0.2293568 0.8910420
Dec 2025      0.3759278  0.001475434 0.7503801 -0.1967477 0.9486032
Jan 2026      0.3843676  0.009297846 0.7594374 -0.1892521 0.9579874
Feb 2026      0.3859476  0.010793513 0.7611016 -0.1878010 0.9596961
Mar 2026      0.3862433  0.011074595 0.7614120 -0.1875277 0.9600143
Apr 2026      0.3862987  0.011127251 0.7614701 -0.1874765 0.9600739
#criando o gráfico da previsão
autoplot(prev_ipca) +
  autolayer(fitted(ipca_111), series = "ajustados")  +
  autolayer(ipca_ts, series = "Observado") +
  ggtitle("Previsão ARIMA(1,1,1) inflacao") +
  ylab("inflação (%)") +
  xlab("Tempo")

#mudando as datas de time series para datas de data frame
datas_ajustadas <- as.yearmon(time(prev_ipca$mean))

#criando nosso data frame com as previsões
previsao_df <- data.frame(
  data = datas_ajustadas, 
  previsao = as.numeric(prev_ipca$mean)
)

print(previsao_df)
      data  previsao
1 Nov 2025 0.3308426
2 Dec 2025 0.3759278
3 Jan 2026 0.3843676
4 Feb 2026 0.3859476
5 Mar 2026 0.3862433
6 Apr 2026 0.3862987
write.csv(previsao_df, "ipca.csv", row.names = FALSE)

8ª Questão:

Explique como se estivesse falando para uma pessoa leiga o que são o Critério de Akaike e os erros médios das estimativas produzidas por um modelo ARIMA.

#Os parâmetros do modelo estimado, as estatísticas de AIC e as medidas de erro médio representam informações essenciais para a avaliação do desempenho do modelo. O AIC (Akaike Information Criterion) indica qualidade de ajuste, sendo valores menores associados a melhor desempenho. As medidas de erro médio, por sua vez, expressam a diferença média entre os valores observados e os valores estimados a partir do modelo.