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 pacote dplyr para aplicar transformações no objeto srag_pr_mes.

  • mutate(mes_ano = ano + (mes-1)/12): Também do pacote dplyr, cria uma nova coluna chamada mes_ano no conjunto de dados srag_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 e mes = 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á.

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.

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.

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 com k=3 (suavização mais rígida, menos flexível).,

    • gam8: Suavização com k=7 (mais flexível que k=3).

    • gam9: Suavização com k=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 com k=3.
    • plot(gam8, select=2, main="k=7"): Mostra o efeito da tendência para o modelo com k=7.
    • plot(gam9, select=2, main="k=10"): Mostra o efeito da tendência para o modelo com k=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.

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 ajustado mod_gam2 e os armazena no objeto residuos_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.

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 dados srag_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.