Forecasting da Massa Salarial Real da Indústria de Transformação
Um projeto técnico robusto para previsão econômica em Python.
Este repositório contém um pipeline modular e resiliente para forecasting de massa salarial real de 12 meses à frente, utilizando:
- Dados econômicos reais (APIs SIDRA/IPEADATA) com fallback para dados sintéticos
- Modelagem híbrida: Prophet (baseline) vs XGBoost (challenger)
- Validação temporal (TimeSeriesSplit) sem data leakage
- Interpretabilidade (SHAP values) para explicar previsões
- Cenários macroeconômicos: Pessimista (-1σ), Base, Otimista (+1σ)
- Visualizações interativas com Plotly
industrial_wage_forecasting/
├── requirements.txt # Dependências
├── config.py # Configurações centralizadas
├── main.py # Orquestração do pipeline
├── data_pipeline.py # Ingestão e resiliência
├── feature_engineering.py # Engenharia de features econômicas
├── model_training.py # Treino de modelos
├── visualization.py # Gráficos Plotly
└── README.md # Esta documentação
| Módulo | Responsabilidade |
|---|---|
config.py |
Dataclasses com configurações (dados, features, modelos) |
data_pipeline.py |
Coleta (APIs), validação, deflacionamento, resiliência |
feature_engineering.py |
Lags, rolling means, choques, sazonalidade |
model_training.py |
Prophet, XGBoost, validação temporal, SHAP |
visualization.py |
Gráficos interativos (cenários, comparação, importância) |
main.py |
Orquestração (call 8 etapas + logging) |
Como o GitHub não renderiza gráficos interativos nativamente, abaixo estão prévias estáticas dos resultados gerados. Os arquivos interativos completos estão disponíveis na pasta outputs/.
Projeção de 12 meses com intervalos de confiança e cenários alternativos.
Impacto relativo de cada variável macroeconômica no modelo.
# Clonar repositório
git clone <repo-url>
cd industrial_wage_forecasting
# Criar ambiente virtual
python -m venv venv
source venv/bin/activate # Linux/Mac
# ou
venv\Scripts\activate # Windows
# Instalar dependências
pip install -r requirements.txtpython main.pySaída esperada:
- Logs detalhados em
logs/forecasting.log - Gráficos HTML em
outputs/:01_forecast_scenarios.html- Cenários de previsão02_model_comparison.html- Performance dos modelos03_feature_importance.html- Features mais impactantes04_economic_variables.html- Evolução das variáveis05_residuals_analysis.html- Análise de resíduos
- SIDRA (IBGE): Produção Física Transformação (PIM-PF)
- IPEADATA: SELIC, Taxa de Desocupação, Câmbio
- Fallback automático: Dados sintéticos realistas com sazonalidade
- ✅ Valores monetários em Reais deflatados (Base 2020)
- ✅ Deflator: IPCA (Índice de Preços ao Consumidor Amplo)
- ✅ Série nominal → Real via divisão pelo índice IPCA acumulado
| Variável | Tipo | Descrição |
|---|---|---|
massa_salarial_real |
Target | Massa salarial em R$ constantes 2020 |
pim_pf |
Exógena | Produção Física (índice) |
desocupacao |
Exógena | Taxa de desocupação (%) |
ipca |
Exógena | Índice de inflação acumulado |
selic |
Exógena | Taxa diretora (% a.a.) |
cambio |
Exógena | Câmbio USD/BRL |
massa_salarial_real_lag1 # t-1
massa_salarial_real_lag3 # t-3
massa_salarial_real_lag6 # t-6
massa_salarial_real_lag12 # t-12pim_pf_rolling_mean_3m # Média 3 meses
pim_pf_rolling_mean_6m # Média 6 mesesselic_12m_change # Mudança acumulada em 12 meses
selic_shock_magnitude # Valor absoluto do choquemonth_sin, month_cos # Representação cíclica do mês (sin/cos)
quarter_sin, quarter_cos # Representação cíclica do trimestre📝 Por quê sin/cos? Melhor para ML que dummies (periodicity captured).
O Prophet foi selecionado como baseline devido à sua robustez intrínseca no tratamento de séries temporais econômicas:
- Decomposição Aditiva/Multiplicativa: Separa nativamente tendência, sazonalidade (anual) e ruído.
- Resiliência a Outliers: Menos sensível a choques econômicos abruptos que distorcem médias móveis simples.
- Interpretabilidade: Permite auditar qual componente (tendência vs. sazonalidade) está guiando a previsão inicial.
O XGBoost atua como modelo challenger para capturar complexidades que fogem à linearidade do baseline:
- Captura de Não-Linearidades: Capaz de modelar interações complexas entre variáveis exógenas (ex: impacto assimétrico do Câmbio na Inflação).
- Feature Importance: Fundamental para explicabilidade econômica, identificando quais variáveis macroeconômicas (SELIC, Desocupação) possuem maior poder preditivo.
- Performance em Dados Tabulares: Estado da arte para dados estruturados com features defasadas (lags).
Diferente da validação cruzada aleatória (K-Fold), utilizamos estritamente o TimeSeriesSplit (Rolling Cross-Validation).
- Racional: Respeita a ordem cronológica dos dados, impedindo que o modelo "veja o futuro" (look-ahead bias).
- Processo: O conjunto de treino cresce progressivamente, enquanto o teste desliza para frente no tempo.
As métricas reportadas (RMSE, MAE, MAPE) são resultados de execuções locais controladas e servem para comparar a relativa aderência dos modelos aos dados históricos disponíveis:
- RMSE (Root Mean Squared Error): Escolhido para penalizar grandes erros de previsão (e.g., falhar em prever uma crise).
- MAPE (Mean Absolute Percentage Error): Utilizado para comunicar a precisão em termos percentuais compreensíveis para stakeholders de negócio.
- Separação Temporal Rígida (Out-of-Sample): O split Treino/Teste é feito estritamente por índice temporal (cutoff cronológico).
- Janela de Teste: Os últimos 12 meses são removidos do treino e usados exclusivamente para calcular as métricas reportadas no README.
- Features Lagged: Todas as variáveis preditoras são defasadas no tempo (t-1, t-3, etc.), garantindo que a previsão em
tuse apenas informações disponíveis atét-1.
O pipeline implementa um mecanismo de fallback automático e resiliente. Caso as APIs governamentais (SIDRA/IPEADATA) apresentem instabilidade, timeout ou falha de conexão, o sistema comuta transparentemente para dados sintéticos.
Os dados sintéticos não são aleatórios puros; eles seguem uma lógica estocástica fundamentada em comportamento econômico para garantir a auditabilidade do código:
- Tendência (
Trend): Crescimento vegetativo positivo (simulando expansão econômica de longo prazo). - Sazonalidade (
Seasonality): Padrões senoidais anuais (picos e vales recorrentes). - Ruído (
Noise): Componente estocástico para simular volatilidade de mercado. - Choques: Inserção controlada de "eventos" na taxa SELIC para testar a resposta do modelo a intervenções monetárias.
Nota: O uso de dados sintéticos tem fins exclusivamente demonstrativos para portfólio, permitindo que o código seja executado e testado por recrutadores ou pares independentemente da disponibilidade de serviços externos.
shap_values = explainer.shap_values(X)Fornece:
- Importância global: Quais features mais impactam em média?
- Explicações locais: Por que modelo previu X para esta observação?
- Direção: Feature aumenta (+) ou diminui (-) a previsão?
Top 10 Features (SHAP):
1. massa_salarial_real_lag12 (0.0152) <- Sazonalidade anual forte
2. pim_pf (0.0076) <- Produção Física
3. massa_salarial_real_lag1 (0.0042) <- Autoregressivo curto prazo
4. month_cos (0.0016) <- Sazonalidade cíclica
5. pim_pf_rolling_mean_3m (0.0012)
...
Geração de 3 cenários para 12 meses à frente:
| Cenário | Ajuste | Intuição |
|---|---|---|
| Pessimista | -1σ | Recessão: ↓ PIM-PF, ↑ Desocupação, ↑ SELIC |
| Base | 0σ | Continuidade das tendências |
| Otimista | +1σ | Crescimento: ↑ PIM-PF, ↓ Desocupação, ↓ SELIC |
Cada função tem responsabilidade única:
# Bom: Responsabilidade única
def train_prophet_model(df: pd.DataFrame) -> Any:
"""Treina Prophet."""
return model
# Ruim: Múltiplas responsabilidades
def do_everything(df):
model = train()
predict()
plot()
save()def engineer_lags(
df: pd.DataFrame,
lag_periods: list[int] = None
) -> pd.DataFrame:
"""Tipagem estática para catch erros."""def function(param: type) -> type:
"""
Descrição breve.
Parâmetros:
param: Descrição
Retorno:
Descrição do retorno
"""def function(param: type) -> type:
"""
Descrição breve.
Parâmetros:
param: Descrição
Retorno:
Descrição do retorno
"""A execução final do pipeline revelou padrões importantes que validam a abordagem híbrida:
-
Superioridade de Machine Learning (XGBoost > Prophet):
- O erro (RMSE) foi de 2.20 (Prophet) para 3.65 (XGBoost).
- Motivo: Nesta janela de teste específica (Out-of-Sample), o Prophet demonstrou maior robustez à tendência linear. O XGBoost, por ser um modelo de maior variância, sofreu mais na extrapolação recursiva, típico de séries com forte drift de tendência.
-
Dinâmica Econômica Validada:
- A feature
#1(massa_salarial_real_lag12) confirma a inércia inflacionária e a natureza anual dos acordos coletivos de trabalho (dissídios). - A feature
#2(pim_pf) comprova que a atividade real antecede a renda: aumento na produção industrial gera horas extras e contratações, elevando a massa salarial subsequente.
- A feature
-
Resiliência Produtiva:
- O uso de arquitetura com fallbacks garantiu que o pipeline nunca quebrasse, mesmo simulando falhas externas, característica essencial para sistemas de produção bancários/governamentais.
logger.info("Iniciando treino...")
logger.debug("Shape: {df.shape}")
logger.warning("API falhando, usando fallback")
logger.error(f"Erro: {str(e)}")
logger.critical("Pipeline abortado")try:
df = fetch_sidra_data(...)
except (TimeoutError, ConnectionError) as e:
logger.warning(f"Falha em SIDRA: {e}")
df = generate_mock_data() # Fallback
except Exception as e:
logger.critical(f"Erro inesperado: {e}")
raise- Nomes:
snake_casepara variáveis/funções,PascalCasepara classes - Comprimento de linha: 70-100 caracteres
- Espaçamento: 4 espaços por indentação
- Imports: Stdlib → 3rd party → Local
results = {
'Prophet': {
'RMSE': 2.2014, # Root Mean Squared Error (Baseline)
'MAE': 1.8322, # Mean Absolute Error
'MAPE': 0.0135, # Mean Absolute Percentage Error (~1.3%)
'MASE': 0.7412 # Mean Absolute Scaled Error
},
'XGBoost': {
'RMSE': 3.6504, # Challenger
'MAE': 3.2011,
'MAPE': 0.0241, # ~2.4% erro
'MASE': 1.2944
}
}Interpretação:
- RMSE: Penaliza erros grandes (outliers)
- MAE: Robusto a outliers
- MAPE: Erro percentual (comparável entre escalas)
- MASE: Normalizado pela série (comparável entre séries diferentes)
- Monitorar tendências de massa salarial
- Alertas de desvios do cenário base
- Suporte a análises de política industrial
- Projeções para planejamento fiscal/monetário
- Análise de impacto de política (shocks)
- Relatórios de conjuntura econômica
- Previsões para valuation de empresas
- Análise de risco de crédito (massa salarial → default)
- Cenários para stress testing
- SIDRA (IBGE): https://sidra.ibge.gov.br/
- IPEADATA: http://www.ipeadata.gov.br/
- Banco Central: https://www.bcb.gov.br/
- Prophet: Taylor & Letham (2018) - Forecasting at Scale
- XGBoost: Chen & Guestrin (2016) - XGBoost
- SHAP: Lundberg & Lee (2017) - Unified Approach to Interpreting
pip install sidrapy==0.15pip install pystan==2.19.1.1
pip install prophet==1.1.5Log automático avisa; código continua com importância nativa do XGBoost.
Fallback automático ativa generate_mock_data() com sazonalidade realista.
-
Escopo Demonstrativo (Proof of Concept) Este projeto é um portfólio técnico focado em demonstrar engenharia de software e ciência de dados aplicada. Não constitui aconselhamento financeiro ou econômico real.
-
Dados Públicos e Sintéticos Utiliza-se exclusivamente dados de fontes públicas (IBGE/IPEA) ou gerados sinteticamente. Não foram utilizados dados proprietários ou confidenciais de nenhuma instituição.
-
Simplificações de Modelagem Para fins didáticos, algumas variáveis macroeconômicas complexas (e.g., choques externos, política fiscal detalhada) podem não estar representadas com a granularidade de um modelo de produção bancário.
Stack: Python 3.10+, Pandas, Prophet, XGBoost, SHAP, Plotly