Módulo 8 - GAM em Séries Temporais
Bom, já vimos como incorporar um termo que represente a sazonalidade
da série de SRAG em relação aos meses do ano (s(mes)
). Como
vimos anteriormente, outro componente frequentemente presente nas séries
temporais é a tendência. O efeito da tendência pode ser
incorporado por um termo que capture a variação da média da série
temporal em um médio/longo prazo. Note que o quão médio ou longo será
esse efeito é determinado pela quantidade de nós (o parâmetro
k da função) que vimos anteriormente. Vamos testar a
entrada do termo de tendência, variando alguns valores de k.
Voltemos aos dados de SRAG no Paraná e verifiquemos as primeiras 15 observações do banco:
ano | mes | n | dt_mes |
---|---|---|---|
2013 | 1 | 54 | 2013-01-01 |
2013 | 2 | 66 | 2013-02-01 |
2013 | 3 | 108 | 2013-03-01 |
2013 | 4 | 291 | 2013-04-01 |
2013 | 5 | 718 | 2013-05-01 |
Vemos que nosso banco de dados tem a variável mês (sobre a qual incluímos o termo de sazonalidade) e a variável ano. Para inserir o efeito da tendência, vamos criar uma variável adicional que inclua informações do mês e ano simultaneamente.
srag_pr_mes <- srag_pr_mes %>%
mutate(mes_ano = ano + (mes-1)/12)
Os comandos estão realizando as seguintes ações:
srag_pr_mes %>%
: Utiliza o operador pipe (%>%
) do pacotedplyr
para aplicar transformações no objetosrag_pr_mes
.mutate(mes_ano = ano + (mes-1)/12)
: Também do pacotedplyr
, cria uma nova coluna chamadames_ano
no conjunto de dadossrag_pr_mes
. Essa nova coluna representa o mês/ano em formato decimal, calculado como:O ano (ano) mais a fração do mês (
mes-1
) dividido por 12. Isso transforma o valor do mês em uma fração do ano.
Exemplo de cálculo:
Para
ano
= 2023 emes
= 4:Cálculo: 2023 + (4-1)/12 = 2023 + 3/12 = 2023.25
Resultado: O valor 2023.25 representa abril de 2023 em formato decimal.
Primeiras 5 observações do banco:
ano | mes | n | dt_mes | mes_ano |
---|---|---|---|---|
2013 | 1 | 54 | 2013-01-01 | 2013.000 |
2013 | 2 | 66 | 2013-02-01 | 2013.083 |
2013 | 3 | 108 | 2013-03-01 | 2013.167 |
2013 | 4 | 291 | 2013-04-01 | 2013.250 |
2013 | 5 | 718 | 2013-05-01 | 2013.333 |
Vamos agora inserir uma função suave sobre essa variável criada e visualizar os efeitos estimados (Figura 47):
mod_gam2 <- gam(n ~ s(mes) + s(mes_ano, k=6), data=srag_pr_mes, family = "poisson")
par(mfrow=c(2,1))
plot(mod_gam2, select = 1, main = "Efeito do mês (sazonalidade)")
plot(mod_gam2, select = 2, main = "Efeito sobre o tempo (tendência)")
Figura 47. Efeitos não lineares da sazonalidade e da tendência temporal estimados por modelo GAM aos dados de SRAG no Paraná.
Este script está ajustando o modelo GAM através do comando
mod_gam2 <- gam(n ~ s(mes) + s(mes_ano, k=6), data=srag_pr_mes, family = "poisson")
com suavizações para capturar os efeitos não lineares da sazonalidade mensal (s(mes)
) e da tendência temporal ao longo dos anos (s(mes_ano, k=6)
), utilizando distribuição de Poisson para modelar contagens.Para a configuração dos gráficos, está sendo utilizada a função
par(mfrow=c(2,1))
, que divide a janela gráfica em duas áreas verticais para exibir dois gráficos.E para visualização dos efeitos, está sendo utilizado:
plot(mod_gam2, select = 1, main = "Efeito do mês (sazonalidade)")
: Mostra o efeito da sazonalidade mensal sobre os casos.plot(mod_gam2, select = 2, main = "Efeito sobre o tempo (tendência)")
: Mostra a tendência de longo prazo nos casos ao longo dos anos.
Vamos também ver os valores ajustados (Figura 48):
Figura 48: Casos de SRAG no Paraná observados comparado com valores ajustados por modelos GAM com e sem tendência.
Da mesma forma que testamos com a sazonalidade, podemos testar diferentes valores de k para o termo da tendência:
gam7 <- gam(n ~ s(mes) + s(mes_ano, k=3), data=srag_pr_mes, family = "poisson")
gam8 <- gam(n ~ s(mes) + s(mes_ano, k=7), data=srag_pr_mes, family = "poisson")
gam9 <- gam(n ~ s(mes) + s(mes_ano, k=10), data=srag_pr_mes, family = "poisson")
par(mfrow=c(3,1))
plot(gam7, select=2, main="k=3")
plot(gam8, select=2, main="k=7")
plot(gam9, select=2, main="k=10")
Figura 49: Relação entre mês de primeiros sintomas e casos de SRAG no Paraná estimada com diferentes dimensões de tendência de modelo GAM.
O script está ajustando três modelos aditivos generalizados (GAM)
para a variável n
(casos de SRAG) no conjunto de dados
srag_pr_mes
, variando o número de nós (k
) para
suavização da tendência temporal (mes_ano
). Em seguida, ele
exibe gráficos comparando o efeito da suavização com diferentes valores
de k
.
O Ajuste de modelos GAM com diferentes níveis de suavização:
gam7
: Suavização da tendência ao longo do tempo comk=3
(suavização mais rígida, menos flexível).,gam8
: Suavização comk=7
(mais flexível quek=3
).gam9
: Suavização comk=10
(ainda mais flexível).
Configuração de múltiplos gráficos:
par(mfrow=c(3,1))
: Configura a área gráfica para exibir três gráficos empilhados (3 linhas, 1 coluna).
Visualização do efeito da tendência temporal
s(mes_ano)
:plot(gam7, select=2, main="k=3")
: Mostra o efeito da tendência para o modelo comk=3
.plot(gam8, select=2, main="k=7")
: Mostra o efeito da tendência para o modelo comk=7
.plot(gam9, select=2, main="k=10")
: Mostra o efeito da tendência para o modelo comk=10
.
Resumindo, este script visa ajustar modelos GAM com diferentes graus
de suavização para a tendência temporal e compara visualmente o efeito
da escolha do número de nós (k
) na flexibilidade das curvas
de tendência.
Veja na Figura 49 que um valor de k pequeno captura uma tendência de mais longo prazo e, conforme aumentamos o valor de k, temos mais especificidade sobre as variações ao longo do tempo.
De forma similar à feita com modelos ARIMA, podemos verificar se há algum padrão restante nos resíduos (como autocorrelação):
residuos_gam <- residuals(mod_gam2)
acf(residuos_gam)
Figura 50: Função de autocorrelação dos resíduos do modelo GAM.
residuos_gam <- residuals(mod_gam2)
: Calcula os resíduos do modelo GAM ajustadomod_gam2
e os armazena no objetoresiduos_gam
.acf(residuos_gam)
: Gera o gráfico da função de autocorrelação (ACF) dos resíduos, avaliando se há dependência temporal (autocorrelação) entre eles.
O objetivo é verificar se os resíduos do modelo são independentes, como esperado para um bom ajuste de modelo.
Vemos que ainda há certa autocorrelação no lag 1. Podemos comparar como a autocorrelação dos resíduos se comporta entre os diferentes valores de k testados:
Figura 51: Função de autocorrelação dos resíduos de modelos GAM com diferentes dimensões de tendência.
Observamos na Figura 51 que os resíduos dos modelos para k=3 e k=7 possuem autocorrelação relevante nos primeiros lags. O modelo com k=10 se comporta melhor, mas ainda com autocorrelação presente no lag 4.
Note que modelar a tendência da série é uma forma simplificada de entender os componentes da série, e pode ser utilizado de maneira exploratória em diversos casos. Quando há dependência temporal entre as observações (autocorrelação), a forma correta de modelar a série é por meio de termos de autocorrelação (AR) ou de Médias Móveis (MA). Para os modelos GAM, há uma extensão chamada de Modelos Aditivos Generalizados Mistos (GAMM), que possibilita a incorporação de termos de AR ou MA ao modelo que poderão tratar a autocorrelação de maneira mais adequada. Para maior compreensão sobre esse tipo de modelos, recomendamos a leitura de Pedersen et. al (2019).
srag_pr_futuro <- srag_pr_mes %>%
select(1:3) %>%
add_row(tibble(ano = 2018, mes = 1:12)) %>%
mutate(
dt_mes = as.Date(paste0(ano, "-", mes, "-01")),
mes_ano = ano + (mes-1)/12
)
previsao_gam <- mod_gam2 %>% predict(newdata = srag_pr_futuro, se.fit = T)
previsao_gam$inf <- previsao_gam$pred - 1.96 * previsao_gam$se
previsao_gam$sup <- previsao_gam$pred + 1.96 * previsao_gam$se
Este script está preparando dados futuros para projeção e realizando previsões com o modelo GAM ajustado, incluindo intervalos de confiança.
1. Criação de um conjunto de dados para previsão futura
select(1:3)
: Seleciona as três primeiras colunas do conjunto de dadossrag_pr_mes
.add_row(tibble(ano = 2018, mes = 1:12))
: Adiciona 12 novas linhas ao conjunto de dados, representando os meses de janeiro a dezembro de 2018.mutate(...)
: Cria/transforma colunas:dt_mes
: Converte as combinações de ano e mes em datas no formato “YYYY-MM-DD” (sempre o dia 1).mes_ano
: Converte ano e mês em uma escala contínua para facilitar cálculos temporais.
2. Previsão utilizando o modelo GAM
predict()
: Gera previsões a partir do modelo mod_gam2, utilizando o conjunto de dados srag_pr_futuro.newdata = srag_pr_futuro:
Aplica as previsões aos dados futuros.se.fit = T
: Retorna também o erro padrão das previsões (standard error).
3. Cálculo do intervalo de confiança
Calcula os limites do intervalo de confiança de 95% para as previsões:
inf
: Limite inferior = previsão (pred) - 1,96 × erro padrão (se).sup
: Limite superior = previsão (pred) + 1,96 × erro padrão (se).
Resumindo, as linhas de comando acima tem por objetivo preparar o conjunto de dados para previsão futura (adicionando novos dados), realizar previsões com o modelo GAM ajustado e calcular intervalos de confiança de 95% para as previsões.