HugoNeres commited on
Commit
4e66049
·
verified ·
1 Parent(s): 8f3ba17

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +98 -10
app.py CHANGED
@@ -8,6 +8,9 @@ import numpy as np
8
  import plotly.express as px
9
  import io
10
  from sklearn.metrics import confusion_matrix, roc_curve, auc
 
 
 
11
 
12
  # --- CONFIGURAÇÃO ---
13
  st.set_page_config(page_title="CrediFast Risk System", layout="wide")
@@ -422,20 +425,105 @@ with tab2:
422
  st.info("👈 Preencha os dados ao lado e clique em 'Calcular Risco' para ver o resultado.")
423
 
424
  # =========================================================
425
- # ABA IV: CLUSTERIZAÇÃO (Mantida)
426
  # =========================================================
427
  with tab3:
428
- st.header("IV. Segmentação de Clientes")
429
- if 'Cluster' in df.columns:
430
- st.markdown("**Perfis Identificados (K-Means):**")
431
- st.dataframe(df.groupby('Cluster')[['person_age', 'person_income', 'loan_amnt', 'loan_status']].mean().style.format({'person_income': 'R$ {:,.2f}', 'loan_status': '{:.1%}'}), use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
432
 
433
- fig_clus = px.scatter(df, x='person_income', y='loan_amnt', color='Cluster',
434
- title="Clusterização: Renda vs Empréstimo", range_x=[0, 200000])
435
- st.plotly_chart(fig_clus, use_container_width=True)
436
- else:
437
- st.warning("Clusterização não disponível.")
438
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
439
  # =========================================================
440
  # ABA V: RECOMENDAÇÕES (Mantida)
441
  # =========================================================
 
8
  import plotly.express as px
9
  import io
10
  from sklearn.metrics import confusion_matrix, roc_curve, auc
11
+ from sklearn.decomposition import PCA
12
+ from sklearn.preprocessing import StandardScaler
13
+ from sklearn.cluster import KMeans
14
 
15
  # --- CONFIGURAÇÃO ---
16
  st.set_page_config(page_title="CrediFast Risk System", layout="wide")
 
425
  st.info("👈 Preencha os dados ao lado e clique em 'Calcular Risco' para ver o resultado.")
426
 
427
  # =========================================================
428
+ # ABA III: CLUSTERIZAÇÃO COM PCA (Visualização Avançada)
429
  # =========================================================
430
  with tab3:
431
+ st.header("IV. Segmentação de Clientes (Clusterização)")
432
+
433
+ st.markdown("""
434
+ Abaixo, utilizamos **K-Means** para agrupar clientes semelhantes e **PCA (Análise de Componentes Principais)** para reduzir todas as dimensões (Renda, Idade, Juros, etc.) em um mapa 2D.
435
+ """)
436
+
437
+ # 1. Definição das Colunas Numéricas para Clusterização
438
+ # (Removendo colunas categóricas e alvo)
439
+ cols_cluster = ['person_age', 'person_income', 'person_emp_length',
440
+ 'loan_amnt', 'loan_int_rate', 'loan_percent_income',
441
+ 'cb_person_cred_hist_length']
442
+
443
+ # 2. Verifica/Gera Clusters (Caso o CSV não tenha a coluna 'Cluster')
444
+ if 'Cluster' not in df.columns:
445
+ with st.spinner("Identificando grupos de clientes (Clusterização)..."):
446
+ # Prepara dados (Inputa médidas se houver nulos para não quebrar)
447
+ X_clus = df[cols_cluster].fillna(df[cols_cluster].mean())
448
+
449
+ # Escala específica para o Cluster (importante ser fresco)
450
+ scaler_clus = StandardScaler()
451
+ X_clus_scaled = scaler_clus.fit_transform(X_clus)
452
+
453
+ # Aplica K-Means (Ex: 4 grupos)
454
+ kmeans = KMeans(n_clusters=4, random_state=42, n_init=10)
455
+ df['Cluster'] = kmeans.fit_predict(X_clus_scaled)
456
+
457
+ # Garante que Cluster seja tratado como texto (Categoria) para cores discretas
458
+ df['Cluster'] = df['Cluster'].astype(str)
459
+
460
+ # 3. Aplicação do PCA para Visualização
461
+ try:
462
+ # Prepara dados para PCA
463
+ X_pca_input = df[cols_cluster].fillna(df[cols_cluster].mean())
464
+ scaler_pca = StandardScaler()
465
+ X_scaled = scaler_pca.fit_transform(X_pca_input)
466
+
467
+ # Calcula PCA (Reduz para 2 componentes)
468
+ pca = PCA(n_components=2)
469
+ components = pca.fit_transform(X_scaled)
470
+
471
+ # Cria DataFrame temporário para o gráfico
472
+ df_pca = pd.DataFrame(data=components, columns=['PC1', 'PC2'])
473
+ df_pca['Cluster'] = df['Cluster'].values
474
 
475
+ # Adiciona dados originais para o Tooltip (Hover)
476
+ df_pca['Renda'] = df['person_income'].values
477
+ df_pca['Empréstimo'] = df['loan_amnt'].values
478
+ df_pca['Risco'] = df['loan_status'].apply(lambda x: 'Calote' if x==1 else 'Bom Pagador').values
 
479
 
480
+ # 4. Gráfico Interativo
481
+ col_graph, col_stats = st.columns([2, 1])
482
+
483
+ with col_graph:
484
+ var_explicada = pca.explained_variance_ratio_.sum()
485
+ st.caption(f"Visualização PCA (Explica {var_explicada:.1%} da variação dos dados)")
486
+
487
+ fig_pca = px.scatter(
488
+ df_pca,
489
+ x='PC1',
490
+ y='PC2',
491
+ color='Cluster',
492
+ symbol='Risco', # Diferencia caloteiros por formato (opcional)
493
+ hover_data=['Renda', 'Empréstimo', 'Risco'],
494
+ title="Mapa de Clusters (PCA)",
495
+ color_discrete_sequence=px.colors.qualitative.Bold,
496
+ height=500
497
+ )
498
+ fig_pca.update_traces(marker=dict(size=8, opacity=0.7), selector=dict(mode='markers'))
499
+ st.plotly_chart(fig_pca, use_container_width=True)
500
+
501
+ # 5. Estatísticas dos Perfis
502
+ with col_stats:
503
+ st.subheader("Perfil dos Grupos")
504
+ # Agrupa e calcula médias
505
+ resumo = df.groupby('Cluster')[['person_income', 'loan_amnt', 'person_age', 'loan_status']].mean()
506
+
507
+ # Formatação bonita
508
+ st.dataframe(
509
+ resumo.style.format({
510
+ 'person_income': 'R$ {:,.0f}',
511
+ 'loan_amnt': 'R$ {:,.0f}',
512
+ 'person_age': '{:.0f} anos',
513
+ 'loan_status': '{:.1%}'
514
+ }).background_gradient(cmap='Blues', subset=['loan_status']),
515
+ use_container_width=True
516
+ )
517
+
518
+ # Interpretação Rápida (Exemplo genérico, ajuste conforme seus dados reais)
519
+ st.info("""
520
+ **Dica de Análise:**
521
+ * Observe se existe um cluster com **alta inadimplência** (Vermelho escuro na tabela).
522
+ * Veja se o PCA conseguiu separar bem os grupos (espaço entre as cores).
523
+ """)
524
+
525
+ except Exception as e:
526
+ st.error(f"Erro ao gerar PCA: {e}")
527
  # =========================================================
528
  # ABA V: RECOMENDAÇÕES (Mantida)
529
  # =========================================================