cat("Conclusão:", ifelse(adf_diff$p.value <0.05,"Série estacionária após diferenciação sazonal","Ainda não estacionária"), "\n")
#> Conclusão: Série estacionária após diferenciação sazonal
4.4 Análise de Autocorrelação
4.4.1 ACF - Função de Autocorrelação
A ACF mede a correlação entre \(Y_t\) e \(Y_{t-k}\) para diferentes lags \(k\).
Mostrar código
acf_result <-acf(y_clean, lag.max =104, plot =FALSE)acf_df <-data.frame(lag = acf_result$lag[-1],acf = acf_result$acf[-1])# Limite de significancian <-length(y_clean)ci <-qnorm(0.975) /sqrt(n)p_acf <-ggplot(acf_df, aes(x = lag, y = acf)) +geom_hline(yintercept =0, color ="gray50") +geom_hline(yintercept =c(-ci, ci), linetype ="dashed", color ="blue") +geom_segment(aes(xend = lag, yend =0), color = cores["observado"]) +geom_point(color = cores["observado"], size =1) +geom_vline(xintercept =52, linetype ="dotted", color ="red", linewidth =1) +annotate("text",x =54, y =0.6, label ="Lag 52\n(1 ano)",color ="red", hjust =0, size =3 ) +labs(title ="Função de Autocorrelação (ACF)",subtitle ="Linhas azuis: intervalo de confiança 95%",x ="Lag (semanas)",y ="Autocorrelação" ) +scale_x_continuous(breaks =seq(0, 104, by =13))p_acf
Figura 5: Função de Autocorrelação (ACF) da série de incidência
Interpretação do ACF
Decaimento lento: Indica não-estacionariedade (tendência ou raiz unitária)
Pico no lag 52: Forte correlação com a mesma semana do ano anterior (sazonalidade anual)
Autocorrelações significativas: Estrutura de dependência temporal que pode ser modelada
4.4.2 PACF - Função de Autocorrelação Parcial
O PACF mede a correlação entre \(Y_t\) e \(Y_{t-k}\) após remover o efeito dos lags intermediários.
Mostrar código
pacf_result <-pacf(y_clean, lag.max =104, plot =FALSE)pacf_df <-data.frame(lag = pacf_result$lag,pacf = pacf_result$acf)ggplot(pacf_df, aes(x = lag, y = pacf)) +geom_hline(yintercept =0, color ="gray50") +geom_hline(yintercept =c(-ci, ci), linetype ="dashed", color ="blue") +geom_segment(aes(xend = lag, yend =0), color = cores["observado"]) +geom_point(color = cores["observado"], size =1) +labs(title ="Função de Autocorrelação Parcial (PACF)",subtitle ="Linhas azuis: intervalo de confiança 95%",x ="Lag (semanas)",y ="Autocorrelação Parcial" ) +scale_x_continuous(breaks =seq(0, 104, by =13))
Figura 6: Função de Autocorrelação Parcial (PACF)
Sugestão de Modelo SARIMA
Baseado no ACF/PACF: - Componente AR: PACF com corte abrupto após lag 2 sugere \(p = 2\) - Diferenciação: Série precisa de 1 diferenciação sazonal (\(D = 1\)) - Modelo sugerido: SARIMA\((2, 0, 0) \times (0, 1, 0)_{52}\) ou similar
4.4.3 ACF da Série Diferenciada
Mostrar código
par(mfrow =c(1, 2))acf(y_diff, lag.max =104, main ="ACF - Série Diferenciada")pacf(y_diff, lag.max =104, main ="PACF - Série Diferenciada")par(mfrow =c(1, 1))
Figura 7: ACF e PACF após diferenciação sazonal (lag 52)
4.5 Análise de Variáveis Climáticas
4.5.1 Correlação Cruzada (CCF)
A correlação cruzada identifica se e quando as variáveis climáticas precedem a incidência de dengue.
Figura 9: Correlação cruzada: Precipitação × Incidência de dengue
5 Engenharia de Atributos (Feature Engineering)
Esta seção demonstra os módulos de engenharia de atributos disponíveis em R/features/ e explica a justificativa estatística para cada tipo de feature.
5.1 Visão Geral do Motor de Features
O módulo R/features/engine.R orquestra a criação de todas as features:
Mostrar código
# Carregar configuracao de featuresconfig_features <-load_config("features")# Listar tipos de features habilitadascat("=== Tipos de Features Habilitadas ===\n\n")
Figura 12: Harmônicos de Fourier por semana epidemiológica
Vantagem dos Harmônicos
Comparado a dummies de semana (52 variáveis): - Menos parâmetros: 4 vs. 51 - Continuidade: Transição suave entre semanas - Regularização natural: Restrição implícita na forma da curva
5.3.2 Estatísticas Sazonais
Mostrar código
# Calcular media sazonalseasonal_stats <-compute_seasonal_mean(df, target ="est_inc100k")# Calcular quantis sazonaisseasonal_quantiles <-compute_seasonal_quantiles(df, target ="est_inc100k")# Juntar dadosseasonal_profile <-left_join(seasonal_stats, seasonal_quantiles, by ="semana")ggplot(seasonal_profile, aes(x = semana)) +geom_ribbon(aes(ymin = q25, ymax = q75), fill = cores["sazonalidade"], alpha =0.3) +geom_ribbon(aes(ymin = q50 - seasonal_sd, ymax = q50 + seasonal_sd),fill = cores["sazonalidade"], alpha =0.2 ) +geom_line(aes(y = seasonal_mean), color = cores["observado"], linewidth =1.2) +geom_line(aes(y = seasonal_median),color = cores["tendencia"],linewidth =1, linetype ="dashed" ) +labs(title ="Perfil Sazonal da Incidência de Dengue",subtitle ="Linha preta = Média | Linha vermelha = Mediana | Faixa = IQR",x ="Semana epidemiológica",y ="Incidência por 100 mil" ) +scale_x_continuous(breaks =seq(1, 52, by =4))
Figura 13: Perfil sazonal da incidência de dengue
5.4 Módulo R/features/climate.R
5.4.1 Lags Climáticos
Baseado na análise de CCF, criamos lags das variáveis climáticas:
Mostrar código
# Buscar config de climaclima_config <- config_features$climatedata.frame(Variavel =c("Temperatura", "Temp. Máxima", "Temp. Mínima", "Precipitação"),Lags =paste(clima_config$lags, collapse =", "),Justificativa =c("Ciclo biológico do vetor: 2-8 semanas de atraso","Mesma justificativa + extremos de calor","Mesma justificativa + limites de desenvolvimento","Acúmulo de criadouros: efeito mais lento" )) |>kable() |>kable_styling(bootstrap_options =c("striped", "hover"))
A amplitude térmica (diferença entre máxima e mínima) é um indicador importante:
Mostrar código
if ("temp_range"%in%names(df_features)) { df_temp_range <- df_features |>filter(!is.na(temp_range)) |>select(data_iniSE, temp_range, est_inc100k) p1 <-ggplot(df_temp_range, aes(x = data_iniSE)) +geom_line(aes(y = temp_range), color = cores["temperatura"]) +labs(title ="Amplitude Térmica", y ="°C", x =NULL) p2 <-ggplot(df_temp_range, aes(x = temp_range, y = est_inc100k)) +geom_point(alpha =0.3, color = cores["observado"]) +geom_smooth(method ="loess", color = cores["tendencia"]) +labs(title ="Relação com Incidência", x ="Amplitude (°C)", y ="Incidência") p1 + p2 +plot_annotation(title ="Feature: Amplitude Térmica (temp_max - temp_min)")} else {cat("Feature temp_range não disponível nos dados processados.")}
Figura 14: Amplitude térmica e sua relação com incidência
6 Análise de Correlações
6.1 Matriz de Correlação das Features
Mostrar código
# Selecionar features numericasfeature_names <-get_feature_names(df_features)feature_names <-c("est_inc100k", feature_names)df_corr <- df_features |>select(all_of(intersect(feature_names, names(df_features)))) |>select(where(is.numeric)) |>drop_na()# Calcular matriz de correlacaocor_matrix <-cor(df_corr, use ="pairwise.complete.obs")# Plotcorrplot( cor_matrix,method ="color",type ="lower",order ="hclust",tl.cex =0.6,tl.col ="black",addCoef.col ="gray30",number.cex =0.5,diag =FALSE,title ="Correlação entre Features",mar =c(0, 0, 2, 0))
Figura 15: Matriz de correlação das features criadas
6.2 Correlação com o Alvo
Mostrar código
# Calcular correlacoes com o alvocor_with_target <- cor_matrix[, "est_inc100k"]cor_with_target <- cor_with_target[names(cor_with_target) !="est_inc100k"]# Top 15top_cors <-sort(abs(cor_with_target), decreasing =TRUE)[1:15]cor_df <-data.frame(feature =names(top_cors),correlacao = cor_with_target[names(top_cors)]) |>mutate(tipo =case_when(grepl("lag_|roll_|diff_|growth", feature) ~"Temporal",grepl("sin_|cos_", feature) ~"Sazonal",grepl("temp|precip", feature) ~"Climática",TRUE~"Outra" ) )ggplot(cor_df, aes(x =reorder(feature, abs(correlacao)), y = correlacao, fill = tipo)) +geom_col() +coord_flip() +scale_fill_brewer(palette ="Set2") +geom_hline(yintercept =0, linetype ="dashed") +labs(title ="Top 15 Features Mais Correlacionadas com Incidência",x =NULL,y ="Correlação de Pearson",fill ="Tipo" )
Figura 16: Top 15 features mais correlacionadas com a incidência
6.3 Multicolinearidade
Mostrar código
# Encontrar pares com alta correlacaohigh_cor <-which(abs(cor_matrix) >0.9&abs(cor_matrix) <1, arr.ind =TRUE)if (nrow(high_cor) >0) { high_cor_pairs <-data.frame(Feature1 =rownames(cor_matrix)[high_cor[, 1]],Feature2 =colnames(cor_matrix)[high_cor[, 2]],Correlacao =round(cor_matrix[high_cor], 3) ) |>filter(Feature1 < Feature2) |># Remover duplicatasarrange(desc(abs(Correlacao))) |>head(10) high_cor_pairs |>kable() |>kable_styling(bootstrap_options =c("striped", "hover"))} else {cat("Nenhum par de features com correlação > 0.9")}
Tabela 9: Pares de features com alta correlação (> 0.9)
Feature1
Feature2
Correlacao
lag_2
roll_mean_4
0.996
lag_3
roll_mean_4
0.996
roll_max_4
roll_mean_4
0.992
lag_4
roll_mean_8
0.992
lag_3
roll_max_4
0.989
est_inc100k
lag_1
0.986
lag_1
lag_2
0.986
lag_2
lag_3
0.986
lag_3
lag_4
0.986
lag_6
roll_mean_12
0.986
Atenção: Multicolinearidade
Features altamente correlacionadas podem causar: - Instabilidade em coeficientes de modelos lineares - Redundância que aumenta dimensionalidade desnecessariamente - Overfitting em modelos de árvore
Recomendação: Considerar seleção de features ou regularização (Lasso, Ridge).
7 Conclusões e Próximos Passos
7.1 Principais Achados
Mostrar código
data.frame(Aspecto =c("Qualidade dos Dados","Sazonalidade","Estacionariedade","Autocorrelação","Clima","Features" ),Achado =c( dq_report$passed |>ifelse("Dados de boa qualidade", "Há problemas a tratar"),"Forte padrão anual com picos no verão (52 semanas)","Série não-estacionária; diferenciação sazonal necessária","Dependência de curto prazo (AR) e sazonalidade (lag 52)","Temperatura precede incidência em 4-8 semanas (CCF)",sprintf("%d features criadas cobrindo aspectos temporais, sazonais e climáticos",length(features_criadas) ) ),Implicacao =c("Pode-se prosseguir com modelagem","Modelos devem incluir componente sazonal (SARIMA, Prophet)","SARIMA com D=1 ou diferenciação antes de ML","Modelos AR são apropriados; considerar p=2","Incluir lags climáticos nos modelos de regressão","Seleção de features pode melhorar performance" )) |>kable() |>kable_styling(bootstrap_options =c("striped", "hover"))
Tabela 10: Resumo dos principais achados da análise exploratória
Aspecto
Achado
Implicacao
Qualidade dos Dados
Dados de boa qualidade
Pode-se prosseguir com modelagem
Sazonalidade
Forte padrão anual com picos no verão (52 semanas)
Prophet: Para captura automática de tendência e sazonalidade
XGBoost/LightGBM: Com features temporais, sazonais e climáticas
Ensemble: Combinar modelos para robustez
7.3 Limitações
Mudança de regime em 2024: Surto sem precedentes pode afetar modelos treinados em dados históricos
Covariáveis limitadas: Apenas clima; fatores socioeconômicos e ações de controle não incluídos
Horizonte de previsão: Qualidade degrada significativamente após 4-6 semanas
7.4 Próximos Passos
Treinar modelos com diferentes horizontes (h = 4, 6, 8 semanas)
Validação temporal via rolling-origin (já implementada em preprocess.R)
Comparar métricas (MAE, RMSE, MASE) entre modelos
Avaliar calibração das previsões probabilísticas
Investigar mudança de regime e possível adaptação de modelos
8 Referências dos Módulos R
Mostrar código
data.frame(Modulo =c("R/data/loader.R","R/data/preprocess.R","R/data/quality.R","R/features/temporal.R","R/features/seasonal.R","R/features/climate.R","R/features/engine.R" ),Funcoes =c("load_raw_data(), aggregate_state(), load_processed_data()","preprocess_data(), impute_climate_nas(), create_rolling_splits()","run_data_quality(), check_completeness(), check_duplicates()","add_temporal_features(), create_lag(), rolling_mean(), create_diff()","add_seasonal_features(), create_fourier_terms(), compute_seasonal_mean()","add_climate_features(), add_climate_anomalies(), create_extreme_indicator()","make_features(), clean_features(), create_model_matrix()" ),Proposito =c("Carregamento e agregação de dados","Preprocessamento e validação temporal","Controle de qualidade","Features baseadas em lags e agregações","Harmônicos de Fourier e estatísticas sazonais","Lags e transformações de variáveis climáticas","Orquestração e limpeza de features" )) |>kable() |>kable_styling(bootstrap_options =c("striped", "hover"))
Tabela 11: Resumo dos módulos R utilizados neste relatório
---title: "Análise Exploratória de Séries Temporais para Previsão de Dengue"subtitle: "Fundamentos Estatísticos e Engenharia de Atributos"author: - "UIVS - Unidade de Inteligência em Vigilância em Saúde" - "Caio Sain Vallio"date: last-modifieddate-format: "DD/MM/YYYY"lang: pt-BRformat: html: embed-resources: true toc: true toc-depth: 4 toc-expand: 2 number-sections: true code-fold: true code-summary: "Mostrar código" code-tools: true theme: light: flatly dark: darkly highlight-style: github df-print: kable include-in-header: text: | <style> .plotly { width: 100% !important; max-width: 100% !important; } .plotly.html-widget { width: 100% !important; height: auto !important; } .callout-note { border-left-color: #3498DB !important; } </style>execute: echo: true warning: false message: false---```{r}#| label: setup#| include: false# Configuracao inicialknitr::opts_chunk$set(fig.align ="center",out.width ="100%",out.height ="auto",comment ="#>")# Raiz do projetoPROJECT_ROOT <- here::here()# Carregar modulos do projetosource(file.path(PROJECT_ROOT, "R", "init.R"))# Pacotes adicionais para analisesuppressPackageStartupMessages({library(tidyverse)library(lubridate)library(forecast)library(tseries)library(patchwork)library(scales)library(knitr)library(kableExtra)library(plotly)library(corrplot)})# Definir tema padrao para graficostheme_set(theme_minimal(base_size =12) +theme(plot.title =element_text(face ="bold", size =14),plot.subtitle =element_text(color ="gray40"),legend.position ="bottom",panel.grid.minor =element_blank() ))# Cores padrao - REGRA: linha PRETA para dados reaiscores <-c("observado"="#000000","tendencia"="#E74C3C","sazonalidade"="#3498DB","residuo"="#2ECC71","temperatura"="#E67E22","precipitacao"="#9B59B6")```# Introdução## Objetivo do RelatórioEste relatório apresenta uma **análise exploratória abrangente** dos dados de série temporal de dengue no Estado de São Paulo, com os seguintes objetivos:1. **Compreender a estrutura dos dados** utilizando os módulos R do projeto2. **Avaliar a qualidade dos dados** antes de qualquer modelagem3. **Identificar padrões temporais** (tendência, sazonalidade, ciclos)4. **Demonstrar a engenharia de atributos** implementada no projeto5. **Estabelecer fundamentos estatísticos** para modelos de forecast::: {.callout-note}## Base para ModelagemEste documento serve como **base sólida** para posterior aplicação e estudo de modelos de previsão (SARIMA, Prophet, ML, etc.).:::## Visão Geral dos DadosOs dados utilizados compreendem:- **Fonte**: SINAN - Secretaria de Saúde do Estado de São Paulo- **Período**: 2014 a 2025- **Frequência**: Semanal (semanas epidemiológicas)- **Granularidade**: Agregado por Estado de São Paulo- **Variável alvo**: Incidência estimada por 100 mil habitantes (`est_inc100k`)- **Covariáveis climáticas**: Temperatura e precipitação---# Carregamento e Preparação dos Dados## Módulo `R/data/loader.R`O módulo `loader.R` fornece funções para carregar e agregar dados. Vamos demonstrar seu uso:### Função `load_raw_data()`Carrega os dados brutos do arquivo `.RData` que contém informações por município.```{r}#| label: load-raw# Carregar dados brutosdf_raw <-load_raw_data()# Estrutura dos dados brutoscat("Dimensões:", nrow(df_raw), "linhas x", ncol(df_raw), "colunas\n\n")cat("Variáveis disponíveis:\n")names(df_raw)```### Função `aggregate_state()`Agrega os dados dos municípios para o nível estadual, calculando:- Soma de casos e população- Média ponderada de incidência- Média de variáveis climáticas```{r}#| label: aggregate-state# Agregar para nivel estadualdf_estado <-aggregate_state(df_raw)# Visualizar estruturaglimpse(df_estado)```## Módulo `R/data/preprocess.R`O módulo `preprocess.R` aplica transformações essenciais aos dados.### Função `preprocess_data()`Pipeline completo que:1. Remove semana 53 (incompleta em alguns anos)2. Preenche semanas faltantes3. Imputa NAs em covariáveis climáticas4. Adiciona transformação logarítmica do alvo5. Cria índice temporal```{r}#| label: preprocess# Preprocessar dadosdf <-preprocess_data(df_estado)# Resumo apos preprocessamentocat("Período:",format(min(df$data_iniSE), "%d/%m/%Y"), "a",format(max(df$data_iniSE), "%d/%m/%Y"), "\n")cat("Total de semanas:", nrow(df), "\n")cat("Variáveis:", ncol(df), "\n")``````{r}#| label: tbl-resumo-estatistico#| tbl-cap: "Resumo estatístico das principais variáveis"df |>select(est_inc100k, mean_temp, mean_precip, y_log) |>summary() |>kable(digits =2) |>kable_styling(bootstrap_options =c("striped", "hover"))```---# Controle de Qualidade dos Dados## Módulo `R/data/quality.R`O módulo `quality.R` implementa verificações sistemáticas de qualidade dos dados, essenciais antes de qualquer análise ou modelagem.### Função `run_data_quality()`Executa todas as checagens de qualidade e retorna um relatório estruturado:```{r}#| label: data-quality# Executar checagens de qualidadedq_report <-run_data_quality(df)# Imprimir relatorioprint(dq_report)```### Detalhamento das Checagens```{r}#| label: tbl-checagens-qualidade#| tbl-cap: "Detalhamento das verificações de qualidade dos dados"data.frame(Checagem =c("check_completeness()","check_duplicates()","check_temporal_order()","check_plausible_ranges()" ),Descricao =c("Verifica NAs por variável (crítico se > 50%)","Identifica datas duplicadas na série","Valida ordenação cronológica e gaps","Confirma valores dentro de faixas plausíveis" ),Status =c(if (dq_report$checks$completeness$passed) "✓ OK"else"✗ Atenção",if (dq_report$checks$duplicates$passed) "✓ OK"else"✗ Atenção",if (dq_report$checks$temporal$passed) "✓ OK"else"✗ Atenção",if (dq_report$checks$ranges$passed) "✓ OK"else"✗ Atenção" )) |>kable() |>kable_styling(bootstrap_options =c("striped", "hover"))```### Verificação de Completude```{r}#| label: fig-completude#| fig-cap: "Proporção de valores faltantes por variável"# Calcular proporcao de NAsna_props <-sapply(df, function(x) mean(is.na(x))) *100na_df <-data.frame(variavel =names(na_props),proporcao =as.numeric(na_props)) |>filter(proporcao >0) |>arrange(desc(proporcao))if (nrow(na_df) >0) {ggplot(na_df, aes(x =reorder(variavel, proporcao), y = proporcao)) +geom_col(fill = cores["tendencia"], alpha =0.8) +coord_flip() +labs(title ="Valores Faltantes por Variável",x =NULL,y ="% de NAs" ) +scale_y_continuous(labels =function(x) paste0(x, "%"))} else {cat("Nenhum valor faltante encontrado nas variáveis principais.")}```---# Análise Exploratória da Série Temporal## Visualização da Série de Incidência```{r}#| label: fig-serie-temporal#| fig-cap: "Série temporal da incidência de dengue no Estado de São Paulo"p <-ggplot(df, aes(x = data_iniSE, y = est_inc100k)) +geom_line(color = cores["observado"], linewidth =0.8) +geom_smooth(method ="loess",span =0.1,se =TRUE,color = cores["tendencia"],linewidth =1,alpha =0.2 ) +labs(title ="Incidência de Dengue - Estado de São Paulo",subtitle ="Linha preta = Observado | Linha vermelha = Tendência suavizada (LOESS)",x ="Data",y ="Incidência por 100 mil hab." ) +scale_x_date(date_breaks ="1 year", date_labels ="%Y") +scale_y_continuous(labels =comma_format(big.mark =".", decimal.mark =",") )ggplotly(p, tooltip =c("x", "y")) |>layout(hovermode ="x unified",autosize =TRUE,width =NULL,height =450 )```::: {.callout-important}## Observações Principais- **Sazonalidade evidente**: Picos anuais consistentes durante o verão (dez-mar)- **Variabilidade interanual**: Intensidade dos surtos varia significativamente entre anos- **Mudança de regime em 2024**: Surto de magnitude sem precedentes na série histórica:::## Decomposição STLA **decomposição STL** (Seasonal and Trend decomposition using Loess) separa a série em três componentes:1. **Tendência** ($T_t$): Evolução de longo prazo2. **Sazonalidade** ($S_t$): Padrão repetitivo anual (período = 52 semanas)3. **Resíduo** ($R_t$): Variação não explicada$$Y_t = T_t + S_t + R_t$$```{r}#| label: fig-decomposicao#| fig-cap: "Decomposição STL da série de incidência de dengue"#| fig-height: 6# Remover NAs e criar objeto tsdf_clean <- df |>filter(!is.na(est_inc100k))y_ts <-ts(df_clean$est_inc100k, frequency =52)# Decomposicao STLdecomp <-stl(y_ts, s.window ="periodic", robust =TRUE)# Plot da decomposicaoautoplot(decomp) +labs(title ="Decomposição STL da Incidência de Dengue") +theme_minimal()``````{r}#| label: tbl-variancia-componentes#| tbl-cap: "Contribuição de cada componente para a variância total"# Calcular varianciasvar_trend <-var(decomp$time.series[, "trend"], na.rm =TRUE)var_season <-var(decomp$time.series[, "seasonal"], na.rm =TRUE)var_remainder <-var(decomp$time.series[, "remainder"], na.rm =TRUE)var_total <-var(df_clean$est_inc100k, na.rm =TRUE)data.frame(Componente =c("Tendência", "Sazonalidade", "Resíduo"),Variancia =c(var_trend, var_season, var_remainder),Proporcao =c(var_trend, var_season, var_remainder) / var_total *100) |>mutate(Variancia =round(Variancia, 2),Proporcao =sprintf("%.1f%%", Proporcao) ) |>kable(col.names =c("Componente", "Variância", "% do Total")) |>kable_styling(bootstrap_options =c("striped", "hover"))```## Análise de EstacionariedadePara modelagem com ARIMA, é fundamental verificar se a série é **estacionária** (média e variância constantes no tempo).### Teste Augmented Dickey-Fuller (ADF)- **H0**: A série tem raiz unitária (não estacionária)- **H1**: A série é estacionária```{r}#| label: teste-adf# Teste ADF na serie originaladf_original <-adf.test(na.omit(df$est_inc100k))cat("=== Teste ADF - Série Original ===\n")cat("Estatística ADF:", round(adf_original$statistic, 4), "\n")cat("P-valor:", round(adf_original$p.value, 4), "\n")cat("Conclusão:", ifelse(adf_original$p.value <0.05,"Série estacionária (rejeita H0)","Série NÃO estacionária (não rejeita H0)"), "\n")```### Teste KPSS- **H0**: A série é estacionária- **H1**: A série tem raiz unitária```{r}#| label: teste-kpss# Teste KPSSkpss_original <-kpss.test(na.omit(df$est_inc100k))cat("=== Teste KPSS - Série Original ===\n")cat("Estatística KPSS:", round(kpss_original$statistic, 4), "\n")cat("P-valor:", round(kpss_original$p.value, 4), "\n")cat("Conclusão:", ifelse(kpss_original$p.value <0.05,"Série NÃO estacionária (rejeita H0)","Série estacionária (não rejeita H0)"), "\n")```### Efeito da Diferenciação SazonalAplicando diferenciação sazonal ($\nabla_{52} Y_t = Y_t - Y_{t-52}$) para remover a sazonalidade:```{r}#| label: fig-diferenciacao#| fig-cap: "Série original vs. série diferenciada sazonalmente"y_clean <-na.omit(df$est_inc100k)y_diff <-diff(y_clean, lag =52)# Criar dataframe para plotdf_diff <-data.frame(t =1:length(y_diff),valor = y_diff)p1 <-ggplot(df_clean, aes(x = data_iniSE, y = est_inc100k)) +geom_line(color = cores["observado"]) +labs(title ="Série Original", x =NULL, y ="Incidência")p2 <-ggplot(df_diff, aes(x = t, y = valor)) +geom_line(color = cores["tendencia"]) +geom_hline(yintercept =0, linetype ="dashed", alpha =0.5) +labs(title ="Série Diferenciada (lag = 52)", x ="Tempo", y ="Diferença")p1 / p2 +plot_annotation(title ="Efeito da Diferenciação Sazonal")``````{r}#| label: teste-adf-diff# Testar estacionariedade apos diferenciacaoadf_diff <-adf.test(y_diff)cat("=== Teste ADF - Série Diferenciada ===\n")cat("Estatística ADF:", round(adf_diff$statistic, 4), "\n")cat("P-valor:", round(adf_diff$p.value, 4), "\n")cat("Conclusão:", ifelse(adf_diff$p.value <0.05,"Série estacionária após diferenciação sazonal","Ainda não estacionária"), "\n")```## Análise de Autocorrelação### ACF - Função de AutocorrelaçãoA ACF mede a correlação entre $Y_t$ e $Y_{t-k}$ para diferentes lags $k$.```{r}#| label: fig-acf#| fig-cap: "Função de Autocorrelação (ACF) da série de incidência"acf_result <-acf(y_clean, lag.max =104, plot =FALSE)acf_df <-data.frame(lag = acf_result$lag[-1],acf = acf_result$acf[-1])# Limite de significancian <-length(y_clean)ci <-qnorm(0.975) /sqrt(n)p_acf <-ggplot(acf_df, aes(x = lag, y = acf)) +geom_hline(yintercept =0, color ="gray50") +geom_hline(yintercept =c(-ci, ci), linetype ="dashed", color ="blue") +geom_segment(aes(xend = lag, yend =0), color = cores["observado"]) +geom_point(color = cores["observado"], size =1) +geom_vline(xintercept =52, linetype ="dotted", color ="red", linewidth =1) +annotate("text",x =54, y =0.6, label ="Lag 52\n(1 ano)",color ="red", hjust =0, size =3 ) +labs(title ="Função de Autocorrelação (ACF)",subtitle ="Linhas azuis: intervalo de confiança 95%",x ="Lag (semanas)",y ="Autocorrelação" ) +scale_x_continuous(breaks =seq(0, 104, by =13))p_acf```::: {.callout-note}## Interpretação do ACF- **Decaimento lento**: Indica não-estacionariedade (tendência ou raiz unitária)- **Pico no lag 52**: Forte correlação com a mesma semana do ano anterior (sazonalidade anual)- **Autocorrelações significativas**: Estrutura de dependência temporal que pode ser modelada:::### PACF - Função de Autocorrelação ParcialO PACF mede a correlação entre $Y_t$ e $Y_{t-k}$ após remover o efeito dos lags intermediários.```{r}#| label: fig-pacf#| fig-cap: "Função de Autocorrelação Parcial (PACF)"pacf_result <-pacf(y_clean, lag.max =104, plot =FALSE)pacf_df <-data.frame(lag = pacf_result$lag,pacf = pacf_result$acf)ggplot(pacf_df, aes(x = lag, y = pacf)) +geom_hline(yintercept =0, color ="gray50") +geom_hline(yintercept =c(-ci, ci), linetype ="dashed", color ="blue") +geom_segment(aes(xend = lag, yend =0), color = cores["observado"]) +geom_point(color = cores["observado"], size =1) +labs(title ="Função de Autocorrelação Parcial (PACF)",subtitle ="Linhas azuis: intervalo de confiança 95%",x ="Lag (semanas)",y ="Autocorrelação Parcial" ) +scale_x_continuous(breaks =seq(0, 104, by =13))```::: {.callout-tip}## Sugestão de Modelo SARIMABaseado no ACF/PACF:- **Componente AR**: PACF com corte abrupto após lag 2 sugere $p = 2$- **Diferenciação**: Série precisa de 1 diferenciação sazonal ($D = 1$)- **Modelo sugerido**: SARIMA$(2, 0, 0) \times (0, 1, 0)_{52}$ ou similar:::### ACF da Série Diferenciada```{r}#| label: fig-acf-diff#| fig-cap: "ACF e PACF após diferenciação sazonal (lag 52)"par(mfrow =c(1, 2))acf(y_diff, lag.max =104, main ="ACF - Série Diferenciada")pacf(y_diff, lag.max =104, main ="PACF - Série Diferenciada")par(mfrow =c(1, 1))```## Análise de Variáveis Climáticas### Correlação Cruzada (CCF)A **correlação cruzada** identifica se e quando as variáveis climáticas precedem a incidência de dengue.```{r}#| label: fig-ccf-temperatura#| fig-cap: "Correlação cruzada: Temperatura média × Incidência de dengue"# Filtrar dados completosdf_ccf <- df |>filter(!is.na(mean_temp) &!is.na(est_inc100k))# CCFccf_temp <-ccf(df_ccf$mean_temp, df_ccf$est_inc100k, lag.max =20, plot =FALSE)ccf_df <-data.frame(lag = ccf_temp$lag,ccf = ccf_temp$acf)ci_ccf <-qnorm(0.975) /sqrt(nrow(df_ccf))ggplot(ccf_df, aes(x = lag, y = ccf)) +geom_hline(yintercept =0) +geom_hline(yintercept =c(-ci_ccf, ci_ccf), linetype ="dashed", color ="blue") +geom_col(fill = cores["temperatura"], width =0.5) +geom_vline(xintercept =c(-8, -4), linetype ="dotted", color ="red") +labs(title ="Correlação Cruzada: Temperatura × Incidência",subtitle ="Lags negativos: temperatura PRECEDE incidência | Linhas vermelhas: lags ótimos",x ="Lag (semanas)",y ="Correlação" )```::: {.callout-note}## Ciclo Biológico do VetorA correlação máxima em **lags de 4-8 semanas** é consistente com o ciclo biológico do *Aedes aegypti*:1. **Temperatura elevada** → ambiente favorável2. **1-2 semanas**: Oviposição e desenvolvimento larval3. **2-4 semanas**: Emergência de adultos4. **4-8 semanas**: Transmissão e notificação de casos:::```{r}#| label: fig-ccf-precipitacao#| fig-cap: "Correlação cruzada: Precipitação × Incidência de dengue"# CCF precipitacaoccf_precip <-ccf(df_ccf$mean_precip, df_ccf$est_inc100k, lag.max =20, plot =FALSE)ccf_precip_df <-data.frame(lag = ccf_precip$lag,ccf = ccf_precip$acf)ggplot(ccf_precip_df, aes(x = lag, y = ccf)) +geom_hline(yintercept =0) +geom_hline(yintercept =c(-ci_ccf, ci_ccf), linetype ="dashed", color ="blue") +geom_col(fill = cores["precipitacao"], width =0.5) +labs(title ="Correlação Cruzada: Precipitação × Incidência",subtitle ="Lags negativos: precipitação PRECEDE incidência",x ="Lag (semanas)",y ="Correlação" )```---# Engenharia de Atributos (Feature Engineering)Esta seção demonstra os módulos de engenharia de atributos disponíveis em **`R/features/`** e explica a justificativa estatística para cada tipo de feature.## Visão Geral do Motor de FeaturesO módulo **`R/features/engine.R`** orquestra a criação de todas as features:```{r}#| label: feature-engine# Carregar configuracao de featuresconfig_features <-load_config("features")# Listar tipos de features habilitadascat("=== Tipos de Features Habilitadas ===\n\n")cat("Temporais:", config_features$temporal$enabled, "\n")cat("Sazonais:", config_features$seasonal$enabled, "\n")cat("Climáticas:", config_features$climate$enabled, "\n")```### Função `make_features()`Esta é a função principal que aplica todas as transformações:```{r}#| label: criar-features# Aplicar engenharia de featuresdf_features <-make_features(df, config_features)# Listar novas features criadasfeatures_criadas <-get_feature_names(df_features)cat("Total de features criadas:", length(features_criadas), "\n\n")cat("Novas colunas:\n")print(features_criadas)```## Módulo `R/features/temporal.R`### Features de LagOs **lags** capturam a dependência temporal da série:```{r}#| label: tbl-lags#| tbl-cap: "Features de lag e suas justificativas"data.frame(Funcao =rep("create_lag()", 3),Feature =c("lag_1 a lag_4", "lag_6, lag_8, lag_12", "lag_26, lag_52"),Tipo =c("Curto prazo", "Médio prazo", "Longo prazo"),Justificativa =c("Memória recente: inércia epidêmica, casos geram novos casos","Dinâmica intermediária: ciclo de transmissão completo","Sazonalidade: correlação com semestre e ano anterior" )) |>kable() |>kable_styling(bootstrap_options =c("striped", "hover"))``````{r}#| label: fig-lags#| fig-cap: "Comparação de diferentes lags com a série original"df_lags <- df_features |>select(data_iniSE, est_inc100k, lag_1, lag_4, lag_52) |>filter(!is.na(lag_52)) |>pivot_longer(cols =c(lag_1, lag_4, lag_52), names_to ="lag", values_to ="valor")ggplot() +geom_line(data = df_features |>filter(!is.na(lag_52)),aes(x = data_iniSE, y = est_inc100k),color = cores["observado"],linewidth =1.2,alpha =0.8 ) +geom_line(data = df_lags,aes(x = data_iniSE, y = valor, color = lag),linewidth =0.8,alpha =0.7 ) +scale_color_brewer(palette ="Set1",labels =c("Lag 1 sem", "Lag 4 sem", "Lag 52 sem") ) +labs(title ="Série Original vs. Lags Temporais",subtitle ="Linha preta = Original | Coloridas = Lags deslocados",x ="Data",y ="Incidência",color ="Lag" )```### Médias Móveis (Rolling Mean)As **médias móveis** suavizam a série e capturam tendências locais:$$\text{roll\_mean}_k(t) = \frac{1}{k} \sum_{i=1}^{k} Y_{t-i}$$```{r}#| label: fig-rolling-mean#| fig-cap: "Médias móveis de diferentes janelas"df_roll <- df_features |>select(data_iniSE, est_inc100k, roll_mean_4, roll_mean_8, roll_mean_12) |>filter(!is.na(roll_mean_12))ggplot(df_roll, aes(x = data_iniSE)) +geom_line(aes(y = est_inc100k),color = cores["observado"],linewidth =0.5, alpha =0.5 ) +geom_line(aes(y = roll_mean_4, color ="4 semanas"), linewidth =1) +geom_line(aes(y = roll_mean_8, color ="8 semanas"), linewidth =1) +geom_line(aes(y = roll_mean_12, color ="12 semanas"), linewidth =1) +scale_color_brewer(palette ="Set2") +labs(title ="Médias Móveis Suavizam a Série",subtitle ="Janelas maiores capturam tendências mais longas",x ="Data",y ="Incidência",color ="Janela" )```::: {.callout-important}## Controle de Vazamento TemporalA função `rolling_mean()` aplica **lag de 1** automaticamente para evitar vazamento de informação futura. Isso é essencial para previsão!```r# Implementação que evita vazamento:c(NA_real_, result[1:(n -1)]) # Desloca resultado 1 posição```:::### Diferenças e Taxa de Crescimento```{r}#| label: tbl-diff-growth#| tbl-cap: "Features de diferenças e crescimento"data.frame(Funcao =c("create_diff()", "create_growth_rate()"),Feature =c("diff_1, diff_4", "growth_4"),Formula =c("Y_t - Y_{t-k}","(Y_t - Y_{t-k}) / (Y_{t-k} + ε)" ),Justificativa =c("Taxa de variação absoluta: aceleração ou desaceleração","Crescimento relativo: importante quando níveis variam muito" )) |>kable() |>kable_styling(bootstrap_options =c("striped", "hover"))```## Módulo `R/features/seasonal.R`### Harmônicos de FourierOs **harmônicos de Fourier** representam a sazonalidade de forma contínua e suave:$$\sin_k(t) = \sin\left(\frac{2\pi k \cdot \text{semana}}{52}\right)$$$$\cos_k(t) = \cos\left(\frac{2\pi k \cdot \text{semana}}{52}\right)$$```{r}#| label: tbl-harmonicos#| tbl-cap: "Harmônicos de Fourier para sazonalidade"data.frame(Ordem =c(1, 1, 2, 2),Componente =c("sin_1", "cos_1", "sin_2", "cos_2"),Periodo =c("52 semanas", "52 semanas", "26 semanas", "26 semanas"),Captura =c("Fase da sazonalidade anual","Amplitude da sazonalidade anual","Fase da sazonalidade semestral","Amplitude da sazonalidade semestral" )) |>kable() |>kable_styling(bootstrap_options =c("striped", "hover"))``````{r}#| label: fig-harmonicos#| fig-cap: "Harmônicos de Fourier por semana epidemiológica"df_harm <- df_features |>select(semana, sin_1, cos_1, sin_2, cos_2) |>distinct() |>pivot_longer(cols =-semana, names_to ="harmonico", values_to ="valor")ggplot(df_harm, aes(x = semana, y = valor, color = harmonico)) +geom_line(linewidth =1.2) +scale_color_brewer(palette ="Set2",labels =c("cos(1)", "cos(2)", "sin(1)", "sin(2)") ) +labs(title ="Harmônicos de Fourier",subtitle ="Ordem 1 = Anual (52 sem) | Ordem 2 = Semestral (26 sem)",x ="Semana epidemiológica",y ="Valor",color ="Harmônico" )```::: {.callout-tip}## Vantagem dos HarmônicosComparado a dummies de semana (52 variáveis):- **Menos parâmetros**: 4 vs. 51- **Continuidade**: Transição suave entre semanas- **Regularização natural**: Restrição implícita na forma da curva:::### Estatísticas Sazonais```{r}#| label: fig-perfil-sazonal#| fig-cap: "Perfil sazonal da incidência de dengue"# Calcular media sazonalseasonal_stats <-compute_seasonal_mean(df, target ="est_inc100k")# Calcular quantis sazonaisseasonal_quantiles <-compute_seasonal_quantiles(df, target ="est_inc100k")# Juntar dadosseasonal_profile <-left_join(seasonal_stats, seasonal_quantiles, by ="semana")ggplot(seasonal_profile, aes(x = semana)) +geom_ribbon(aes(ymin = q25, ymax = q75), fill = cores["sazonalidade"], alpha =0.3) +geom_ribbon(aes(ymin = q50 - seasonal_sd, ymax = q50 + seasonal_sd),fill = cores["sazonalidade"], alpha =0.2 ) +geom_line(aes(y = seasonal_mean), color = cores["observado"], linewidth =1.2) +geom_line(aes(y = seasonal_median),color = cores["tendencia"],linewidth =1, linetype ="dashed" ) +labs(title ="Perfil Sazonal da Incidência de Dengue",subtitle ="Linha preta = Média | Linha vermelha = Mediana | Faixa = IQR",x ="Semana epidemiológica",y ="Incidência por 100 mil" ) +scale_x_continuous(breaks =seq(1, 52, by =4))```## Módulo `R/features/climate.R`### Lags ClimáticosBaseado na análise de CCF, criamos lags das variáveis climáticas:```{r}#| label: tbl-lags-clima#| tbl-cap: "Features climáticas com defasagem"# Buscar config de climaclima_config <- config_features$climatedata.frame(Variavel =c("Temperatura", "Temp. Máxima", "Temp. Mínima", "Precipitação"),Lags =paste(clima_config$lags, collapse =", "),Justificativa =c("Ciclo biológico do vetor: 2-8 semanas de atraso","Mesma justificativa + extremos de calor","Mesma justificativa + limites de desenvolvimento","Acúmulo de criadouros: efeito mais lento" )) |>kable() |>kable_styling(bootstrap_options =c("striped", "hover"))```### Agregações Climáticas```{r}#| label: tbl-rolling-clima#| tbl-cap: "Agregações climáticas (rolling)"data.frame(Feature =c("temp_roll_mean_4", "temp_roll_mean_8","precip_roll_sum_4", "precip_roll_sum_8", "precip_roll_sum_12" ),Tipo =c("Média móvel", "Média móvel","Soma acumulada", "Soma acumulada", "Soma acumulada" ),Justificativa =c("Condição térmica recente (1 mês)","Condição térmica média (2 meses)","Chuva acumulada recente","Chuva acumulada médio prazo","Chuva acumulada longo prazo (3 meses)" )) |>kable() |>kable_styling(bootstrap_options =c("striped", "hover"))```### Amplitude TérmicaA **amplitude térmica** (diferença entre máxima e mínima) é um indicador importante:```{r}#| label: fig-amplitude-termica#| fig-cap: "Amplitude térmica e sua relação com incidência"if ("temp_range"%in%names(df_features)) { df_temp_range <- df_features |>filter(!is.na(temp_range)) |>select(data_iniSE, temp_range, est_inc100k) p1 <-ggplot(df_temp_range, aes(x = data_iniSE)) +geom_line(aes(y = temp_range), color = cores["temperatura"]) +labs(title ="Amplitude Térmica", y ="°C", x =NULL) p2 <-ggplot(df_temp_range, aes(x = temp_range, y = est_inc100k)) +geom_point(alpha =0.3, color = cores["observado"]) +geom_smooth(method ="loess", color = cores["tendencia"]) +labs(title ="Relação com Incidência", x ="Amplitude (°C)", y ="Incidência") p1 + p2 +plot_annotation(title ="Feature: Amplitude Térmica (temp_max - temp_min)")} else {cat("Feature temp_range não disponível nos dados processados.")}```---# Análise de Correlações## Matriz de Correlação das Features```{r}#| label: fig-correlacao-matrix#| fig-cap: "Matriz de correlação das features criadas"#| fig-height: 10#| fig-width: 10# Selecionar features numericasfeature_names <-get_feature_names(df_features)feature_names <-c("est_inc100k", feature_names)df_corr <- df_features |>select(all_of(intersect(feature_names, names(df_features)))) |>select(where(is.numeric)) |>drop_na()# Calcular matriz de correlacaocor_matrix <-cor(df_corr, use ="pairwise.complete.obs")# Plotcorrplot( cor_matrix,method ="color",type ="lower",order ="hclust",tl.cex =0.6,tl.col ="black",addCoef.col ="gray30",number.cex =0.5,diag =FALSE,title ="Correlação entre Features",mar =c(0, 0, 2, 0))```## Correlação com o Alvo```{r}#| label: fig-correlacao-alvo#| fig-cap: "Top 15 features mais correlacionadas com a incidência"# Calcular correlacoes com o alvocor_with_target <- cor_matrix[, "est_inc100k"]cor_with_target <- cor_with_target[names(cor_with_target) !="est_inc100k"]# Top 15top_cors <-sort(abs(cor_with_target), decreasing =TRUE)[1:15]cor_df <-data.frame(feature =names(top_cors),correlacao = cor_with_target[names(top_cors)]) |>mutate(tipo =case_when(grepl("lag_|roll_|diff_|growth", feature) ~"Temporal",grepl("sin_|cos_", feature) ~"Sazonal",grepl("temp|precip", feature) ~"Climática",TRUE~"Outra" ) )ggplot(cor_df, aes(x =reorder(feature, abs(correlacao)), y = correlacao, fill = tipo)) +geom_col() +coord_flip() +scale_fill_brewer(palette ="Set2") +geom_hline(yintercept =0, linetype ="dashed") +labs(title ="Top 15 Features Mais Correlacionadas com Incidência",x =NULL,y ="Correlação de Pearson",fill ="Tipo" )```## Multicolinearidade```{r}#| label: tbl-multicolinearidade#| tbl-cap: "Pares de features com alta correlação (> 0.9)"# Encontrar pares com alta correlacaohigh_cor <-which(abs(cor_matrix) >0.9&abs(cor_matrix) <1, arr.ind =TRUE)if (nrow(high_cor) >0) { high_cor_pairs <-data.frame(Feature1 =rownames(cor_matrix)[high_cor[, 1]],Feature2 =colnames(cor_matrix)[high_cor[, 2]],Correlacao =round(cor_matrix[high_cor], 3) ) |>filter(Feature1 < Feature2) |># Remover duplicatasarrange(desc(abs(Correlacao))) |>head(10) high_cor_pairs |>kable() |>kable_styling(bootstrap_options =c("striped", "hover"))} else {cat("Nenhum par de features com correlação > 0.9")}```::: {.callout-warning}## Atenção: MulticolinearidadeFeatures altamente correlacionadas podem causar:- **Instabilidade** em coeficientes de modelos lineares- **Redundância** que aumenta dimensionalidade desnecessariamente- **Overfitting** em modelos de árvore**Recomendação**: Considerar seleção de features ou regularização (Lasso, Ridge).:::---# Conclusões e Próximos Passos## Principais Achados```{r}#| label: tbl-resumo-achados#| tbl-cap: "Resumo dos principais achados da análise exploratória"data.frame(Aspecto =c("Qualidade dos Dados","Sazonalidade","Estacionariedade","Autocorrelação","Clima","Features" ),Achado =c( dq_report$passed |>ifelse("Dados de boa qualidade", "Há problemas a tratar"),"Forte padrão anual com picos no verão (52 semanas)","Série não-estacionária; diferenciação sazonal necessária","Dependência de curto prazo (AR) e sazonalidade (lag 52)","Temperatura precede incidência em 4-8 semanas (CCF)",sprintf("%d features criadas cobrindo aspectos temporais, sazonais e climáticos",length(features_criadas) ) ),Implicacao =c("Pode-se prosseguir com modelagem","Modelos devem incluir componente sazonal (SARIMA, Prophet)","SARIMA com D=1 ou diferenciação antes de ML","Modelos AR são apropriados; considerar p=2","Incluir lags climáticos nos modelos de regressão","Seleção de features pode melhorar performance" )) |>kable() |>kable_styling(bootstrap_options =c("striped", "hover"))```## Recomendações para Modelagem::: {.callout-note}## Modelos Recomendados1. **SARIMA$(2,0,0) \times (0,1,0)_{52}$**: Modelo baseline estatístico2. **Prophet**: Para captura automática de tendência e sazonalidade3. **XGBoost/LightGBM**: Com features temporais, sazonais e climáticas4. **Ensemble**: Combinar modelos para robustez:::## Limitações- **Mudança de regime em 2024**: Surto sem precedentes pode afetar modelos treinados em dados históricos- **Covariáveis limitadas**: Apenas clima; fatores socioeconômicos e ações de controle não incluídos- **Horizonte de previsão**: Qualidade degrada significativamente após 4-6 semanas## Próximos Passos1. **Treinar modelos** com diferentes horizontes (h = 4, 6, 8 semanas)2. **Validação temporal** via rolling-origin (já implementada em `preprocess.R`)3. **Comparar métricas** (MAE, RMSE, MASE) entre modelos4. **Avaliar calibração** das previsões probabilísticas5. **Investigar mudança de regime** e possível adaptação de modelos---# Referências dos Módulos R```{r}#| label: tbl-modulos-resumo#| tbl-cap: "Resumo dos módulos R utilizados neste relatório"data.frame(Modulo =c("R/data/loader.R","R/data/preprocess.R","R/data/quality.R","R/features/temporal.R","R/features/seasonal.R","R/features/climate.R","R/features/engine.R" ),Funcoes =c("load_raw_data(), aggregate_state(), load_processed_data()","preprocess_data(), impute_climate_nas(), create_rolling_splits()","run_data_quality(), check_completeness(), check_duplicates()","add_temporal_features(), create_lag(), rolling_mean(), create_diff()","add_seasonal_features(), create_fourier_terms(), compute_seasonal_mean()","add_climate_features(), add_climate_anomalies(), create_extreme_indicator()","make_features(), clean_features(), create_model_matrix()" ),Proposito =c("Carregamento e agregação de dados","Preprocessamento e validação temporal","Controle de qualidade","Features baseadas em lags e agregações","Harmônicos de Fourier e estatísticas sazonais","Lags e transformações de variáveis climáticas","Orquestração e limpeza de features" )) |>kable() |>kable_styling(bootstrap_options =c("striped", "hover"))```---# Informações da Sessão```{r}#| label: session-infosessionInfo()```