Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -130,13 +130,13 @@ predictor = HousePricePredictor()
|
|
| 130 |
def load_data(file):
|
| 131 |
"""Função para carregar dados do arquivo"""
|
| 132 |
if file is None:
|
| 133 |
-
return "❌ Por favor, faça upload do arquivo CSV", None
|
| 134 |
|
| 135 |
success, message = predictor.load_and_prepare_data(file.name)
|
| 136 |
if success:
|
| 137 |
-
return message, gr.update(visible=True)
|
| 138 |
else:
|
| 139 |
-
return message, gr.update(visible=False)
|
| 140 |
|
| 141 |
def train_model_action():
|
| 142 |
"""Função para treinar o modelo"""
|
|
@@ -165,21 +165,12 @@ def train_model_action():
|
|
| 165 |
else:
|
| 166 |
return result, None, gr.update(visible=False)
|
| 167 |
|
| 168 |
-
def
|
| 169 |
-
"""Cria
|
| 170 |
-
if predictor.feature_names is None:
|
| 171 |
-
return
|
| 172 |
|
| 173 |
-
# Criar inputs para cada feature
|
| 174 |
inputs = []
|
| 175 |
-
default_values = {}
|
| 176 |
-
|
| 177 |
-
# Calcular valores médios para preenchimento automático
|
| 178 |
-
if predictor.df is not None:
|
| 179 |
-
for feature in predictor.feature_names:
|
| 180 |
-
mean_val = predictor.df[feature].mean()
|
| 181 |
-
default_values[feature] = mean_val
|
| 182 |
-
|
| 183 |
for feature in predictor.feature_names:
|
| 184 |
min_val = float(predictor.df[feature].min())
|
| 185 |
max_val = float(predictor.df[feature].max())
|
|
@@ -190,8 +181,7 @@ def create_prediction_interface(metrics_result):
|
|
| 190 |
label=feature,
|
| 191 |
value=mean_val,
|
| 192 |
minimum=min_val,
|
| 193 |
-
maximum=max_val
|
| 194 |
-
info=f"Range: {min_val:.1f} - {max_val:.1f}"
|
| 195 |
)
|
| 196 |
)
|
| 197 |
|
|
@@ -215,7 +205,7 @@ def predict_price_action(*feature_values):
|
|
| 215 |
# Criar visualização dos inputs
|
| 216 |
features_text = "**Características do Imóvel:**\n"
|
| 217 |
for feature, value in input_features.items():
|
| 218 |
-
features_text += f"\n• {feature}: {value}"
|
| 219 |
|
| 220 |
result_text = f"""
|
| 221 |
🏠 **Previsão de Preço**
|
|
@@ -247,6 +237,7 @@ def create_analysis_plots():
|
|
| 247 |
ax1.set_title('Distribuição dos Preços dos Imóveis')
|
| 248 |
ax1.legend()
|
| 249 |
ax1.grid(True, alpha=0.3)
|
|
|
|
| 250 |
|
| 251 |
# Gráfico 2: Correlações
|
| 252 |
numeric_cols = predictor.df.select_dtypes(include=[np.number]).columns.tolist()
|
|
@@ -266,22 +257,27 @@ def create_analysis_plots():
|
|
| 266 |
for i, (bar, val) in enumerate(zip(bars, top_corr.values)):
|
| 267 |
ax2.text(val + 0.01 if val > 0 else val - 0.01, i, f'{val:.3f}',
|
| 268 |
va='center', ha='left' if val > 0 else 'right', fontsize=9, fontweight='bold')
|
|
|
|
| 269 |
|
| 270 |
# Gráfico 3: Scatter plot da feature mais correlacionada
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
|
| 284 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 285 |
|
| 286 |
return fig1, fig2, fig3
|
| 287 |
|
|
@@ -289,8 +285,8 @@ def create_analysis_plots():
|
|
| 289 |
print(f"Erro ao criar gráficos: {e}")
|
| 290 |
return None, None, None
|
| 291 |
|
| 292 |
-
# Interface Gradio
|
| 293 |
-
with gr.Blocks(
|
| 294 |
gr.Markdown(
|
| 295 |
"""
|
| 296 |
# 🏠 Previsão de Preços de Imóveis - King County
|
|
@@ -322,7 +318,7 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Previsão de Preços de Imóveis")
|
|
| 322 |
load_btn.click(
|
| 323 |
load_data,
|
| 324 |
inputs=[file_input],
|
| 325 |
-
outputs=[load_status, train_btn]
|
| 326 |
)
|
| 327 |
|
| 328 |
train_btn.click(
|
|
@@ -347,23 +343,25 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Previsão de Preços de Imóveis")
|
|
| 347 |
|
| 348 |
with gr.Tab("🎯 Fazer Previsão"):
|
| 349 |
gr.Markdown("### Faça uma Previsão de Preço")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 350 |
|
| 351 |
with gr.Row():
|
| 352 |
-
|
| 353 |
-
|
| 354 |
-
|
| 355 |
-
|
| 356 |
-
|
| 357 |
-
prediction_output = gr.Markdown("Preencha os valores das características e clique em 'Prever Preço'")
|
| 358 |
-
price_display = gr.Number(
|
| 359 |
-
label="Preço Previsto ($)",
|
| 360 |
-
visible=False
|
| 361 |
-
)
|
| 362 |
|
| 363 |
-
# Atualizar interface
|
| 364 |
-
def update_prediction_interface(
|
| 365 |
-
|
| 366 |
-
|
|
|
|
|
|
|
|
|
|
| 367 |
|
| 368 |
metrics_json.change(
|
| 369 |
update_prediction_interface,
|
|
@@ -374,7 +372,7 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Previsão de Preços de Imóveis")
|
|
| 374 |
# Conectar botão de previsão
|
| 375 |
predict_btn.click(
|
| 376 |
predict_price_action,
|
| 377 |
-
inputs=
|
| 378 |
outputs=[prediction_output, price_display]
|
| 379 |
).then(
|
| 380 |
lambda: gr.update(visible=True),
|
|
@@ -418,9 +416,6 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Previsão de Preços de Imóveis")
|
|
| 418 |
"""
|
| 419 |
)
|
| 420 |
|
| 421 |
-
# Para executar localmente (descomente se quiser testar)
|
| 422 |
-
# if __name__ == "__main__":
|
| 423 |
-
# demo.launch(share=True)
|
| 424 |
-
|
| 425 |
# Para Hugging Face Spaces
|
| 426 |
-
|
|
|
|
|
|
| 130 |
def load_data(file):
|
| 131 |
"""Função para carregar dados do arquivo"""
|
| 132 |
if file is None:
|
| 133 |
+
return "❌ Por favor, faça upload do arquivo CSV", None, gr.update(visible=False)
|
| 134 |
|
| 135 |
success, message = predictor.load_and_prepare_data(file.name)
|
| 136 |
if success:
|
| 137 |
+
return message, gr.update(visible=True), gr.update(visible=True)
|
| 138 |
else:
|
| 139 |
+
return message, gr.update(visible=False), gr.update(visible=False)
|
| 140 |
|
| 141 |
def train_model_action():
|
| 142 |
"""Função para treinar o modelo"""
|
|
|
|
| 165 |
else:
|
| 166 |
return result, None, gr.update(visible=False)
|
| 167 |
|
| 168 |
+
def create_prediction_inputs():
|
| 169 |
+
"""Cria os inputs de previsão baseados nas features disponíveis"""
|
| 170 |
+
if predictor.feature_names is None or predictor.df is None:
|
| 171 |
+
return []
|
| 172 |
|
|
|
|
| 173 |
inputs = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
for feature in predictor.feature_names:
|
| 175 |
min_val = float(predictor.df[feature].min())
|
| 176 |
max_val = float(predictor.df[feature].max())
|
|
|
|
| 181 |
label=feature,
|
| 182 |
value=mean_val,
|
| 183 |
minimum=min_val,
|
| 184 |
+
maximum=max_val
|
|
|
|
| 185 |
)
|
| 186 |
)
|
| 187 |
|
|
|
|
| 205 |
# Criar visualização dos inputs
|
| 206 |
features_text = "**Características do Imóvel:**\n"
|
| 207 |
for feature, value in input_features.items():
|
| 208 |
+
features_text += f"\n• {feature}: {value:.2f}"
|
| 209 |
|
| 210 |
result_text = f"""
|
| 211 |
🏠 **Previsão de Preço**
|
|
|
|
| 237 |
ax1.set_title('Distribuição dos Preços dos Imóveis')
|
| 238 |
ax1.legend()
|
| 239 |
ax1.grid(True, alpha=0.3)
|
| 240 |
+
plt.tight_layout()
|
| 241 |
|
| 242 |
# Gráfico 2: Correlações
|
| 243 |
numeric_cols = predictor.df.select_dtypes(include=[np.number]).columns.tolist()
|
|
|
|
| 257 |
for i, (bar, val) in enumerate(zip(bars, top_corr.values)):
|
| 258 |
ax2.text(val + 0.01 if val > 0 else val - 0.01, i, f'{val:.3f}',
|
| 259 |
va='center', ha='left' if val > 0 else 'right', fontsize=9, fontweight='bold')
|
| 260 |
+
plt.tight_layout()
|
| 261 |
|
| 262 |
# Gráfico 3: Scatter plot da feature mais correlacionada
|
| 263 |
+
if len(top_corr) > 0:
|
| 264 |
+
most_correlated_feature = top_corr.index[0]
|
| 265 |
+
fig3, ax3 = plt.subplots(figsize=(10, 6))
|
| 266 |
+
ax3.scatter(predictor.df[most_correlated_feature], predictor.df['price'],
|
| 267 |
+
alpha=0.3, s=10, color='steelblue')
|
| 268 |
+
ax3.set_xlabel(most_correlated_feature)
|
| 269 |
+
ax3.set_ylabel('Preço ($)')
|
| 270 |
+
ax3.set_title(f'Preço vs {most_correlated_feature}\n(Corr: {top_corr.iloc[0]:.3f})')
|
| 271 |
+
ax3.grid(True, alpha=0.3)
|
| 272 |
+
|
| 273 |
+
# Adicionar linha de tendência
|
| 274 |
+
z = np.polyfit(predictor.df[most_correlated_feature], predictor.df['price'], 1)
|
| 275 |
+
p = np.poly1d(z)
|
| 276 |
+
ax3.plot(predictor.df[most_correlated_feature], p(predictor.df[most_correlated_feature]),
|
| 277 |
+
"r--", linewidth=2, alpha=0.8)
|
| 278 |
+
plt.tight_layout()
|
| 279 |
+
else:
|
| 280 |
+
fig3 = None
|
| 281 |
|
| 282 |
return fig1, fig2, fig3
|
| 283 |
|
|
|
|
| 285 |
print(f"Erro ao criar gráficos: {e}")
|
| 286 |
return None, None, None
|
| 287 |
|
| 288 |
+
# Interface Gradio corrigida
|
| 289 |
+
with gr.Blocks(title="Previsão de Preços de Imóveis - King County") as demo:
|
| 290 |
gr.Markdown(
|
| 291 |
"""
|
| 292 |
# 🏠 Previsão de Preços de Imóveis - King County
|
|
|
|
| 318 |
load_btn.click(
|
| 319 |
load_data,
|
| 320 |
inputs=[file_input],
|
| 321 |
+
outputs=[load_status, train_btn, train_btn]
|
| 322 |
)
|
| 323 |
|
| 324 |
train_btn.click(
|
|
|
|
| 343 |
|
| 344 |
with gr.Tab("🎯 Fazer Previsão"):
|
| 345 |
gr.Markdown("### Faça uma Previsão de Preço")
|
| 346 |
+
gr.Markdown("Primeiro carregue os dados e treine o modelo na aba 'Carregar Dados e Treinar'")
|
| 347 |
+
|
| 348 |
+
prediction_inputs = gr.Column()
|
| 349 |
+
predict_btn = gr.Button("💰 Prever Preço", variant="primary")
|
| 350 |
|
| 351 |
with gr.Row():
|
| 352 |
+
prediction_output = gr.Markdown("")
|
| 353 |
+
price_display = gr.Number(
|
| 354 |
+
label="Preço Previsto ($)",
|
| 355 |
+
visible=False
|
| 356 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 357 |
|
| 358 |
+
# Atualizar interface quando métricas estiverem disponíveis
|
| 359 |
+
def update_prediction_interface(metrics):
|
| 360 |
+
if metrics is None:
|
| 361 |
+
return []
|
| 362 |
+
|
| 363 |
+
inputs = create_prediction_inputs()
|
| 364 |
+
return inputs
|
| 365 |
|
| 366 |
metrics_json.change(
|
| 367 |
update_prediction_interface,
|
|
|
|
| 372 |
# Conectar botão de previsão
|
| 373 |
predict_btn.click(
|
| 374 |
predict_price_action,
|
| 375 |
+
inputs=prediction_inputs,
|
| 376 |
outputs=[prediction_output, price_display]
|
| 377 |
).then(
|
| 378 |
lambda: gr.update(visible=True),
|
|
|
|
| 416 |
"""
|
| 417 |
)
|
| 418 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 419 |
# Para Hugging Face Spaces
|
| 420 |
+
if __name__ == "__main__":
|
| 421 |
+
demo.launch()
|