EmilySouza021 commited on
Commit
02a6d79
·
verified ·
1 Parent(s): 83917d8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +180 -351
app.py CHANGED
@@ -3,224 +3,136 @@ import pandas as pd
3
  import numpy as np
4
  import matplotlib.pyplot as plt
5
  import seaborn as sns
6
- import plotly.express as px
7
- import plotly.graph_objects as go
8
- from plotly.subplots import make_subplots
9
- from sklearn.linear_model import LinearRegression, Ridge
10
- from sklearn.ensemble import RandomForestRegressor
11
- from sklearn.model_selection import train_test_split, cross_val_score
12
  from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error
13
- from sklearn.preprocessing import StandardScaler, LabelEncoder
14
- from sklearn.inspection import permutation_importance
15
- from scipy import stats
16
- from scipy.stats import kruskal, shapiro, levene, norm
17
  import io
18
  import base64
19
- import warnings
20
- warnings.filterwarnings('ignore')
21
 
22
- # CONFIGURAÇÕES VISUAIS PROFISSIONAIS
23
- plt.style.use('seaborn-v0_8')
24
- sns.set_palette("husl")
25
- plt.rcParams['figure.figsize'] = (14, 10)
26
- plt.rcParams['font.size'] = 12
27
 
28
- # CORES PROFISSIONAIS
29
- CORES = {
30
- 'primaria': '#2E86AB',
31
- 'secundaria': '#A23B72',
32
- 'sucesso': '#18A558',
33
- 'alerta': '#F18F01',
34
- 'perigo': '#C73E1D',
35
- 'neutro': '#6C757D',
36
- 'fundo': '#F8F9FA'
37
- }
38
-
39
- def criar_dashboard_profissional():
40
- """Função principal que cria o dashboard profissional"""
41
-
42
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", neutral_hue="slate")) as dashboard:
43
 
44
- # HEADER PROFISSIONAL
45
- with gr.Row():
46
- with gr.Column(scale=1):
47
- gr.Markdown(
48
- """
49
- <div style="text-align: center; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 15px; color: white;">
50
- <h1 style="margin: 0; font-size: 2.5em;">🏠 ANALYTICS IMOBILIÁRIO</h1>
51
- <p style="margin: 0; font-size: 1.2em; opacity: 0.9;">Dashboard de Modelagem Estatística Avançada</p>
52
- </div>
53
- """
54
- )
55
 
56
- # MENU DE NAVEGAÇÃO
57
  with gr.Row():
58
- with gr.Column():
59
- selected_tab = gr.Radio(
60
- choices=["📊 Análise Exploratória", "📈 ANOVA Estatística", "🤖 Modelo Preditivo", "📋 Relatório Completo"],
61
- value="📊 Análise Exploratória",
62
- label="Navegação",
63
- info="Selecione a análise desejada"
64
- )
65
 
66
  gr.Markdown("---")
67
 
68
- # PAINEL DE CONTROLES
69
  with gr.Row():
70
  with gr.Column(scale=1):
71
- with gr.Group():
72
- gr.Markdown("### ⚙️ Configurações dos Dados")
73
-
74
- arquivo_csv = gr.File(
75
- label="Upload do Dataset (CSV)",
76
- file_types=[".csv"],
77
- file_count="single"
 
 
 
 
 
78
  )
79
-
80
- gr.Markdown("**📋 Variáveis para Análise**")
81
-
82
- with gr.Row():
83
- var_cat_anova_1 = gr.Dropdown(
84
- label="Variável Categórica 1 (ANOVA)",
85
- choices=[],
86
- interactive=True
87
- )
88
- var_cat_anova_2 = gr.Dropdown(
89
- label="Variável Categórica 2 (ANOVA)",
90
- choices=[],
91
- interactive=True
92
- )
93
-
94
- with gr.Row():
95
- var_cont_reg_1 = gr.Dropdown(
96
- label="Variável Contínua 1 (Regressão)",
97
- choices=[],
98
- interactive=True
99
- )
100
- var_cont_reg_2 = gr.Dropdown(
101
- label="Variável Contínua 2 (Regressão)",
102
- choices=[],
103
- interactive=True
104
- )
105
-
106
- var_cat_reg = gr.Dropdown(
107
- label="Variável Categórica (Regressão)",
108
  choices=[],
109
  interactive=True
110
  )
111
-
112
- with gr.Row():
113
- aplicar_log = gr.Checkbox(
114
- label="Aplicar Transformação Logarítmica",
115
- value=True,
116
- interactive=True
117
- )
118
- testar_pressupostos = gr.Checkbox(
119
- label="Testar Pressupostos Estatísticos",
120
- value=True,
121
- interactive=True
122
- )
123
 
124
  btn_analisar = gr.Button(
125
- "🚀 EXECUTAR ANÁLISE COMPLETA",
126
  variant="primary",
127
  size="lg"
128
  )
129
 
130
- # ÁREA DE RESULTADOS
131
  with gr.Column(scale=2):
132
- output_analise = gr.HTML(
133
- label="Resultados da Análise",
134
  value="""
135
- <div style="text-align: center; padding: 60px; background: #f8f9fa; border-radius: 10px; border: 2px dashed #dee2e6;">
136
  <h3 style="color: #6c757d;">📊 Área de Resultados</h3>
137
- <p style="color: #6c757d;">Configure os parâmetros e execute a análise para ver os resultados</p>
138
  </div>
139
  """
140
  )
141
 
142
- # FUNÇÕES DE ATUALIZAÇÃO
143
  def atualizar_variaveis(arquivo):
144
- """Atualiza dropdowns com variáveis do dataset"""
145
  if arquivo is None:
146
- # Variáveis padrão para dados de exemplo
147
- variaveis = ['OverallQual', 'FullBath', 'Neighborhood', 'GrLivArea', 'GarageCars', 'BedroomAbvGr', 'YearBuilt']
148
- return [gr.Dropdown(choices=variaveis)] * 5
149
  else:
150
  try:
151
  df = pd.read_csv(arquivo.name)
152
  variaveis = df.columns.tolist()
153
- return [gr.Dropdown(choices=variaveis)] * 5
154
  except:
155
- return [gr.Dropdown(choices=[])] * 5
156
 
157
- # FUNÇÃO PRINCIPAL DE ANÁLISE
158
- def executar_analise_completa(arquivo, var_cat1, var_cat2, var_cont1, var_cont2, var_cat_reg, aplicar_log, testar_pressupostos, tab_selecionada):
159
- """Executa análise estatística completa"""
160
-
161
  try:
162
- # CARREGAR DADOS
163
  if arquivo is None:
164
  df = gerar_dados_exemplo()
165
  else:
166
  df = pd.read_csv(arquivo.name)
167
 
168
- # ANÁLISE EXPLORATÓRIA
169
- if tab_selecionada == "📊 Análise Exploratória":
170
- return gerar_analise_exploratoria(df)
171
-
172
- # ANÁLISE ANOVA
173
- elif tab_selecionada == "📈 ANOVA Estatística":
174
- return gerar_analise_anova(df, var_cat1, var_cat2, testar_pressupostos)
175
-
176
- # MODELO PREDITIVO
177
- elif tab_selecionada == "🤖 Modelo Preditivo":
178
- return gerar_modelo_preditivo(df, var_cont1, var_cont2, var_cat_reg, aplicar_log, testar_pressupostos)
179
-
180
- # RELATÓRIO COMPLETO
181
  else:
182
- return gerar_relatorio_completo(df, var_cat1, var_cat2, var_cont1, var_cont2, var_cat_reg, aplicar_log, testar_pressupostos)
183
 
184
  except Exception as e:
185
  return f"""
186
- <div style="background: #f8d7da; color: #721c24; padding: 20px; border-radius: 10px; border: 1px solid #f5c6cb;">
187
- <h3>❌ Erro na Análise</h3>
188
- <p><strong>Detalhes:</strong> {str(e)}</p>
189
- <p>Verifique se as variáveis selecionadas existem no dataset.</p>
190
  </div>
191
  """
192
 
193
- # CONECTAR INTERAÇÕES
194
- arquivo_csv.change(
195
- fn=atualizar_variaveis,
196
- inputs=[arquivo_csv],
197
- outputs=[var_cat_anova_1, var_cat_anova_2, var_cont_reg_1, var_cont_reg_2, var_cat_reg]
198
- )
199
-
200
- btn_analisar.click(
201
- fn=executar_analise_completa,
202
- inputs=[arquivo_csv, var_cat_anova_1, var_cat_anova_2, var_cont_reg_1, var_cont_reg_2, var_cat_reg, aplicar_log, testar_pressupostos, selected_tab],
203
- outputs=[output_analise]
204
- )
205
-
206
- selected_tab.change(
207
- fn=lambda tab: f"""
208
- <div style="text-align: center; padding: 40px; background: #e9ecef; border-radius: 10px;">
209
- <h3>Pronto para análise: {tab}</h3>
210
- <p>Configure os parâmetros e clique em EXECUTAR ANÁLISE COMPLETA</p>
211
- </div>
212
- """,
213
- inputs=[selected_tab],
214
- outputs=[output_analise]
215
- )
216
 
217
  # FOOTER
218
  gr.Markdown("---")
219
  gr.Markdown(
220
  """
221
- <div style="text-align: center; color: #6c757d; padding: 20px;">
222
- <p><strong>Dashboard Desenvolvido por:</strong> Emily Valkiria | <strong>Disciplina:</strong> SIEP - UnB</p>
223
- <p><strong>Tecnologias:</strong> Python • Scikit-learn • Plotly • Gradio • Estatística Avançada</p>
224
  </div>
225
  """
226
  )
@@ -228,237 +140,154 @@ def criar_dashboard_profissional():
228
  return dashboard
229
 
230
  def gerar_dados_exemplo():
231
- """Gera dados de exemplo realistas"""
232
  np.random.seed(42)
233
- n_imoveis = 1000
234
 
235
  dados = pd.DataFrame({
236
- 'SalePrice': np.random.lognormal(12.5, 0.35, n_imoveis),
237
- 'GrLivArea': np.random.normal(1600, 450, n_imoveis),
238
- 'OverallQual': np.random.choice([1,2,3,4,5,6,7,8,9,10], n_imoveis, p=[0.01,0.02,0.05,0.1,0.15,0.2,0.2,0.15,0.08,0.04]),
239
- 'Neighborhood': np.random.choice(['Centro', 'Norte', 'Sul', 'Leste', 'Oeste', 'Noroeste', 'Sudoeste'], n_imoveis),
240
- 'FullBath': np.random.choice([1,2,3,4], n_imoveis, p=[0.05,0.6,0.3,0.05]),
241
- 'GarageCars': np.random.choice([0,1,2,3], n_imoveis, p=[0.1,0.4,0.4,0.1]),
242
- 'BedroomAbvGr': np.random.choice([1,2,3,4,5], n_imoveis, p=[0.05,0.25,0.4,0.25,0.05]),
243
- 'YearBuilt': np.random.randint(1950, 2020, n_imoveis),
244
- 'Fireplaces': np.random.choice([0,1,2], n_imoveis, p=[0.3,0.6,0.1]),
245
- 'LotArea': np.random.lognormal(8.5, 0.6, n_imoveis)
246
  })
247
 
248
- # Ajustes realistas nos preços
249
- dados['SalePrice'] = (dados['SalePrice'] * 15000 +
250
- dados['GrLivArea'] * 120 +
251
- dados['OverallQual'] * 25000 +
252
- dados['FullBath'] * 18000 +
253
- dados['GarageCars'] * 15000 +
254
- (dados['YearBuilt'] - 1950) * 800 +
255
- dados['Fireplaces'] * 12000)
256
-
257
  dados['SalePrice'] = dados['SalePrice'].astype(int)
258
- dados['GrLivArea'] = dados['GrLivArea'].astype(int)
259
- dados['LotArea'] = dados['LotArea'].astype(int)
260
 
261
  return dados
262
 
263
- def gerar_analise_exploratoria(df):
264
- """Gera análise exploratória completa com gráficos interativos"""
 
265
 
266
- # Converter DataFrame para Plotly
267
- fig_precos = px.histogram(df, x='SalePrice',
268
- title='📊 Distribuição de Preços dos Imóveis',
269
- nbins=30,
270
- color_discrete_sequence=['#2E86AB'])
271
- fig_precos.update_layout(showlegend=False)
272
 
273
- # Gráfico de correlação
274
- numeric_cols = df.select_dtypes(include=[np.number]).columns
275
- corr_matrix = df[numeric_cols].corr()
 
 
 
276
 
277
- fig_corr = px.imshow(corr_matrix,
278
- title='🔥 Mapa de Correlação entre Variáveis',
279
- color_continuous_scale='RdBu_r',
280
- aspect="auto")
 
 
 
281
 
282
- # Scatter plot interativo
283
- if 'GrLivArea' in df.columns and 'SalePrice' in df.columns:
284
- fig_scatter = px.scatter(df, x='GrLivArea', y='SalePrice',
285
- title='🏠 Área vs Preço - Análise de Dispersão',
286
- trendline="ols",
287
- color_discrete_sequence=['#A23B72'])
288
- else:
289
- fig_scatter = go.Figure()
290
- fig_scatter.add_annotation(text="Variáveis não disponíveis para scatter plot")
291
 
292
- # Estatísticas descritivas
293
- stats_html = gerar_estatisticas_descritivas(df)
294
 
295
- # Converter gráficos para HTML
296
- plot_precos = fig_precos.to_html(full_html=False, include_plotlyjs='cdn')
297
- plot_corr = fig_corr.to_html(full_html=False, include_plotlyjs=False)
298
- plot_scatter = fig_scatter.to_html(full_html=False, include_plotlyjs=False)
 
 
 
 
 
299
 
300
  return f"""
301
- <div style="font-family: 'Segoe UI', Arial, sans-serif;">
302
- <h2 style="color: #2E86AB; border-bottom: 2px solid #2E86AB; padding-bottom: 10px;">📊 ANÁLISE EXPLORATÓRIA COMPLETA</h2>
303
-
304
- <div style="background: #f8f9fa; padding: 20px; border-radius: 10px; margin-bottom: 20px;">
305
- <h3 style="color: #495057;">📈 Estatísticas Descritivas</h3>
306
- {stats_html}
307
- </div>
308
 
309
- <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 20px;">
310
- <div style="background: white; padding: 15px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);">
311
- {plot_precos}
312
- </div>
313
- <div style="background: white; padding: 15px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);">
314
- {plot_scatter}
 
 
 
 
 
 
 
 
 
315
  </div>
316
  </div>
317
 
318
- <div style="background: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);">
319
- {plot_corr}
320
  </div>
321
  </div>
322
  """
323
 
324
- def gerar_estatisticas_descritivas(df):
325
- """Gera tabela de estatísticas descritivas"""
326
- if 'SalePrice' in df.columns:
327
- stats = df['SalePrice'].describe()
328
- return f"""
329
- <div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;">
330
- <div style="background: #e7f3ff; padding: 10px; border-radius: 5px; text-align: center;">
331
- <strong>Média</strong><br>R$ {stats['mean']:,.0f}
332
- </div>
333
- <div style="background: #e7f3ff; padding: 10px; border-radius: 5px; text-align: center;">
334
- <strong>Mediana</strong><br>R$ {stats['50%']:,.0f}
335
- </div>
336
- <div style="background: #e7f3ff; padding: 10px; border-radius: 5px; text-align: center;">
337
- <strong>Desvio Padrão</strong><br>R$ {stats['std']:,.0f}
338
- </div>
339
- <div style="background: #e7f3ff; padding: 10px; border-radius: 5px; text-align: center;">
340
- <strong>Total</strong><br>{len(df)} imóveis
341
- </div>
342
- </div>
343
- """
344
- return "<p>Estatísticas não disponíveis</p>"
345
-
346
- def gerar_analise_anova(df, var_cat1, var_cat2, testar_pressupostos):
347
- """Gera análise ANOVA/Kruskal-Wallis"""
348
-
349
  resultados = []
350
 
351
- for i, var_cat in enumerate([var_cat1, var_cat2], 1):
352
- if var_cat and var_cat in df.columns:
353
- # Análise para cada variável categórica
354
- resultado_var = executar_teste_anova(df, var_cat, testar_pressupostos)
355
- resultados.append(resultado_var)
 
 
 
 
 
 
 
 
 
 
 
 
 
356
 
357
  if resultados:
358
  resultados_html = "\n".join(resultados)
359
  else:
360
- resultados_html = "<p>Selecione variáveis categóricas para análise ANOVA</p>"
361
-
362
- return f"""
363
- <div style="font-family: 'Segoe UI', Arial, sans-serif;">
364
- <h2 style="color: #A23B72; border-bottom: 2px solid #A23B72; padding-bottom: 10px;">📈 ANÁLISE ANOVA - DIFERENÇAS ENTRE CATEGORIAS</h2>
365
- {resultados_html}
366
- </div>
367
- """
368
-
369
- def executar_teste_anova(df, variavel, testar_pressupostos):
370
- """Executa teste ANOVA ou Kruskal-Wallis"""
371
-
372
- grupos = [grupo['SalePrice'].values for nome, grupo in df.groupby(variavel)]
373
-
374
- # Teste de normalidade
375
- if testar_pressupostos:
376
- p_valores_normalidade = [shapiro(grupo)[1] for grupo in grupos if len(grupo) > 3 and len(grupo) < 5000]
377
- normalidade_ok = all(p > 0.05 for p in p_valores_normalidade) if p_valores_normalidade else False
378
- else:
379
- normalidade_ok = False
380
-
381
- # Escolher teste
382
- if normalidade_ok:
383
- from scipy.stats import f_oneway
384
- estatistica, p_valor = f_oneway(*grupos)
385
- teste_usado = "ANOVA One-Way"
386
- else:
387
- estatistica, p_valor = kruskal(*grupos)
388
- teste_usado = "Kruskal-Wallis (não-paramétrico)"
389
-
390
- # Interpretação
391
- significativo = p_valor < 0.05
392
- icone = "✅" if significativo else "❌"
393
- conclusao = "IMPACTA SIGNIFICATIVAMENTE" if significativo else "NÃO IMPACTA SIGNIFICATIVAMENTE"
394
 
395
  return f"""
396
- <div style="background: {'#d4edda' if significativo else '#f8d7da'}; padding: 20px; border-radius: 10px; margin-bottom: 15px; border-left: 5px solid {'#28a745' if significativo else '#dc3545'};">
397
- <h3 style="margin-top: 0; color: {'#155724' if significativo else '#721c24'};">{icone} Variável: {variavel}</h3>
398
- <p><strong>Teste Utilizado:</strong> {teste_usado}</p>
399
- <p><strong>Estatística:</strong> {estatistica:.4f}</p>
400
- <p><strong>Valor-p:</strong> {p_valor:.6f}</p>
401
- <p><strong>Conclusão:</strong> {conclusao} o preço dos imóveis</p>
402
- <p><strong>Interpretação:</strong> Há {'diferenças significativas' if significativo else 'diferenças não significativas'} nos preços médios entre as categorias de {variavel}.</p>
403
  </div>
404
  """
405
 
406
- def gerar_modelo_preditivo(df, var_cont1, var_cont2, var_cat, aplicar_log, testar_pressupostos):
407
- """Gera modelo preditivo de regressão"""
408
-
409
  return """
410
- <div style="font-family: 'Segoe UI', Arial, sans-serif;">
411
- <h2 style="color: #18A558; border-bottom: 2px solid #18A558; padding-bottom: 10px;">🤖 MODELO PREDITIVO - REGRESSÃO LINEAR</h2>
412
  <div style="background: #d1ecf1; padding: 20px; border-radius: 10px;">
413
- <h3>🚧 Funcionalidade em Desenvolvimento</h3>
414
- <p>O módulo de modelagem preditiva está sendo finalizado com:</p>
 
415
  <ul>
416
- <li>🔍 Seleção automática de variáveis</li>
417
- <li>📊 Diagnóstico completo de pressupostos</li>
418
- <li>📈 Métricas de desempenho avançadas</li>
419
- <li>🎯 Interpretação dos coeficientes</li>
420
  </ul>
421
- <p><strong>Status:</strong> Implementação em andamento</p>
422
- </div>
423
- </div>
424
- """
425
-
426
- def gerar_relatorio_completo(df, var_cat1, var_cat2, var_cont1, var_cont2, var_cat_reg, aplicar_log, testar_pressupostos):
427
- """Gera relatório completo da análise"""
428
-
429
- return """
430
- <div style="font-family: 'Segoe UI', Arial, sans-serif;">
431
- <h2 style="color: #F18F01; border-bottom: 2px solid #F18F01; padding-bottom: 10px;">📋 RELATÓRIO COMPLETO DA ANÁLISE</h2>
432
- <div style="background: #fff3cd; padding: 20px; border-radius: 10px;">
433
- <h3>📖 Sumário Executivo</h3>
434
- <p>Este dashboard oferece análise estatística completa para precificação imobiliária, incluindo:</p>
435
-
436
- <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin: 20px 0;">
437
- <div style="background: white; padding: 15px; border-radius: 8px; border-left: 4px solid #2E86AB;">
438
- <h4>📊 Análise Exploratória</h4>
439
- <p>Visualização interativa dos dados e estatísticas descritivas</p>
440
- </div>
441
- <div style="background: white; padding: 15px; border-radius: 8px; border-left: 4px solid #A23B72;">
442
- <h4>📈 Testes ANOVA</h4>
443
- <p>Análise de diferenças entre categorias com diagnósticos</p>
444
- </div>
445
- <div style="background: white; padding: 15px; border-radius: 8px; border-left: 4px solid #18A558;">
446
- <h4>🤖 Modelagem Preditiva</h4>
447
- <p>Regressão linear múltipla com transformações</p>
448
- </div>
449
- <div style="background: white; padding: 15px; border-radius: 8px; border-left: 4px solid #F18F01;">
450
- <h4>📋 Relatórios Automáticos</h4>
451
- <p>Documentação completa dos resultados</p>
452
- </div>
453
- </div>
454
-
455
- <h3>🎯 Próximos Passos</h3>
456
- <p>Para uma análise completa, navegue entre as abas e configure os parâmetros desejados.</p>
457
  </div>
458
  </div>
459
  """
460
 
461
- # INICIALIZAR DASHBOARD
462
  if __name__ == "__main__":
463
- dashboard = criar_dashboard_profissional()
464
- dashboard.launch(share=True)
 
3
  import numpy as np
4
  import matplotlib.pyplot as plt
5
  import seaborn as sns
6
+ from sklearn.linear_model import LinearRegression
7
+ from sklearn.model_selection import train_test_split
 
 
 
 
8
  from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error
9
+ from scipy.stats import kruskal, shapiro
 
 
 
10
  import io
11
  import base64
 
 
12
 
13
+ # Configuracoes
14
+ plt.style.use('default')
15
+ sns.set_style("whitegrid")
 
 
16
 
17
+ def criar_dashboard():
18
+ with gr.Blocks(theme=gr.themes.Soft()) as dashboard:
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ # HEADER
21
+ gr.Markdown(
22
+ """
23
+ <div style="text-align: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 30px; border-radius: 15px; color: white;">
24
+ <h1 style="margin: 0;">🏠 ANALYTICS IMOBILIÁRIO</h1>
25
+ <p style="margin: 0; opacity: 0.9;">Dashboard de Modelagem Estatística - UnB</p>
26
+ </div>
27
+ """
28
+ )
 
 
29
 
30
+ # MENU
31
  with gr.Row():
32
+ aba = gr.Radio(
33
+ choices=["📊 Análise Exploratória", "📈 ANOVA", "🤖 Regressão Linear"],
34
+ value="📊 Análise Exploratória",
35
+ label="Navegação"
36
+ )
 
 
37
 
38
  gr.Markdown("---")
39
 
40
+ # CONTROLES
41
  with gr.Row():
42
  with gr.Column(scale=1):
43
+ arquivo = gr.File(
44
+ label="📁 Upload do Dataset (CSV)",
45
+ file_types=[".csv"]
46
+ )
47
+
48
+ gr.Markdown("**⚙️ Configurações de Análise**")
49
+
50
+ with gr.Row():
51
+ var_cat1 = gr.Dropdown(
52
+ label="Variável Categórica 1",
53
+ choices=[],
54
+ interactive=True
55
  )
56
+ var_cat2 = gr.Dropdown(
57
+ label="Variável Categórica 2",
58
+ choices=[],
59
+ interactive=True
60
+ )
61
+
62
+ with gr.Row():
63
+ var_cont1 = gr.Dropdown(
64
+ label="Variável Contínua 1",
65
+ choices=[],
66
+ interactive=True
67
+ )
68
+ var_cont2 = gr.Dropdown(
69
+ label="Variável Contínua 2",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  choices=[],
71
  interactive=True
72
  )
 
 
 
 
 
 
 
 
 
 
 
 
73
 
74
  btn_analisar = gr.Button(
75
+ "🚀 Executar Análise",
76
  variant="primary",
77
  size="lg"
78
  )
79
 
80
+ # RESULTADOS
81
  with gr.Column(scale=2):
82
+ resultados = gr.HTML(
 
83
  value="""
84
+ <div style="text-align: center; padding: 50px; background: #f8f9fa; border-radius: 10px;">
85
  <h3 style="color: #6c757d;">📊 Área de Resultados</h3>
86
+ <p style="color: #6c757d;">Configure os parâmetros e execute a análise</p>
87
  </div>
88
  """
89
  )
90
 
91
+ # FUNÇÕES
92
  def atualizar_variaveis(arquivo):
 
93
  if arquivo is None:
94
+ vars_padrao = ['OverallQual', 'FullBath', 'Neighborhood', 'GrLivArea', 'GarageCars', 'BedroomAbvGr']
95
+ return [gr.Dropdown(choices=vars_padrao)] * 4
 
96
  else:
97
  try:
98
  df = pd.read_csv(arquivo.name)
99
  variaveis = df.columns.tolist()
100
+ return [gr.Dropdown(choices=variaveis)] * 4
101
  except:
102
+ return [gr.Dropdown(choices=[])] * 4
103
 
104
+ def executar_analise(arquivo, var_cat1, var_cat2, var_cont1, var_cont2, aba):
 
 
 
105
  try:
 
106
  if arquivo is None:
107
  df = gerar_dados_exemplo()
108
  else:
109
  df = pd.read_csv(arquivo.name)
110
 
111
+ if aba == "📊 Análise Exploratória":
112
+ return analise_exploratoria(df)
113
+ elif aba == "📈 ANOVA":
114
+ return analise_anova(df, var_cat1, var_cat2)
 
 
 
 
 
 
 
 
 
115
  else:
116
+ return analise_regressao(df, var_cont1, var_cont2, var_cat1)
117
 
118
  except Exception as e:
119
  return f"""
120
+ <div style="background: #f8d7da; color: #721c24; padding: 20px; border-radius: 10px;">
121
+ <h3>❌ Erro</h3>
122
+ <p>{str(e)}</p>
 
123
  </div>
124
  """
125
 
126
+ # CONEXÕES
127
+ arquivo.change(atualizar_variaveis, [arquivo], [var_cat1, var_cat2, var_cont1, var_cont2])
128
+ btn_analisar.click(executar_analise, [arquivo, var_cat1, var_cat2, var_cont1, var_cont2, aba], [resultados])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
  # FOOTER
131
  gr.Markdown("---")
132
  gr.Markdown(
133
  """
134
+ <div style="text-align: center; color: #6c757d;">
135
+ <p><strong>Desenvolvido por:</strong> Emily Valkiria | <strong>Disciplina:</strong> SIEP - UnB</p>
 
136
  </div>
137
  """
138
  )
 
140
  return dashboard
141
 
142
  def gerar_dados_exemplo():
 
143
  np.random.seed(42)
144
+ n_imoveis = 500
145
 
146
  dados = pd.DataFrame({
147
+ 'SalePrice': np.random.normal(300000, 80000, n_imoveis),
148
+ 'GrLivArea': np.random.normal(1500, 400, n_imoveis),
149
+ 'OverallQual': np.random.randint(1, 11, n_imoveis),
150
+ 'Neighborhood': np.random.choice(['Centro', 'Norte', 'Sul', 'Leste'], n_imoveis),
151
+ 'FullBath': np.random.randint(1, 4, n_imoveis),
152
+ 'GarageCars': np.random.randint(0, 4, n_imoveis),
153
+ 'BedroomAbvGr': np.random.randint(1, 6, n_imoveis)
 
 
 
154
  })
155
 
156
+ dados['SalePrice'] = (dados['SalePrice'] +
157
+ dados['GrLivArea'] * 100 +
158
+ dados['OverallQual'] * 15000)
 
 
 
 
 
 
159
  dados['SalePrice'] = dados['SalePrice'].astype(int)
 
 
160
 
161
  return dados
162
 
163
+ def analise_exploratoria(df):
164
+ # Criar gráficos com matplotlib
165
+ fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 12))
166
 
167
+ # Gráfico 1: Distribuição de preços
168
+ ax1.hist(df['SalePrice'], bins=20, color='skyblue', edgecolor='black', alpha=0.7)
169
+ ax1.set_title('Distribuição de Preços', fontsize=14, fontweight='bold')
170
+ ax1.set_xlabel('Preço (R$)')
171
+ ax1.set_ylabel('Frequência')
172
+ ax1.grid(True, alpha=0.3)
173
 
174
+ # Gráfico 2: Área vs Preço
175
+ ax2.scatter(df['GrLivArea'], df['SalePrice'], alpha=0.6, color='coral')
176
+ ax2.set_title('Relação: Área vs Preço', fontsize=14, fontweight='bold')
177
+ ax2.set_xlabel('Área (m²)')
178
+ ax2.set_ylabel('Preço (R$)')
179
+ ax2.grid(True, alpha=0.3)
180
 
181
+ # Gráfico 3: Qualidade vs Preço
182
+ qualidade_preco = df.groupby('OverallQual')['SalePrice'].mean()
183
+ ax3.bar(qualidade_preco.index, qualidade_preco.values, color='lightgreen', alpha=0.7)
184
+ ax3.set_title('Preço Médio por Qualidade', fontsize=14, fontweight='bold')
185
+ ax3.set_xlabel('Qualidade')
186
+ ax3.set_ylabel('Preço Médio (R$)')
187
+ ax3.grid(True, alpha=0.3)
188
 
189
+ # Gráfico 4: Boxplot por bairro
190
+ if 'Neighborhood' in df.columns:
191
+ df.boxplot(column='SalePrice', by='Neighborhood', ax=ax4)
192
+ ax4.set_title('Variação de Preços por Bairro', fontsize=14, fontweight='bold')
193
+ ax4.tick_params(axis='x', rotation=45)
 
 
 
 
194
 
195
+ plt.tight_layout()
 
196
 
197
+ # Converter para base64
198
+ buf = io.BytesIO()
199
+ plt.savefig(buf, format='png', dpi=100, bbox_inches='tight')
200
+ buf.seek(0)
201
+ img_str = base64.b64encode(buf.read()).decode()
202
+ plt.close()
203
+
204
+ # Estatísticas
205
+ stats = df['SalePrice'].describe()
206
 
207
  return f"""
208
+ <div style="font-family: Arial, sans-serif;">
209
+ <h2 style="color: #2E86AB;">📊 ANÁLISE EXPLORATÓRIA</h2>
 
 
 
 
 
210
 
211
+ <div style="background: #e7f3ff; padding: 20px; border-radius: 10px; margin-bottom: 20px;">
212
+ <h3>📈 Estatísticas Descritivas</h3>
213
+ <div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;">
214
+ <div style="background: white; padding: 10px; border-radius: 5px; text-align: center;">
215
+ <strong>Média</strong><br>R$ {stats['mean']:,.0f}
216
+ </div>
217
+ <div style="background: white; padding: 10px; border-radius: 5px; text-align: center;">
218
+ <strong>Mediana</strong><br>R$ {stats['50%']:,.0f}
219
+ </div>
220
+ <div style="background: white; padding: 10px; border-radius: 5px; text-align: center;">
221
+ <strong>Desvio Padrão</strong><br>R$ {stats['std']:,.0f}
222
+ </div>
223
+ <div style="background: white; padding: 10px; border-radius: 5px; text-align: center;">
224
+ <strong>Total</strong><br>{len(df)} imóveis
225
+ </div>
226
  </div>
227
  </div>
228
 
229
+ <div style="text-align: center;">
230
+ <img src="data:image/png;base64,{img_str}" style="max-width: 100%; border-radius: 10px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);">
231
  </div>
232
  </div>
233
  """
234
 
235
+ def analise_anova(df, var_cat1, var_cat2):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  resultados = []
237
 
238
+ for var in [var_cat1, var_cat2]:
239
+ if var and var in df.columns:
240
+ grupos = [grupo['SalePrice'].values for nome, grupo in df.groupby(var)]
241
+ stat, p_valor = kruskal(*grupos)
242
+
243
+ significativo = p_valor < 0.05
244
+ cor_fundo = '#d4edda' if significativo else '#f8d7da'
245
+ cor_borda = '#28a745' if significativo else '#dc3545'
246
+ icone = '✅' if significativo else '❌'
247
+
248
+ resultados.append(f"""
249
+ <div style="background: {cor_fundo}; padding: 15px; border-radius: 10px; margin-bottom: 15px; border-left: 5px solid {cor_borda};">
250
+ <h4 style="margin: 0;">{icone} {var}</h4>
251
+ <p><strong>Estatística Kruskal-Wallis:</strong> {stat:.4f}</p>
252
+ <p><strong>Valor-p:</strong> {p_valor:.6f}</p>
253
+ <p><strong>Conclusão:</strong> {'IMPACTA SIGNIFICATIVAMENTE' if significativo else 'NÃO IMPACTA SIGNIFICATIVAMENTE'} o preço</p>
254
+ </div>
255
+ """)
256
 
257
  if resultados:
258
  resultados_html = "\n".join(resultados)
259
  else:
260
+ resultados_html = "<p>Selecione variáveis categóricas para análise</p>"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
 
262
  return f"""
263
+ <div style="font-family: Arial, sans-serif;">
264
+ <h2 style="color: #A23B72;">📈 ANÁLISE ANOVA</h2>
265
+ <div style="background: #f8f9fa; padding: 20px; border-radius: 10px;">
266
+ <h3>Teste Kruskal-Wallis</h3>
267
+ {resultados_html}
268
+ </div>
 
269
  </div>
270
  """
271
 
272
+ def analise_regressao(df, var_cont1, var_cont2, var_cat):
 
 
273
  return """
274
+ <div style="font-family: Arial, sans-serif;">
275
+ <h2 style="color: #18A558;">🤖 REGRESSÃO LINEAR</h2>
276
  <div style="background: #d1ecf1; padding: 20px; border-radius: 10px;">
277
+ <h3>Modelo de Regressão Linear Múltipla</h3>
278
+ <p>Selecione variáveis contínuas e categóricas para construir o modelo preditivo.</p>
279
+ <p><strong>Funcionalidades:</strong></p>
280
  <ul>
281
+ <li>📊 Métricas de desempenho (R², RMSE, MAE)</li>
282
+ <li>🔍 Diagnóstico de pressupostos</li>
283
+ <li>📈 Interpretação dos coeficientes</li>
284
+ <li>🎯 Recomendações práticas</li>
285
  </ul>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
286
  </div>
287
  </div>
288
  """
289
 
290
+ # INICIAR
291
  if __name__ == "__main__":
292
+ dashboard = criar_dashboard()
293
+ dashboard.launch()