FernandezUNB commited on
Commit
66d0fa3
·
verified ·
1 Parent(s): 67fe8dc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +157 -182
app.py CHANGED
@@ -16,73 +16,6 @@ sns.set_style("whitegrid")
16
  plt.rcParams['figure.figsize'] = (12, 6)
17
  plt.rcParams['font.size'] = 10
18
 
19
- # Gerar dados realísticos do King County
20
- 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
- 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)
29
-
30
- bedrooms = np.random.choice([1, 2, 3, 4, 5], n_samples, p=[0.1, 0.3, 0.4, 0.15, 0.05])
31
- bathrooms = np.random.choice([1, 1.5, 2, 2.5, 3, 3.5], n_samples, p=[0.1, 0.2, 0.4, 0.2, 0.08, 0.02])
32
- floors = np.random.choice([1, 1.5, 2, 2.5, 3], n_samples, p=[0.4, 0.3, 0.2, 0.08, 0.02])
33
- waterfront = np.random.choice([0, 1], n_samples, p=[0.99, 0.01])
34
- view = np.random.choice([0, 1, 2, 3, 4], n_samples, p=[0.9, 0.05, 0.03, 0.015, 0.005])
35
- condition = np.random.choice([1, 2, 3, 4, 5], n_samples, p=[0.05, 0.2, 0.5, 0.2, 0.05])
36
- grade = np.random.choice([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], n_samples,
37
- p=[0.001, 0.005, 0.01, 0.05, 0.1, 0.15, 0.2, 0.15, 0.1, 0.08, 0.06, 0.03, 0.01])
38
-
39
- yr_built = np.random.randint(1900, 2016, n_samples)
40
- lat = np.random.uniform(47.2, 47.8, n_samples)
41
- long = np.random.uniform(-122.5, -121.8, n_samples)
42
-
43
- # Calcular preço base com relações realísticas
44
- base_price = (
45
- sqft_living * 300 +
46
- bedrooms * 50000 +
47
- bathrooms * 40000 +
48
- floors * 25000 +
49
- waterfront * 500000 +
50
- view * 25000 +
51
- condition * 15000 +
52
- grade * 30000 +
53
- (2024 - yr_built) * -500 +
54
- (lat - 47.5) * 100000 +
55
- (long + 122.2) * 80000
56
- )
57
-
58
- noise = np.random.normal(0, 150000, n_samples)
59
- price = base_price + noise
60
- price = np.clip(price, 75000, 5000000)
61
-
62
- # Criar DataFrame
63
- data = {
64
- 'price': price,
65
- 'sqft_living': sqft_living,
66
- 'bedrooms': bedrooms,
67
- 'bathrooms': bathrooms,
68
- 'floors': floors,
69
- 'waterfront': waterfront,
70
- 'view': view,
71
- 'condition': condition,
72
- 'grade': grade,
73
- 'yr_built': yr_built,
74
- 'lat': lat,
75
- 'long': long,
76
- 'sqft_lot': np.random.normal(15000, 10000, n_samples),
77
- 'sqft_above': sqft_living * 0.8,
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):
88
  self.model = None
@@ -93,17 +26,46 @@ class HousePricePredictor:
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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  def get_numeric_features(self):
108
  """Retorna lista de features numéricas (excluindo price)"""
109
  if self.df is None:
@@ -124,7 +86,7 @@ class HousePricePredictor:
124
 
125
  self.selected_features = selected_features
126
  X = self.df[selected_features]
127
- y = np.log1p(self.df['price'])
128
 
129
  # Dividir dados
130
  X_train, X_test, y_train, y_test = train_test_split(
@@ -204,7 +166,7 @@ class HousePricePredictor:
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()
@@ -233,7 +195,8 @@ def load_data_action():
233
  feature_checkboxes.append(
234
  gr.Checkbox(
235
  label=f"{feature} (corr: {corr_value:.3f})",
236
- value=feature in top_features
 
237
  )
238
  )
239
 
@@ -280,7 +243,7 @@ def train_model_action(*checkbox_values):
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
@@ -293,10 +256,10 @@ def create_correlation_plot():
293
 
294
  corr_matrix = predictor.df[top_features].corr()
295
 
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:
@@ -310,17 +273,19 @@ def create_feature_analysis_plot(selected_feature):
310
 
311
  try:
312
  # Gráfico 1: Distribuição
313
- fig1, ax1 = plt.subplots(figsize=(8, 4))
314
  ax1.hist(predictor.df[selected_feature], bins=30, edgecolor='black', alpha=0.7, color='skyblue')
315
- ax1.axvline(predictor.df[selected_feature].mean(), color='red', linestyle='--', linewidth=2)
 
316
  ax1.set_xlabel(selected_feature)
317
  ax1.set_ylabel('Frequência')
318
- ax1.set_title(f'Distribuição de {selected_feature}')
 
319
  ax1.grid(True, alpha=0.3)
320
  plt.tight_layout()
321
 
322
  # Gráfico 2: Relação com preço
323
- fig2, ax2 = plt.subplots(figsize=(8, 4))
324
 
325
  if predictor.df[selected_feature].nunique() < 10:
326
  # Boxplot para variáveis categóricas
@@ -332,20 +297,24 @@ def create_feature_analysis_plot(selected_feature):
332
  ax2.boxplot(data_to_plot, labels=categories)
333
  else:
334
  # Scatter plot para variáveis contínuas
335
- ax2.scatter(predictor.df[selected_feature], predictor.df['price'], alpha=0.5, s=20, color='steelblue')
336
  # Linha de tendência
337
  z = np.polyfit(predictor.df[selected_feature], predictor.df['price'], 1)
338
  p = np.poly1d(z)
339
  x_range = np.linspace(predictor.df[selected_feature].min(), predictor.df[selected_feature].max(), 100)
340
- ax2.plot(x_range, p(x_range), "r--", linewidth=2, alpha=0.8)
 
341
 
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
 
 
 
 
 
349
  return fig1, fig2
350
 
351
  except Exception as e:
@@ -357,7 +326,7 @@ def create_price_distribution_plot():
357
  if predictor.df is None:
358
  return None
359
 
360
- fig, ax = plt.subplots(figsize=(10, 5))
361
  ax.hist(predictor.df['price'], bins=50, edgecolor='black', alpha=0.7, color='steelblue')
362
  ax.axvline(predictor.df['price'].mean(), color='red', linestyle='--', linewidth=2,
363
  label=f'Média: ${predictor.df["price"].mean():,.0f}')
@@ -365,9 +334,13 @@ def create_price_distribution_plot():
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()
372
  return fig
373
 
@@ -380,7 +353,7 @@ def get_feature_stats(feature):
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}
@@ -389,6 +362,11 @@ def get_feature_stats(feature):
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
@@ -409,6 +387,8 @@ def create_prediction_inputs(metrics_result):
409
  step = (max_val - min_val) / 100
410
  if step < 0.1:
411
  step = 0.1
 
 
412
 
413
  inputs.append(
414
  gr.Slider(
@@ -416,7 +396,8 @@ def create_prediction_inputs(metrics_result):
416
  minimum=min_val,
417
  maximum=max_val,
418
  value=mean_val,
419
- step=step
 
420
  )
421
  )
422
 
@@ -452,7 +433,7 @@ def predict_price_action(*feature_values):
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,14 +442,15 @@ def predict_price_action(*feature_values):
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
 
@@ -476,31 +458,35 @@ with gr.Blocks(title="🏠 Análise e Previsão de Preços de Imóveis") as demo
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
 
@@ -537,47 +523,29 @@ with gr.Blocks(title="🏠 Análise e Previsão de Preços de Imóveis") as demo
537
  outputs=[feature_dist_plot, feature_price_plot]
538
  )
539
 
540
- # Atualizar estatísticas quando feature mudar
541
- def update_stats(feature):
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)
564
- top_features = []
565
- for feature in correlations.index:
566
- if feature != 'price' and len(top_features) < 6:
567
- top_features.append(feature)
568
-
569
- for feature in initial_features:
570
- corr_value = correlations.get(feature, 0)
571
- feature_checkboxes.append(
572
- gr.Checkbox(
573
- label=f"{feature} (corr: {corr_value:.3f})",
574
- value=feature in top_features
575
- )
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(
@@ -587,24 +555,24 @@ with gr.Blocks(title="🏠 Análise e Previsão de Preços de Imóveis") as demo
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):
605
- return create_prediction_inputs(metrics)
606
-
607
- metrics_display.change(update_prediction_inputs, inputs=[metrics_display], outputs=[prediction_inputs])
 
608
 
609
  predict_btn.click(
610
  predict_price_action,
@@ -618,50 +586,57 @@ with gr.Blocks(title="🏠 Análise e Previsão de Preços de Imóveis") as demo
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**: 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)
 
16
  plt.rcParams['figure.figsize'] = (12, 6)
17
  plt.rcParams['font.size'] = 10
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  class HousePricePredictor:
20
  def __init__(self):
21
  self.model = None
 
26
  self._data_loaded = False
27
 
28
  def load_data(self):
29
+ """Carrega dados do arquivo kc_house_data.csv"""
30
  try:
31
  if not self._data_loaded:
32
+ print("📂 Tentando carregar kc_house_data.csv...")
33
+
34
+ # Tentar carregar do arquivo local (Hugging Face Files)
35
+ self.df = pd.read_csv('kc_house_data.csv')
36
+
37
+ # Limpeza básica dos dados
38
+ self._clean_data()
39
+
40
  self._data_loaded = True
41
+ print(f"✅ Dados carregados: {self.df.shape[0]} imóveis × {self.df.shape[1]} características")
42
  return f"✅ Dados carregados: {self.df.shape[0]} imóveis × {self.df.shape[1]} características"
43
  else:
44
  return f"✅ Dados já carregados: {self.df.shape[0]} imóveis × {self.df.shape[1]} características"
45
+
46
  except Exception as e:
47
+ print(f"❌ Erro ao carregar arquivo: {e}")
48
  return f"❌ Erro ao carregar dados: {str(e)}"
49
 
50
+ def _clean_data(self):
51
+ """Faz limpeza básica dos dados"""
52
+ # Remover colunas não numéricas problemáticas
53
+ if 'date' in self.df.columns:
54
+ self.df = self.df.drop(columns=['date'])
55
+ if 'id' in self.df.columns:
56
+ self.df = self.df.drop(columns=['id'])
57
+
58
+ # Remover linhas com valores missing
59
+ self.df = self.df.dropna()
60
+
61
+ # Remover outliers extremos no preço
62
+ Q1 = self.df['price'].quantile(0.01)
63
+ Q3 = self.df['price'].quantile(0.99)
64
+ self.df = self.df[(self.df['price'] >= Q1) & (self.df['price'] <= Q3)]
65
+
66
+ print(f"📊 Dados limpos: {self.df.shape[0]} imóveis")
67
+ print(f"💰 Preço médio: ${self.df['price'].mean():,.2f}")
68
+
69
  def get_numeric_features(self):
70
  """Retorna lista de features numéricas (excluindo price)"""
71
  if self.df is None:
 
86
 
87
  self.selected_features = selected_features
88
  X = self.df[selected_features]
89
+ y = np.log1p(self.df['price']) # Transformação logarítmica
90
 
91
  # Dividir dados
92
  X_train, X_test, y_train, y_test = train_test_split(
 
166
  # Instanciar o predictor
167
  predictor = HousePricePredictor()
168
 
169
+ # Carregar dados automaticamente ao iniciar
170
  print("🚀 Iniciando aplicação...")
171
  initial_message = predictor.load_data()
172
  initial_features = predictor.get_numeric_features()
 
195
  feature_checkboxes.append(
196
  gr.Checkbox(
197
  label=f"{feature} (corr: {corr_value:.3f})",
198
+ value=feature in top_features,
199
+ info=f"Média: {predictor.df[feature].mean():.1f}"
200
  )
201
  )
202
 
 
243
  def create_correlation_plot():
244
  """Cria gráfico de correlação"""
245
  if predictor.df is None:
246
+ return None
247
 
248
  try:
249
  # Selecionar features mais importantes
 
256
 
257
  corr_matrix = predictor.df[top_features].corr()
258
 
259
+ fig, ax = plt.subplots(figsize=(12, 10))
260
  sns.heatmap(corr_matrix, annot=True, fmt='.2f', cmap='RdYlBu', center=0,
261
  square=True, linewidths=0.5, cbar_kws={"shrink": 0.8}, ax=ax)
262
+ ax.set_title('🔗 Matriz de Correlação - Dataset Real King County', fontsize=14, fontweight='bold')
263
  plt.tight_layout()
264
  return fig
265
  except Exception as e:
 
273
 
274
  try:
275
  # Gráfico 1: Distribuição
276
+ fig1, ax1 = plt.subplots(figsize=(10, 5))
277
  ax1.hist(predictor.df[selected_feature], bins=30, edgecolor='black', alpha=0.7, color='skyblue')
278
+ ax1.axvline(predictor.df[selected_feature].mean(), color='red', linestyle='--', linewidth=2,
279
+ label=f'Média: {predictor.df[selected_feature].mean():.2f}')
280
  ax1.set_xlabel(selected_feature)
281
  ax1.set_ylabel('Frequência')
282
+ ax1.set_title(f'📊 Distribuição de {selected_feature}')
283
+ ax1.legend()
284
  ax1.grid(True, alpha=0.3)
285
  plt.tight_layout()
286
 
287
  # Gráfico 2: Relação com preço
288
+ fig2, ax2 = plt.subplots(figsize=(10, 5))
289
 
290
  if predictor.df[selected_feature].nunique() < 10:
291
  # Boxplot para variáveis categóricas
 
297
  ax2.boxplot(data_to_plot, labels=categories)
298
  else:
299
  # Scatter plot para variáveis contínuas
300
+ ax2.scatter(predictor.df[selected_feature], predictor.df['price'], alpha=0.3, s=20, color='steelblue')
301
  # Linha de tendência
302
  z = np.polyfit(predictor.df[selected_feature], predictor.df['price'], 1)
303
  p = np.poly1d(z)
304
  x_range = np.linspace(predictor.df[selected_feature].min(), predictor.df[selected_feature].max(), 100)
305
+ ax2.plot(x_range, p(x_range), "r--", linewidth=2, alpha=0.8, label='Tendência linear')
306
+ ax2.legend()
307
 
308
  ax2.set_xlabel(selected_feature)
309
  ax2.set_ylabel('Preço ($)')
310
  correlation = predictor.df[selected_feature].corr(predictor.df['price'])
311
+ ax2.set_title(f'💰 Preço vs {selected_feature} (Corr: {correlation:.3f})')
312
  ax2.grid(True, alpha=0.3)
 
313
 
314
+ # Formatar eixo y para dólares
315
+ ax2.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f'${x:,.0f}'))
316
+
317
+ plt.tight_layout()
318
  return fig1, fig2
319
 
320
  except Exception as e:
 
326
  if predictor.df is None:
327
  return None
328
 
329
+ fig, ax = plt.subplots(figsize=(12, 6))
330
  ax.hist(predictor.df['price'], bins=50, edgecolor='black', alpha=0.7, color='steelblue')
331
  ax.axvline(predictor.df['price'].mean(), color='red', linestyle='--', linewidth=2,
332
  label=f'Média: ${predictor.df["price"].mean():,.0f}')
 
334
  label=f'Mediana: ${predictor.df["price"].median():,.0f}')
335
  ax.set_xlabel('Preço ($)')
336
  ax.set_ylabel('Número de Imóveis')
337
+ ax.set_title('🏠 Distribuição dos Preços - Dataset Real King County')
338
  ax.legend()
339
  ax.grid(True, alpha=0.3)
340
+
341
+ # Formatar eixo x para dólares
342
+ ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f'${x:,.0f}'))
343
+
344
  plt.tight_layout()
345
  return fig
346
 
 
353
  correlation = predictor.df[feature].corr(predictor.df['price'])
354
 
355
  return f"""
356
+ ## 📈 Estatísticas de **{feature}**
357
 
358
  **Valores:**
359
  - Média: {stats['mean']:.2f}
 
362
  - Mínimo: {stats['min']:.2f}
363
  - Máximo: {stats['max']:.2f}
364
 
365
+ **Distribuição:**
366
+ - 25º Percentil: {stats['25%']:.2f}
367
+ - 75º Percentil: {stats['75%']:.2f}
368
+ - Valores Únicos: {predictor.df[feature].nunique()}
369
+
370
  **Relação com Preço:**
371
  - Correlação: {correlation:.3f}
372
  - Interpretação: {'Forte' if abs(correlation) > 0.5 else 'Moderada' if abs(correlation) > 0.3 else 'Fraca'} relação
 
387
  step = (max_val - min_val) / 100
388
  if step < 0.1:
389
  step = 0.1
390
+ elif step > 100:
391
+ step = 10
392
 
393
  inputs.append(
394
  gr.Slider(
 
396
  minimum=min_val,
397
  maximum=max_val,
398
  value=mean_val,
399
+ step=step,
400
+ info=f"Range: {min_val:.1f} - {max_val:.1f}"
401
  )
402
  )
403
 
 
433
  {features_summary}
434
 
435
  ---
436
+ *💡 Nota: Previsão baseada no modelo treinado com dados reais do King County.*
437
  """
438
 
439
  return result_text, pred_price
 
442
  return f"❌ Erro na previsão: {str(e)}", None
443
 
444
  # Interface Gradio
445
+ with gr.Blocks(title="🏠 Análise e Previsão - King County Dataset Real") as demo:
446
  gr.Markdown(
447
  """
448
  # 🏠 Análise e Previsão de Preços de Imóveis
449
+ ## 📊 Dataset Real - King County, Washington
450
 
451
+ ### ℹ️ Sobre os Dados:
452
+ Este aplicativo utiliza o **dataset real** `kc_house_data.csv` do mercado imobiliário de King County.
453
+ Dados reais de vendas de imóveis com diversas características.
454
  """
455
  )
456
 
 
458
  initial_status = gr.Markdown(f"**Status:** {initial_message}")
459
 
460
  with gr.Tab("🚀 Iniciar"):
461
+ gr.Markdown("### Bem-vindo ao Analisador de Dados Reais do King County!")
462
+
463
+ gr.Markdown(f"""
464
+ **📊 Dataset Carregado:**
465
+ - **Arquivo**: kc_house_data.csv
466
+ - **Imóveis**: {predictor.df.shape[0] if predictor.df else 'Carregando...'}
467
+ - **Características**: {predictor.df.shape[1] if predictor.df else 'Carregando...'}
468
+ - **Preço Médio**: ${predictor.df['price'].mean():,.2f' if predictor.df else 'Carregando...'}
469
+
470
+ **🎯 Funcionalidades:**
471
+ 1. **📊 Análise Exploratória** - Gráficos com dados reais
472
+ 2. **🤖 Treinar Modelo** - Machine Learning com features selecionadas
473
+ 3. **💰 Fazer Previsão** - Estime preços baseado no modelo
474
+ 4. **📚 Explicações** - Entenda as análises
475
  """)
476
 
477
  load_btn = gr.Button("🔄 Recarregar Dados", variant="secondary")
478
+ load_status = gr.Markdown()
479
+ feature_selection = gr.Column()
480
+ train_btn = gr.Button("🚀 Treinar Modelo", variant="primary", visible=False)
481
+
482
+ load_btn.click(load_data_action, outputs=[load_status, feature_selection, train_btn])
483
 
484
  with gr.Tab("📊 Análise Exploratória"):
485
+ gr.Markdown("### Explore os Dados Reais do King County")
486
 
487
  with gr.Row():
488
  with gr.Column():
489
+ gr.Markdown("#### 📈 Distribuição de Preços Reais")
490
  price_plot_btn = gr.Button("🎨 Gerar Gráfico de Preços", variant="primary")
491
  price_plot = gr.Plot()
492
 
 
523
  outputs=[feature_dist_plot, feature_price_plot]
524
  )
525
 
 
 
 
 
 
 
526
  # Inicializar estatísticas da primeira feature
527
  if initial_features:
528
  feature_stats.value = get_feature_stats(initial_features[0])
529
+
530
+ # Atualizar estatísticas quando feature mudar
531
+ feature_selector.change(
532
+ get_feature_stats,
533
+ inputs=[feature_selector],
534
+ outputs=[feature_stats]
535
+ )
536
 
537
  with gr.Tab("🤖 Treinar Modelo"):
538
+ gr.Markdown("### Treine o Modelo com Dados Reais")
539
 
540
  gr.Markdown("""
541
  **🎯 Como Funciona:**
542
+ - Selecione as características para prever preços
543
+ - Features com alta correlação são melhores preditoras
544
+ - Modelo: **Regressão Linear** com dados reais
545
+ - **Dataset**: kc_house_data.csv (dados reais)
546
  """)
547
 
548
+ train_output = gr.Markdown("Selecione as features e clique em 'Treinar Modelo'")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
549
  metrics_display = gr.JSON(label="Métricas Detalhadas", visible=False)
550
 
551
  train_btn.click(
 
555
  )
556
 
557
  with gr.Tab("💰 Fazer Previsão"):
558
+ gr.Markdown("### Faça Previsões com o Modelo Treinado")
 
559
 
560
  prediction_inputs = gr.Column()
561
  predict_btn = gr.Button("🎯 Calcular Preço do Imóvel", variant="primary", size="lg")
562
 
563
  with gr.Row():
564
+ prediction_output = gr.Markdown("Preencha os valores e clique em 'Calcular Preço'")
565
  price_result = gr.Number(
566
  label="💵 Preço Previsto",
567
  visible=False
568
  )
569
 
570
  # Atualizar inputs quando modelo for treinado
571
+ metrics_display.change(
572
+ create_prediction_inputs,
573
+ inputs=[metrics_display],
574
+ outputs=[prediction_inputs]
575
+ )
576
 
577
  predict_btn.click(
578
  predict_price_action,
 
586
  with gr.Tab("📚 Explicações"):
587
  gr.Markdown(
588
  """
589
+ ## 📊 Guia do Dataset Real King County
590
 
591
+ ### 🏠 Sobre os Dados Reais
592
+ **King County** inclui Seattle e áreas metropolitanas. O dataset contém:
593
+ - **Vendas reais** de imóveis
594
+ - **Período**: Maio 2014 - Maio 2015
595
+ - **Características**: 21 colunas incluindo localização, tamanho, qualidade
596
+ - **Preços**: Variam de dezenas de milhares a milhões de dólares
597
 
598
+ ### 📈 Variáveis Principais:
599
+ - **price**: Preço de venda (target)
600
+ - **sqft_living**: Área habitável (pés quadrados)
601
+ - **bedrooms**: Número de quartos
602
+ - **bathrooms**: Número de banheiros
603
+ - **floors**: Número de andares
604
+ - **waterfront**: Vista para água (0/1)
605
+ - **view**: Qualidade da vista (0-4)
606
+ - **condition**: Condição do imóvel (1-5)
607
+ - **grade**: Grau de construção (1-13)
608
+ - **yr_built**: Ano de construção
609
+ - **lat/long**: Coordenadas geográficas
610
 
611
+ ### 🎯 Interpretação dos Gráficos
 
 
 
612
 
613
+ #### Distribuição de Preços
614
+ - Mostra a realidade do mercado imobiliário
615
+ - Geralmente assimétrica positiva (mais imóveis baratos)
616
+ - Presença de outliers (imóveis de luxo)
 
617
 
618
+ #### Matriz de Correlação
619
+ - Baseada em **dados reais**
620
+ - Relações observadas no mercado real
621
+ - Padrões que o modelo aprenderá
622
 
623
+ #### Análise por Feature
624
+ - Distribuições reais das características
625
+ - Relações observadas com preços de venda
626
+ - Insights do mercado real
 
627
 
628
+ ### 🤖 Modelo de Machine Learning
629
+ - **Algoritmo**: Regressão Linear Múltipla
630
+ - **Base**: Dados reais de vendas
631
+ - **Aplicação**: Previsão de preços baseada em padrões históricos
 
632
 
633
+ ### 💡 Insights do Mercado Real
634
+ - Features como **sqft_living** e **grade** têm alta correlação
635
+ - Localização (**lat/long**) é crucial para preços
636
+ - Características de qualidade impactam significativamente
637
+ - O modelo captura relações observadas no mercado real
638
  """
639
  )
640
 
641
  if __name__ == "__main__":
642
+ demo.launch()