FernandezUNB commited on
Commit
445c876
·
verified ·
1 Parent(s): 4e28d04

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +140 -70
app.py CHANGED
@@ -21,6 +21,8 @@ def generate_king_county_data(n_samples=2000):
21
  """Gera dados realísticos simulando o dataset King County"""
22
  np.random.seed(42)
23
 
 
 
24
  # Gerar características básicas
25
  sqft_living = np.random.normal(2080, 920, n_samples)
26
  sqft_living = np.clip(sqft_living, 370, 13540)
@@ -76,7 +78,10 @@ def generate_king_county_data(n_samples=2000):
76
  'sqft_basement': sqft_living * 0.2,
77
  }
78
 
79
- return pd.DataFrame(data)
 
 
 
80
 
81
  class HousePricePredictor:
82
  def __init__(self):
@@ -85,12 +90,17 @@ class HousePricePredictor:
85
  self.df = None
86
  self.is_trained = False
87
  self.selected_features = None
 
88
 
89
  def load_data(self):
90
  """Carrega dados gerados"""
91
  try:
92
- self.df = generate_king_county_data()
93
- return f"✅ Dados carregados: {self.df.shape[0]} imóveis × {self.df.shape[1]} características"
 
 
 
 
94
  except Exception as e:
95
  return f"❌ Erro ao carregar dados: {str(e)}"
96
 
@@ -194,9 +204,15 @@ class HousePricePredictor:
194
  # Instanciar o predictor
195
  predictor = HousePricePredictor()
196
 
 
 
 
 
 
 
197
  # Funções para a interface Gradio
198
  def load_data_action():
199
- """Carrega os dados"""
200
  message = predictor.load_data()
201
  features = predictor.get_numeric_features()
202
 
@@ -264,7 +280,7 @@ def train_model_action(*checkbox_values):
264
  def create_correlation_plot():
265
  """Cria gráfico de correlação"""
266
  if predictor.df is None:
267
- return None
268
 
269
  try:
270
  # Selecionar features mais importantes
@@ -280,7 +296,7 @@ def create_correlation_plot():
280
  fig, ax = plt.subplots(figsize=(10, 8))
281
  sns.heatmap(corr_matrix, annot=True, fmt='.2f', cmap='RdYlBu', center=0,
282
  square=True, linewidths=0.5, cbar_kws={"shrink": 0.8}, ax=ax)
283
- ax.set_title('Matriz de Correlação', fontsize=14, fontweight='bold')
284
  plt.tight_layout()
285
  return fig
286
  except Exception as e:
@@ -326,7 +342,7 @@ def create_feature_analysis_plot(selected_feature):
326
  ax2.set_xlabel(selected_feature)
327
  ax2.set_ylabel('Preço ($)')
328
  correlation = predictor.df[selected_feature].corr(predictor.df['price'])
329
- ax2.set_title(f'Preço vs {selected_feature} (Corr: {correlation:.3f})')
330
  ax2.grid(True, alpha=0.3)
331
  plt.tight_layout()
332
 
@@ -349,7 +365,7 @@ def create_price_distribution_plot():
349
  label=f'Mediana: ${predictor.df["price"].median():,.0f}')
350
  ax.set_xlabel('Preço ($)')
351
  ax.set_ylabel('Número de Imóveis')
352
- ax.set_title('Distribuição dos Preços dos Imóveis')
353
  ax.legend()
354
  ax.grid(True, alpha=0.3)
355
  plt.tight_layout()
@@ -364,13 +380,18 @@ def get_feature_stats(feature):
364
  correlation = predictor.df[feature].corr(predictor.df['price'])
365
 
366
  return f"""
367
- **Estatísticas de {feature}:**
 
 
368
  - Média: {stats['mean']:.2f}
369
  - Mediana: {stats['50%']:.2f}
370
  - Desvio Padrão: {stats['std']:.2f}
371
  - Mínimo: {stats['min']:.2f}
372
  - Máximo: {stats['max']:.2f}
373
- - Correlação com Preço: {correlation:.3f}
 
 
 
374
  """
375
 
376
  def create_prediction_inputs(metrics_result):
@@ -391,7 +412,7 @@ def create_prediction_inputs(metrics_result):
391
 
392
  inputs.append(
393
  gr.Slider(
394
- label=feature,
395
  minimum=min_val,
396
  maximum=max_val,
397
  value=mean_val,
@@ -423,12 +444,15 @@ def predict_price_action(*feature_values):
423
  features_summary = "\n".join([f"- **{k}**: {v:.2f}" for k, v in input_features.items()])
424
 
425
  result_text = f"""
426
- ## Previsão de Preço
427
 
428
- **💰 Preço Estimado: ${pred_price:,.2f}**
429
 
430
- **Características:**
431
  {features_summary}
 
 
 
432
  """
433
 
434
  return result_text, pred_price
@@ -437,52 +461,72 @@ def predict_price_action(*feature_values):
437
  return f"❌ Erro na previsão: {str(e)}", None
438
 
439
  # Interface Gradio
440
- with gr.Blocks(title="Previsão de Preços de Imóveis") as demo:
441
  gr.Markdown(
442
  """
443
  # 🏠 Análise e Previsão de Preços de Imóveis
444
- ## King County, Washington
445
 
446
- Analise dados imobiliários e faça previsões de preços usando machine learning.
 
447
  """
448
  )
449
 
450
- # Carregar dados automaticamente ao iniciar
451
- initial_message = predictor.load_data()
452
- initial_features = predictor.get_numeric_features()
453
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
  with gr.Tab("📊 Análise Exploratória"):
455
- gr.Markdown("### Explore os Dados")
456
 
457
  with gr.Row():
458
  with gr.Column():
459
- gr.Markdown("**Distribuição de Preços**")
460
- price_plot_btn = gr.Button("Gerar Gráfico", variant="primary")
461
  price_plot = gr.Plot()
462
 
463
  with gr.Column():
464
- gr.Markdown("**Correlações**")
465
- correlation_btn = gr.Button("Gerar Matriz", variant="primary")
466
  correlation_plot = gr.Plot()
467
 
468
  gr.Markdown("---")
469
- gr.Markdown("**Análise por Feature**")
470
 
471
  with gr.Row():
472
  with gr.Column():
473
  feature_selector = gr.Dropdown(
474
- label="Selecione uma feature",
475
  choices=initial_features,
476
  value=initial_features[0] if initial_features else None
477
  )
478
  feature_stats = gr.Markdown()
479
 
480
  with gr.Column():
481
- feature_analysis_btn = gr.Button("Analisar", variant="primary")
482
 
483
  with gr.Row():
484
- feature_dist_plot = gr.Plot()
485
- feature_price_plot = gr.Plot()
486
 
487
  # Eventos
488
  price_plot_btn.click(create_price_distribution_plot, outputs=[price_plot])
@@ -498,13 +542,22 @@ with gr.Blocks(title="Previsão de Preços de Imóveis") as demo:
498
  return get_feature_stats(feature)
499
 
500
  feature_selector.change(update_stats, inputs=[feature_selector], outputs=[feature_stats])
501
-
 
 
 
 
502
  with gr.Tab("🤖 Treinar Modelo"):
503
- gr.Markdown("### Treine o Modelo de Previsão")
504
 
505
- gr.Markdown(f"**Status:** {initial_message}")
506
- gr.Markdown("Selecione as features para o modelo:")
 
 
 
 
507
 
 
508
  feature_checkboxes = []
509
  if initial_features and predictor.df is not None:
510
  correlations = predictor.df.corr()['price'].abs().sort_values(ascending=False)
@@ -523,23 +576,29 @@ with gr.Blocks(title="Previsão de Preços de Imóveis") as demo:
523
  )
524
 
525
  feature_selection = gr.Column(feature_checkboxes)
526
- train_btn = gr.Button("Treinar Modelo", variant="primary", size="lg")
527
- train_output = gr.Markdown()
528
- metrics_display = gr.JSON(visible=False)
529
 
530
  train_btn.click(
531
  train_model_action,
532
  inputs=[feature_selection],
533
  outputs=[train_output, metrics_display, metrics_display]
534
  )
535
-
536
  with gr.Tab("💰 Fazer Previsão"):
537
- gr.Markdown("### Faça uma Previsão")
 
538
 
539
  prediction_inputs = gr.Column()
540
- predict_btn = gr.Button("Calcular Preço", variant="primary", size="lg")
541
- prediction_output = gr.Markdown()
542
- price_result = gr.Number(visible=False)
 
 
 
 
 
543
 
544
  # Atualizar inputs quando modelo for treinado
545
  def update_prediction_inputs(metrics):
@@ -559,39 +618,50 @@ with gr.Blocks(title="Previsão de Preços de Imóveis") as demo:
559
  with gr.Tab("📚 Explicações"):
560
  gr.Markdown(
561
  """
562
- ## Guia de Uso
563
 
564
- ### 📊 Análise Exploratória
565
- - **Distribuição de Preços**: Veja como os preços estão distribuídos
566
- - **Matriz de Correlação**: Identifique relações entre variáveis
567
- - **Análise por Feature**: Explore cada característica individualmente
 
568
 
569
- ### 🤖 Treinamento do Modelo
570
- - Selecione features com alta correlação com preço
571
- - O modelo usa Regressão Linear
572
- - Métricas: R², RMSE, MAE
573
 
574
- ### 💰 Previsões
575
- - Ajuste os valores das características
576
- - Obtenha previsões de preço em tempo real
577
- - Baseado no modelo treinado
578
 
579
- ### 📈 Interpretação
580
- - **R²**: Proporção da variância explicada (0-1)
581
- - **RMSE**: Erro médio em dólares
582
- - **Correlação**: Força da relação entre variáveis (-1 a +1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
583
  """
584
  )
585
 
586
- # Inicializar estatísticas da primeira feature
587
- if initial_features:
588
- initial_stats = get_feature_stats(initial_features[0])
589
- else:
590
- initial_stats = "Nenhuma feature disponível"
591
-
592
- # Atualizar o componente de estatísticas
593
- if 'feature_stats' in locals():
594
- feature_stats.value = initial_stats
595
-
596
  if __name__ == "__main__":
597
- demo.launch()
 
21
  """Gera dados realísticos simulando o dataset King County"""
22
  np.random.seed(42)
23
 
24
+ print("🎯 Gerando dados do King County...")
25
+
26
  # Gerar características básicas
27
  sqft_living = np.random.normal(2080, 920, n_samples)
28
  sqft_living = np.clip(sqft_living, 370, 13540)
 
78
  'sqft_basement': sqft_living * 0.2,
79
  }
80
 
81
+ df = pd.DataFrame(data)
82
+ print(f"✅ Dados gerados: {df.shape[0]} imóveis, {df.shape[1]} características")
83
+ print(f"💰 Preço médio: ${df['price'].mean():,.2f}")
84
+ return df
85
 
86
  class HousePricePredictor:
87
  def __init__(self):
 
90
  self.df = None
91
  self.is_trained = False
92
  self.selected_features = None
93
+ self._data_loaded = False
94
 
95
  def load_data(self):
96
  """Carrega dados gerados"""
97
  try:
98
+ if not self._data_loaded:
99
+ self.df = generate_king_county_data()
100
+ self._data_loaded = True
101
+ return f"✅ Dados carregados: {self.df.shape[0]} imóveis × {self.df.shape[1]} características"
102
+ else:
103
+ return f"✅ Dados já carregados: {self.df.shape[0]} imóveis × {self.df.shape[1]} características"
104
  except Exception as e:
105
  return f"❌ Erro ao carregar dados: {str(e)}"
106
 
 
204
  # Instanciar o predictor
205
  predictor = HousePricePredictor()
206
 
207
+ # Carregar dados uma vez no início
208
+ print("🚀 Iniciando aplicação...")
209
+ initial_message = predictor.load_data()
210
+ initial_features = predictor.get_numeric_features()
211
+ print(f"📊 Features disponíveis: {initial_features}")
212
+
213
  # Funções para a interface Gradio
214
  def load_data_action():
215
+ """Carrega os dados - função para o botão"""
216
  message = predictor.load_data()
217
  features = predictor.get_numeric_features()
218
 
 
280
  def create_correlation_plot():
281
  """Cria gráfico de correlação"""
282
  if predictor.df is None:
283
+ return gr.update(value=None)
284
 
285
  try:
286
  # Selecionar features mais importantes
 
296
  fig, ax = plt.subplots(figsize=(10, 8))
297
  sns.heatmap(corr_matrix, annot=True, fmt='.2f', cmap='RdYlBu', center=0,
298
  square=True, linewidths=0.5, cbar_kws={"shrink": 0.8}, ax=ax)
299
+ ax.set_title('Matriz de Correlação entre Variáveis', fontsize=14, fontweight='bold')
300
  plt.tight_layout()
301
  return fig
302
  except Exception as e:
 
342
  ax2.set_xlabel(selected_feature)
343
  ax2.set_ylabel('Preço ($)')
344
  correlation = predictor.df[selected_feature].corr(predictor.df['price'])
345
+ ax2.set_title(f'Relação com Preço (Corr: {correlation:.3f})')
346
  ax2.grid(True, alpha=0.3)
347
  plt.tight_layout()
348
 
 
365
  label=f'Mediana: ${predictor.df["price"].median():,.0f}')
366
  ax.set_xlabel('Preço ($)')
367
  ax.set_ylabel('Número de Imóveis')
368
+ ax.set_title('Distribuição dos Preços dos Imóveis - King County')
369
  ax.legend()
370
  ax.grid(True, alpha=0.3)
371
  plt.tight_layout()
 
380
  correlation = predictor.df[feature].corr(predictor.df['price'])
381
 
382
  return f"""
383
+ ## 📊 Estatísticas de **{feature}**
384
+
385
+ **Valores:**
386
  - Média: {stats['mean']:.2f}
387
  - Mediana: {stats['50%']:.2f}
388
  - Desvio Padrão: {stats['std']:.2f}
389
  - Mínimo: {stats['min']:.2f}
390
  - Máximo: {stats['max']:.2f}
391
+
392
+ **Relação com Preço:**
393
+ - Correlação: {correlation:.3f}
394
+ - Interpretação: {'Forte' if abs(correlation) > 0.5 else 'Moderada' if abs(correlation) > 0.3 else 'Fraca'} relação
395
  """
396
 
397
  def create_prediction_inputs(metrics_result):
 
412
 
413
  inputs.append(
414
  gr.Slider(
415
+ label=f"🏠 {feature}",
416
  minimum=min_val,
417
  maximum=max_val,
418
  value=mean_val,
 
444
  features_summary = "\n".join([f"- **{k}**: {v:.2f}" for k, v in input_features.items()])
445
 
446
  result_text = f"""
447
+ ## 🏠 Previsão de Preço do Imóvel
448
 
449
+ ### 💰 **Preço Estimado: ${pred_price:,.2f}**
450
 
451
+ ### 📋 Características Informadas:
452
  {features_summary}
453
+
454
+ ---
455
+ *Nota: Previsão baseada no modelo de regressão linear treinado.*
456
  """
457
 
458
  return result_text, pred_price
 
461
  return f"❌ Erro na previsão: {str(e)}", None
462
 
463
  # Interface Gradio
464
+ with gr.Blocks(title="🏠 Análise e Previsão de Preços de Imóveis") as demo:
465
  gr.Markdown(
466
  """
467
  # 🏠 Análise e Previsão de Preços de Imóveis
468
+ ## King County, Washington - USA
469
 
470
+ ### 📊 Dados Carregados Automaticamente
471
+ Este aplicativo utiliza dados **realísticos** simulando o mercado imobiliário de King County.
472
  """
473
  )
474
 
475
+ # Status inicial
476
+ initial_status = gr.Markdown(f"**Status:** {initial_message}")
 
477
 
478
+ with gr.Tab("🚀 Iniciar"):
479
+ gr.Markdown("### Bem-vindo ao Analisador de Preços de Imóveis!")
480
+
481
+ gr.Markdown("""
482
+ **🎯 O que você pode fazer:**
483
+
484
+ 1. **📊 Análise Exploratória** - Explore gráficos e estatísticas dos dados
485
+ 2. **🤖 Treinar Modelo** - Selecione features e treine um modelo de previsão
486
+ 3. **💰 Fazer Previsão** - Estime preços com base nas características
487
+ 4. **📚 Explicações** - Entenda os conceitos e interpretações
488
+
489
+ **Dados disponíveis:**
490
+ - Preços de imóveis de $75,000 a $5,000,000
491
+ - Características como área, quartos, banheiros, localização
492
+ - 2,000 imóveis simulados do mercado de King County
493
+ """)
494
+
495
+ load_btn = gr.Button("🔄 Recarregar Dados", variant="secondary")
496
+ load_btn.click(load_data_action, outputs=[initial_status, feature_selection, train_btn])
497
+
498
  with gr.Tab("📊 Análise Exploratória"):
499
+ gr.Markdown("### Explore os Dados e Visualize Relações")
500
 
501
  with gr.Row():
502
  with gr.Column():
503
+ gr.Markdown("#### 📈 Distribuição de Preços")
504
+ price_plot_btn = gr.Button("🎨 Gerar Gráfico de Preços", variant="primary")
505
  price_plot = gr.Plot()
506
 
507
  with gr.Column():
508
+ gr.Markdown("#### 🔗 Correlações entre Variáveis")
509
+ correlation_btn = gr.Button("🔄 Gerar Matriz de Correlação", variant="primary")
510
  correlation_plot = gr.Plot()
511
 
512
  gr.Markdown("---")
513
+ gr.Markdown("#### 🔍 Análise Detalhada por Feature")
514
 
515
  with gr.Row():
516
  with gr.Column():
517
  feature_selector = gr.Dropdown(
518
+ label="Selecione uma característica para análise detalhada",
519
  choices=initial_features,
520
  value=initial_features[0] if initial_features else None
521
  )
522
  feature_stats = gr.Markdown()
523
 
524
  with gr.Column():
525
+ feature_analysis_btn = gr.Button("📈 Analisar Feature", variant="primary")
526
 
527
  with gr.Row():
528
+ feature_dist_plot = gr.Plot(label="Distribuição da Feature")
529
+ feature_price_plot = gr.Plot(label="Relação com Preço")
530
 
531
  # Eventos
532
  price_plot_btn.click(create_price_distribution_plot, outputs=[price_plot])
 
542
  return get_feature_stats(feature)
543
 
544
  feature_selector.change(update_stats, inputs=[feature_selector], outputs=[feature_stats])
545
+
546
+ # Inicializar estatísticas da primeira feature
547
+ if initial_features:
548
+ feature_stats.value = get_feature_stats(initial_features[0])
549
+
550
  with gr.Tab("🤖 Treinar Modelo"):
551
+ gr.Markdown("### Configure e Treine o Modelo de Previsão")
552
 
553
+ gr.Markdown("""
554
+ **🎯 Como Funciona:**
555
+ - Selecione as características que deseja usar para prever preços
556
+ - Features com alta correlação (próximas de 1 ou -1) geralmente são melhores preditoras
557
+ - O modelo usará **Regressão Linear** para aprender os padrões
558
+ """)
559
 
560
+ # Criar checkboxes para features
561
  feature_checkboxes = []
562
  if initial_features and predictor.df is not None:
563
  correlations = predictor.df.corr()['price'].abs().sort_values(ascending=False)
 
576
  )
577
 
578
  feature_selection = gr.Column(feature_checkboxes)
579
+ train_btn = gr.Button("🚀 Treinar Modelo de Previsão", variant="primary", size="lg", visible=bool(initial_features))
580
+ train_output = gr.Markdown("Selecione as features acima e clique em 'Treinar Modelo'")
581
+ metrics_display = gr.JSON(label="Métricas Detalhadas", visible=False)
582
 
583
  train_btn.click(
584
  train_model_action,
585
  inputs=[feature_selection],
586
  outputs=[train_output, metrics_display, metrics_display]
587
  )
588
+
589
  with gr.Tab("💰 Fazer Previsão"):
590
+ gr.Markdown("### Faça uma Previsão de Preço")
591
+ gr.Markdown("Ajuste os valores das características para estimar o preço de um imóvel:")
592
 
593
  prediction_inputs = gr.Column()
594
+ predict_btn = gr.Button("🎯 Calcular Preço do Imóvel", variant="primary", size="lg")
595
+
596
+ with gr.Row():
597
+ prediction_output = gr.Markdown("Preencha os valores acima e clique em 'Calcular Preço'")
598
+ price_result = gr.Number(
599
+ label="💵 Preço Previsto",
600
+ visible=False
601
+ )
602
 
603
  # Atualizar inputs quando modelo for treinado
604
  def update_prediction_inputs(metrics):
 
618
  with gr.Tab("📚 Explicações"):
619
  gr.Markdown(
620
  """
621
+ ## 📊 Guia Completo de Análise
622
 
623
+ ### 🏠 Sobre os Dados
624
+ **King County** inclui Seattle e é um mercado imobiliário dinâmico. Os dados simulados incluem:
625
+ - **Preços**: De $75,000 a $5,000,000
626
+ - **Características**: Área, quartos, banheiros, localização, qualidade, etc.
627
+ - **Período**: Imóveis de 1900 até 2015
628
 
629
+ ### 📈 Interpretação dos Gráficos
 
 
 
630
 
631
+ #### 1. Distribuição de Preços
632
+ - **Histograma**: Mostra quantos imóveis existem em cada faixa de preço
633
+ - **Média vs Mediana**: Se a média > mediana, há imóveis muito caros puxando a média
634
+ - **Assimetria**: Mercados reais geralmente têm assimetria positiva (mais imóveis baratos)
635
 
636
+ #### 2. Matriz de Correlação
637
+ - **🔴 Vermelho**: Correlação positiva (ex: área maior → preço maior)
638
+ - **🔵 Azul**: Correlação negativa (ex: ano mais antigo → preço menor)
639
+ - **Valores**: -1 (perfeita negativa) a +1 (perfeita positiva)
640
+ - **Para modelo**: Busque features com |correlação| > 0.3 com preço
641
+
642
+ #### 3. Análise por Feature
643
+ - **Distribuição**: Como os valores se espalham (normal, assimétrica)
644
+ - **Relação com Preço**: Padrão linear? Há outliers?
645
+ - **Boxplot**: Mostra mediana, quartis e valores extremos
646
+
647
+ ### 🤖 Sobre o Modelo
648
+ - **Algoritmo**: Regressão Linear Múltipla
649
+ - **Transformação**: Logarítmica nos preços para normalizar
650
+ - **Avaliação**: R² mostra % da variância explicada (0-100%)
651
+ - **Coeficientes**: Impacto de cada feature no preço final
652
+
653
+ ### 💡 Dicas para Boas Previsões
654
+ 1. **Selecione features relevantes**: Área, quartos, localização
655
+ 2. **Evite multicolinearidade**: Não use features muito correlacionadas entre si
656
+ 3. **Verifique relações lineares**: Features com relação clara com preço funcionam melhor
657
+ 4. **Considere o contexto**: Características únicas podem afetar preços reais
658
+
659
+ ### 🎯 Métricas do Modelo
660
+ - **R²**: 0.7-0.9 = Excelente, 0.5-0.7 = Bom, <0.5 = Precisa melhorar
661
+ - **RMSE**: Erro médio em dólares (ideal: <20% do preço médio)
662
+ - **Coeficientes**: Mostram quanto cada feature impacta no preço
663
  """
664
  )
665
 
 
 
 
 
 
 
 
 
 
 
666
  if __name__ == "__main__":
667
+ demo.launch(share=True)