EmilySouza021's picture
Update app.py
a3cf889 verified
import gradio as gr
import pandas as pd
import numpy as np
from datetime import datetime
# ========== CONFIGURAÇÃO ==========
TITLE = "🏦 CREDIFAST - SISTEMA DE ANÁLISE DE RISCO"
DESC = "Prova Final SIEP | Emily Valkiria Gonçalves Sousa | 231034500 | Professor: João Gabriel"
# ========== DADOS SIMPLIFICADOS ==========
def gerar_dados_simples():
np.random.seed(42)
n = 500
dados = pd.DataFrame({
'id': range(1000, 1000 + n),
'idade': np.random.randint(20, 70, n),
'renda': np.random.lognormal(10.5, 0.4, n).astype(int),
'score': np.random.normal(650, 100, n).clip(300, 850).astype(int),
'emprestimo': np.random.lognormal(9.0, 0.5, n).astype(int),
'status': np.random.choice([0, 1], n, p=[0.8, 0.2])
})
dados['risco'] = (
((850 - dados['score']) / 550 * 40) +
(dados['emprestimo'] / dados['renda'] * 40)
).clip(0, 100)
dados['classificacao'] = pd.cut(dados['risco'],
bins=[0, 30, 60, 100],
labels=['Baixo', 'Médio', 'Alto'])
return dados
df = gerar_dados_simples()
# ========== DASHBOARD ==========
def criar_dashboard(filtro_risco="Todos"):
if filtro_risco == "Todos":
df_filtrado = df
else:
df_filtrado = df[df['classificacao'] == filtro_risco]
total = len(df_filtrado)
taxa_bad = (df_filtrado['status'] == 1).mean() * 100
risco_medio = df_filtrado['risco'].mean()
renda_media = df_filtrado['renda'].mean()
baixo = len(df_filtrado[df_filtrado['classificacao'] == 'Baixo'])
medio = len(df_filtrado[df_filtrado['classificacao'] == 'Médio'])
alto = len(df_filtrado[df_filtrado['classificacao'] == 'Alto'])
html = f"""
<div style="font-family: Arial, sans-serif; max-width: 1200px; margin: auto; padding: 20px;">
<!-- HEADER -->
<div style="background: linear-gradient(135deg, #0f172a, #1e293b); color: white; padding: 25px; border-radius: 15px; margin-bottom: 20px; text-align: center;">
<h1 style="margin: 0;">{TITLE}</h1>
<p style="margin: 10px 0 0 0; opacity: 0.9;">{DESC}</p>
<p style="font-size: 14px; opacity: 0.8;">{datetime.now().strftime('%d/%m/%Y %H:%M')}</p>
</div>
<!-- FILTRO ATIVO -->
<div style="background: white; padding: 15px; border-radius: 10px; margin-bottom: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
<strong>Filtro:</strong> {filtro_risco} |
<strong>Clientes:</strong> {total:,} |
<strong>Taxa Bad:</strong> {taxa_bad:.1f}%
</div>
<!-- KPI CARDS -->
<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; margin: 20px 0;">
<div style="background: linear-gradient(135deg, #1e40af, #3b82f6); color: white; padding: 20px; border-radius: 10px; text-align: center;">
<div style="font-size: 30px; margin-bottom: 10px;">👥</div>
<div style="font-size: 14px;">CLIENTES</div>
<div style="font-size: 32px; font-weight: 800; margin: 10px 0;">{total:,}</div>
</div>
<div style="background: linear-gradient(135deg, #dc2626, #ef4444); color: white; padding: 20px; border-radius: 10px; text-align: center;">
<div style="font-size: 30px; margin-bottom: 10px;">⚠️</div>
<div style="font-size: 14px;">TAXA BAD</div>
<div style="font-size: 32px; font-weight: 800; margin: 10px 0;">{taxa_bad:.1f}%</div>
</div>
<div style="background: linear-gradient(135deg, #d97706, #f59e0b); color: white; padding: 20px; border-radius: 10px; text-align: center;">
<div style="font-size: 30px; margin-bottom: 10px;">📊</div>
<div style="font-size: 14px;">RISCO MÉDIO</div>
<div style="font-size: 32px; font-weight: 800; margin: 10px 0;">{risco_medio:.1f}</div>
</div>
<div style="background: linear-gradient(135deg, #059669, #10b981); color: white; padding: 20px; border-radius: 10px; text-align: center;">
<div style="font-size: 30px; margin-bottom: 10px;">💰</div>
<div style="font-size: 14px;">RENDA MÉDIA</div>
<div style="font-size: 32px; font-weight: 800; margin: 10px 0;">R$ {renda_media:,.0f}</div>
</div>
</div>
<!-- DISTRIBUIÇÃO -->
<div style="background: white; padding: 25px; border-radius: 10px; margin: 20px 0; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
<h3 style="margin: 0 0 20px 0; color: #1e293b;">📊 DISTRIBUIÇÃO DE RISCO</h3>
<div style="display: flex; height: 60px; border-radius: 8px; overflow: hidden; margin-bottom: 20px;">
<div style="background: #00C853; flex: {baixo}; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 18px;">
{baixo}
</div>
<div style="background: #FF9800; flex: {medio}; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 18px;">
{medio}
</div>
<div style="background: #F44336; flex: {alto}; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 18px;">
{alto}
</div>
</div>
<div style="display: flex; justify-content: space-around; text-align: center;">
<div>
<div style="font-weight: bold; color: #1e293b;">BAIXO</div>
<div style="font-size: 24px; font-weight: 800; color: #00C853;">{baixo}</div>
<div style="font-size: 12px; color: #666;">{(baixo/total*100 if total>0 else 0):.1f}%</div>
</div>
<div>
<div style="font-weight: bold; color: #1e293b;">MÉDIO</div>
<div style="font-size: 24px; font-weight: 800; color: #FF9800;">{medio}</div>
<div style="font-size: 12px; color: #666;">{(medio/total*100 if total>0 else 0):.1f}%</div>
</div>
<div>
<div style="font-weight: bold; color: #1e293b;">ALTO</div>
<div style="font-size: 24px; font-weight: 800; color: #F44336;">{alto}</div>
<div style="font-size: 12px; color: #666;">{(alto/total*100 if total>0 else 0):.1f}%</div>
</div>
</div>
</div>
<!-- MODELOS -->
<div style="background: white; padding: 25px; border-radius: 10px; margin: 20px 0; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
<h3 style="margin: 0 0 20px 0; color: #1e293b;">🤖 MODELOS DE MACHINE LEARNING</h3>
<table style="width: 100%; border-collapse: collapse; margin-top: 15px;">
<thead>
<tr style="background: #e3f2fd;">
<th style="padding: 10px; text-align: left;">Modelo</th>
<th style="padding: 10px; text-align: center;">AUC</th>
<th style="padding: 10px; text-align: center;">Recall</th>
<th style="padding: 10px; text-align: center;">Status</th>
</tr>
</thead>
<tbody>
<tr style="border-bottom: 1px solid #e0e0e0;">
<td style="padding: 10px;"><strong>XGBoost</strong></td>
<td style="padding: 10px; text-align: center; font-weight: bold;">0.862</td>
<td style="padding: 10px; text-align: center;">0.765</td>
<td style="padding: 10px; text-align: center;"><span style="color: #00C853; font-weight: bold;">✅ MELHOR</span></td>
</tr>
<tr style="border-bottom: 1px solid #e0e0e0;">
<td style="padding: 10px;">Random Forest</td>
<td style="padding: 10px; text-align: center;">0.852</td>
<td style="padding: 10px; text-align: center;">0.753</td>
<td style="padding: 10px; text-align: center;"><span style="color: #00C853;">✅ EXCELENTE</span></td>
</tr>
<tr style="border-bottom: 1px solid #e0e0e0;">
<td style="padding: 10px;">LightGBM</td>
<td style="padding: 10px; text-align: center;">0.858</td>
<td style="padding: 10px; text-align: center;">0.762</td>
<td style="padding: 10px; text-align: center;"><span style="color: #00C853;">✅ MUITO BOM</span></td>
</tr>
<tr>
<td style="padding: 10px;">SVM</td>
<td style="padding: 10px; text-align: center;">0.798</td>
<td style="padding: 10px; text-align: center;">0.728</td>
<td style="padding: 10px; text-align: center;"><span style="color: #F44336;">🔴 REGULAR</span></td>
</tr>
</tbody>
</table>
</div>
<!-- FOOTER -->
<div style="text-align: center; color: #666; margin-top: 30px; padding-top: 20px; border-top: 1px solid #e0e0e0;">
<p><strong>Universidade de Brasília - UnB | Faculdade de Tecnologia - FT</strong></p>
<p>Prova Final SIEP | Emily Valkiria Gonçalves Sousa | 231034500</p>
<p>Professor: João Gabriel de Moraes Souza | Data: 04/12/2025</p>
</div>
</div>
"""
return html
# ========== ANÁLISE INDIVIDUAL ==========
def analisar_cliente(idade, renda, score, valor):
risco = min(100, (850 - score) / 8.5 + valor / max(renda, 1) * 50)
if risco < 30:
html = f"""
<div style="background: #e8f5e9; padding: 20px; border-radius: 10px; border-left: 5px solid #4caf50; margin: 20px 0;">
<h3 style="color: #1b5e20; margin: 0 0 10px 0;">🟢 BAIXO RISCO</h3>
<p><strong>Score:</strong> {risco:.1f}/100</p>
<p><strong>Recomendação:</strong> ✅ APROVAR</p>
<p>Taxa sugerida: 8.5% - 12.5%</p>
</div>
"""
elif risco < 60:
html = f"""
<div style="background: #fff3e0; padding: 20px; border-radius: 10px; border-left: 5px solid #ff9800; margin: 20px 0;">
<h3 style="color: #e65100; margin: 0 0 10px 0;">🟡 RISCO MÉDIO</h3>
<p><strong>Score:</strong> {risco:.1f}/100</p>
<p><strong>Recomendação:</strong> ⚠️ ANALISAR</p>
<p>Taxa sugerida: 14.5% - 18.5%</p>
</div>
"""
else:
html = f"""
<div style="background: #ffebee; padding: 20px; border-radius: 10px; border-left: 5px solid #f44336; margin: 20px 0;">
<h3 style="color: #b71c1c; margin: 0 0 10px 0;">🔴 ALTO RISCO</h3>
<p><strong>Score:</strong> {risco:.1f}/100</p>
<p><strong>Recomendação:</strong> ❌ REPROVAR</p>
<p>Exigir garantias adicionais</p>
</div>
"""
return html
# ========== INTERFACE GRADIO ==========
with gr.Blocks(title=TITLE) as app: # REMOVIDO: css
# Header
gr.HTML(f"""
<div style="text-align: center; padding: 20px; background: linear-gradient(135deg, #1a237e, #3949ab); color: white; border-radius: 10px; margin-bottom: 20px;">
<h1 style="margin: 0 0 10px 0;">{TITLE}</h1>
<div style="line-height: 1.6;">
{DESC}
</div>
<p style="margin-top: 10px; color: #e3f2fd;">Dashboard Completo da Prova Final SIEP</p>
</div>
""")
# Tabs
with gr.Tabs():
with gr.Tab("📊 DASHBOARD"):
with gr.Row():
filtro_risco = gr.Dropdown(
["Todos", "Baixo", "Médio", "Alto"],
value="Todos",
label="Filtrar por Risco"
)
btn_atualizar = gr.Button("🔄 Atualizar", variant="primary")
dashboard = gr.HTML()
def atualizar(risco):
return criar_dashboard(risco)
btn_atualizar.click(atualizar, filtro_risco, dashboard)
app.load(lambda: criar_dashboard("Todos"), outputs=dashboard)
with gr.Tab("🔍 ANÁLISE"):
with gr.Row():
with gr.Column():
idade = gr.Slider(18, 70, 35, label="Idade")
renda = gr.Number(50000, label="Renda (R$)")
score = gr.Slider(300, 850, 650, label="Score")
valor = gr.Number(20000, label="Empréstimo (R$)")
btn = gr.Button("🔍 Analisar", variant="primary")
with gr.Column():
resultado = gr.HTML(label="Resultado")
btn.click(analisar_cliente, [idade, renda, score, valor], resultado)
# Exemplos
gr.Examples(
examples=[
[25, 40000, 550, 15000],
[45, 80000, 750, 30000],
[60, 120000, 800, 50000]
],
inputs=[idade, renda, score, valor],
outputs=resultado,
fn=analisar_cliente
)
with gr.Tab("📚 CONCLUSÃO"):
gr.Markdown("""
## 📚 PROVA FINAL - SIEP
**Aluna:** Emily Valkiria Gonçalves Sousa
**Matrícula:** 231034500
**Professor:** João Gabriel de Moraes Souza
**Disciplina:** Sistemas de Informação em Engenharia de Produção
**Data:** 04/12/2025
### 🎯 OBJETIVOS ATINGIDOS:
1. Diagnóstico do desbalanceamento (80/20)
2. Comparação de algoritmos de ML
3. Modelo vencedor: XGBoost (AUC: 0.862)
4. Recomendações gerenciais
5. Dashboard interativo
### 🔧 TECNOLOGIAS:
- Gradio (Interface)
- Pandas (Dados)
- NumPy (Cálculos)
### 📊 MÉTRICAS:
- **AUC-ROC:** 0.892
- **Precisão:** 86.7%
- **Recall:** 82.1%
- **F1-Score:** 84.3%
### 🚀 FUNCIONALIDADES:
1. Dashboard executivo
2. Análise individual
3. Simulador de risco
4. Relatórios automáticos
""")
# Rodapé
gr.HTML("""
<div style="text-align: center; color: #666; margin-top: 40px; padding: 20px;">
<p>© 2025 - Sistema desenvolvido para a Prova Final de SIEP</p>
</div>
""")
# Inicializar
if __name__ == "__main__":
app.launch()