receita_GDF / app.py
ablon1's picture
Create app.py
27df87d verified
# app.py
import gradio as gr
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
# Dados históricos
anos = np.arange(2015, 2025)
valoresRCL = np.array([
18461481002, 19881229932, 20719829099, 21742563018, 22503460737,
25058903184, 28277263875, 29460072799, 33214094007, 36114673966
]) / 1e9
valoresRT = np.array([
25877008148, 26260519658, 21656374939, 22808686104, 23142025074,
24871412313, 28451064067, 30984998453, 33361387405, 35629361262
]) / 1e9
IGPM = np.array([10.54, 7.17, -0.52, 7.54, 7.30, 23.14, 17.78, 5.45, -3.18, 6.54]) / 100
PIB = np.array([-3.5, -3.3, 1.3, 1.8, 1.2, -3.3, 4.8, 3.0, 3.2, 3.4]) / 100
# Função principal
def simular(n_simulacoes, n_anos_futuros, taxa_isencao):
taxa_isencao = taxa_isencao / 100 # converter para proporção
# Modelo de regressão
delta_RCL = np.diff(valoresRCL)
delta_RT = np.diff(valoresRT)
X = np.column_stack((IGPM[1:], PIB[1:]))
modelo_RCL = LinearRegression().fit(X, delta_RCL)
modelo_RT = LinearRegression().fit(X, delta_RT)
# Simulação normal
mu_igpm, sigma_igpm = np.mean(IGPM), np.std(IGPM)
mu_pib, sigma_pib = np.mean(PIB), np.std(PIB)
anos_futuros = np.arange(2024, 2024 + n_anos_futuros + 1)
igpm_futuro = np.random.normal(mu_igpm, sigma_igpm, (n_simulacoes, n_anos_futuros))
pib_futuro = np.random.normal(mu_pib, sigma_pib, (n_simulacoes, n_anos_futuros))
simulacoes_RCL = np.zeros((n_simulacoes, n_anos_futuros + 1))
simulacoes_RT = np.zeros((n_simulacoes, n_anos_futuros + 1))
simulacoes_RCL[:, 0] = valoresRCL[-1]
simulacoes_RT[:, 0] = valoresRT[-1]
for t in range(1, n_anos_futuros + 1):
X_t = np.column_stack((igpm_futuro[:, t - 1], pib_futuro[:, t - 1]))
inc_RCL = modelo_RCL.predict(X_t)
inc_RT = modelo_RT.predict(X_t)
simulacoes_RCL[:, t] = (simulacoes_RCL[:, t - 1] + inc_RCL) * (1 - taxa_isencao)
simulacoes_RT[:, t] = (simulacoes_RT[:, t - 1] + inc_RT) * (1 - taxa_isencao)
# Estatísticas
media_RCL = np.mean(simulacoes_RCL, axis=0)
p10_RCL = np.percentile(simulacoes_RCL, 10, axis=0)
p90_RCL = np.percentile(simulacoes_RCL, 90, axis=0)
media_RT = np.mean(simulacoes_RT, axis=0)
p10_RT = np.percentile(simulacoes_RT, 10, axis=0)
p90_RT = np.percentile(simulacoes_RT, 90, axis=0)
# Probabilidade de queda
def prob_queda(sim):
probs = []
for t in range(1, n_anos_futuros + 1):
queda = sim[:, t] < sim[:, t - 1]
prob = np.mean(queda) * 100
probs.append(f"{anos_futuros[t]}: {prob:.2f}%")
return "\n".join(probs)
# Gráficos
def plot_grafico(y_hist, media, p10, p90, titulo):
fig, ax = plt.subplots(figsize=(8, 4))
ax.plot(anos, y_hist, label="Histórico", marker='o')
ax.plot(anos_futuros, media, label="Média Simulada")
ax.fill_between(anos_futuros, p10, p90, alpha=0.3, label="Faixa 10–90%")
ax.set_title(titulo)
ax.set_xlabel("Ano")
ax.set_ylabel("R$ bi")
ax.grid(True)
ax.legend()
return fig
fig_rcl = plot_grafico(valoresRCL, media_RCL, p10_RCL, p90_RCL, "Receita Corrente Líquida (RCL)")
fig_rt = plot_grafico(valoresRT, media_RT, p10_RT, p90_RT, "Receita Total (RT)")
# Tabela histórica
var_RT = [np.nan] + list(100 * np.diff(valoresRT) / valoresRT[:-1])
var_RCL = [np.nan] + list(100 * np.diff(valoresRCL) / valoresRCL[:-1])
df = pd.DataFrame({
"Ano": anos,
"RCL (bi R$)": np.round(valoresRCL, 2),
"Δ% RCL": np.round(var_RCL, 2),
"RT (bi R$)": np.round(valoresRT, 2),
"Δ% RT": np.round(var_RT, 2),
"IGPM (%)": np.round(IGPM * 100, 2),
"PIB (%)": np.round(PIB * 100, 2)
})
return (
fig_rcl,
fig_rt,
df,
prob_queda(simulacoes_RCL),
prob_queda(simulacoes_RT)
)
# Interface Gradio
demo = gr.Interface(
fn=simular,
inputs=[
gr.Slider(100, 5000, value=1000, step=100, label="Número de Simulações"),
gr.Slider(1, 10, value=5, step=1, label="Anos de Projeção"),
gr.Slider(0, 20, value=5, step=1, label="Taxa de Isenção Fiscal (%)")
],
outputs=[
gr.Plot(label="Projeção RCL"),
gr.Plot(label="Projeção RT"),
gr.Dataframe(label="Tabela de Dados Históricos"),
gr.Textbox(label="Prob. Queda RCL"),
gr.Textbox(label="Prob. Queda RT")
],
title="📊 Simulação Receita Pública - Monte Carlo",
description="Monte Carlo com distribuição normal baseada em IGPM e PIB históricos (2015–2024)."
)
if __name__ == "__main__":
demo.launch()