Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import pickle | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| import seaborn as sns | |
| import os | |
| os.makedirs('plots', exist_ok=True) | |
| print("Chargement du modèle...") | |
| with open('model.pkl', 'rb') as f: | |
| model = pickle.load(f) | |
| with open('scaler.pkl', 'rb') as f: | |
| scaler = pickle.load(f) | |
| with open('feature_names.pkl', 'rb') as f: | |
| feature_names = pickle.load(f) | |
| print("✓ Modèle chargé avec succès!") | |
| def plot_feature_importance(): | |
| """Visualise l'importance des features du modèle""" | |
| importances = model.feature_importances_ | |
| indices = np.argsort(importances)[::-1] | |
| plt.figure(figsize=(10, 6)) | |
| plt.title('Importance des Features', fontsize=16, fontweight='bold') | |
| plt.bar(range(len(importances)), importances[indices], color='steelblue') | |
| plt.xticks(range(len(importances)), | |
| [feature_names[i] for i in indices], | |
| rotation=45, ha='right') | |
| plt.ylabel('Importance', fontsize=12) | |
| plt.xlabel('Features', fontsize=12) | |
| plt.tight_layout() | |
| filepath = 'plots/feature_importance.png' | |
| plt.savefig(filepath, dpi=100, bbox_inches='tight') | |
| plt.close() | |
| return filepath | |
| def plot_input_summary(square_feet, bedrooms, bathrooms, age_years, | |
| lot_size, garage_spaces, neighborhood_score): | |
| """Visualise un résumé des inputs utilisateur""" | |
| values = [square_feet, bedrooms, bathrooms, age_years, | |
| lot_size, garage_spaces, neighborhood_score] | |
| fig, ax = plt.subplots(figsize=(10, 6)) | |
| colors = plt.cm.viridis(np.linspace(0.3, 0.9, len(feature_names))) | |
| bars = ax.barh(feature_names, values, color=colors) | |
| ax.set_xlabel('Valeur', fontsize=12, fontweight='bold') | |
| ax.set_title('Résumé de Votre Propriété', fontsize=16, fontweight='bold') | |
| ax.grid(axis='x', alpha=0.3, linestyle='--') | |
| for bar, value in zip(bars, values): | |
| width = bar.get_width() | |
| ax.text(width, bar.get_y() + bar.get_height()/2, | |
| f' {value:,.0f}', | |
| ha='left', va='center', fontsize=10, fontweight='bold') | |
| plt.tight_layout() | |
| filepath = 'plots/input_summary.png' | |
| plt.savefig(filepath, dpi=100, bbox_inches='tight') | |
| plt.close() | |
| return filepath | |
| def plot_prediction_with_confidence(predicted_price, lower_bound, upper_bound): | |
| """Visualise la prédiction avec l'intervalle de confiance""" | |
| fig, ax = plt.subplots(figsize=(10, 6)) | |
| ax.barh(['Prix Prédit'], [predicted_price], color='#2ecc71', | |
| alpha=0.8, height=0.5, label='Prédiction') | |
| ax.barh(['Prix Prédit'], [upper_bound - lower_bound], | |
| left=lower_bound, color='#3498db', alpha=0.3, | |
| height=0.5, label='Intervalle de confiance 95%') | |
| ax.axvline(lower_bound, color='red', linestyle='--', linewidth=2, alpha=0.7) | |
| ax.axvline(upper_bound, color='red', linestyle='--', linewidth=2, alpha=0.7) | |
| ax.set_xlabel('Prix ($)', fontsize=12, fontweight='bold') | |
| ax.set_title('Prédiction du Prix avec Intervalle de Confiance (95%)', | |
| fontsize=16, fontweight='bold') | |
| ax.legend(loc='upper right') | |
| ax.grid(axis='x', alpha=0.3, linestyle='--') | |
| ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f'${x:,.0f}')) | |
| ax.text(predicted_price, 0, f'${predicted_price:,.0f}', | |
| ha='center', va='bottom', fontsize=12, fontweight='bold', color='green') | |
| ax.text(lower_bound, 0.25, f'${lower_bound:,.0f}', | |
| ha='right', va='center', fontsize=10, color='red') | |
| ax.text(upper_bound, 0.25, f'${upper_bound:,.0f}', | |
| ha='left', va='center', fontsize=10, color='red') | |
| plt.tight_layout() | |
| filepath = 'plots/prediction_confidence.png' | |
| plt.savefig(filepath, dpi=100, bbox_inches='tight') | |
| plt.close() | |
| return filepath | |
| def predict_price(square_feet, bedrooms, bathrooms, age_years, | |
| lot_size, garage_spaces, neighborhood_score): | |
| """Prédit le prix et génère toutes les visualisations""" | |
| input_data = np.array([[square_feet, bedrooms, bathrooms, age_years, | |
| lot_size, garage_spaces, neighborhood_score]]) | |
| input_scaled = scaler.transform(input_data) | |
| predicted_price = model.predict(input_scaled)[0] | |
| tree_predictions = np.array([tree.predict(input_scaled)[0] | |
| for tree in model.estimators_]) | |
| std_dev = np.std(tree_predictions) | |
| confidence_interval = 1.96 * std_dev | |
| lower_bound = predicted_price - confidence_interval | |
| upper_bound = predicted_price + confidence_interval | |
| plot1 = plot_feature_importance() | |
| plot2 = plot_input_summary(square_feet, bedrooms, bathrooms, age_years, | |
| lot_size, garage_spaces, neighborhood_score) | |
| plot3 = plot_prediction_with_confidence(predicted_price, lower_bound, upper_bound) | |
| result_text = f""" | |
| **PRÉDICTION DU PRIX IMMOBILIER** | |
| **Prix Prédit:** ${predicted_price:,.2f} | |
| **Intervalle de Confiance (95%):** | |
| - Minimum: ${lower_bound:,.2f} | |
| - Maximum: ${upper_bound:,.2f} | |
| - Marge: ±${confidence_interval:,.2f} | |
| """ | |
| return result_text, plot1, plot2, plot3 | |
| # Créer l'interface Gradio | |
| with gr.Blocks(theme=gr.themes.Soft(), title="Prédiction Prix Immobilier") as demo: | |
| gr.Markdown( | |
| """ | |
| # Prédicteur de Prix Immobilier | |
| ### Application ML avec Random Forest Regressor | |
| Entrez les caractéristiques de votre propriété pour obtenir une estimation de prix. | |
| """ | |
| ) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| gr.Markdown("### Caractéristiques de la Propriété") | |
| square_feet = gr.Slider( | |
| minimum=800, maximum=4000, value=2000, step=50, | |
| label="Surface (pieds carrés)" | |
| ) | |
| bedrooms = gr.Slider( | |
| minimum=1, maximum=5, value=3, step=1, | |
| label="Nombre de chambres" | |
| ) | |
| bathrooms = gr.Slider( | |
| minimum=1, maximum=3, value=2, step=1, | |
| label="Nombre de salles de bain" | |
| ) | |
| age_years = gr.Slider( | |
| minimum=0, maximum=50, value=10, step=1, | |
| label="Âge de la maison (années)" | |
| ) | |
| lot_size = gr.Slider( | |
| minimum=2000, maximum=15000, value=8000, step=500, | |
| label="Taille du terrain (pieds carrés)" | |
| ) | |
| garage_spaces = gr.Slider( | |
| minimum=0, maximum=3, value=2, step=1, | |
| label="Places de garage" | |
| ) | |
| neighborhood_score = gr.Slider( | |
| minimum=1, maximum=10, value=7, step=1, | |
| label="Score du quartier (1-10)" | |
| ) | |
| predict_btn = gr.Button("🔮 Prédire le Prix", variant="primary", size="lg") | |
| with gr.Column(scale=2): | |
| gr.Markdown("### 💡 Résultats de la Prédiction") | |
| output_text = gr.Markdown() | |
| with gr.Row(): | |
| plot_importance = gr.Image(label="Importance des Features") | |
| plot_summary = gr.Image(label="Résumé de Votre Propriété") | |
| plot_confidence = gr.Image(label="Prédiction avec Intervalle de Confiance") | |
| predict_btn.click( | |
| fn=predict_price, | |
| inputs=[square_feet, bedrooms, bathrooms, age_years, | |
| lot_size, garage_spaces, neighborhood_score], | |
| outputs=[output_text, plot_importance, plot_summary, plot_confidence] | |
| ) | |
| gr.Markdown( | |
| """ | |
| --- | |
| **Note:** Ce modèle a été entraîné sur 1000 propriétés synthétiques. | |
| L'intervalle de confiance représente la plage de prix probable à 95%. | |
| """ | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch(server_name="0.0.0.0", server_port=7860, share=True) | |