import streamlit as st import pandas as pd import numpy as np import plotly.express as px import plotly.graph_objects as go from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_absolute_error, r2_score # Configuration de la page st.set_page_config( page_title="AI Immo Predictor", page_icon="🏠", layout="wide", initial_sidebar_state="expanded" ) # Style personnalisé st.markdown(""" """, unsafe_allow_html=True) # 1. DONNÉES donnees = { 'm2': [30, 50, 70, 90, 110, 130, 30, 50, 70, 50, 45, 85, 120, 60, 95, 55, 75, 100, 65, 80, 40, 90, 115, 140, 35, 60, 95, 105, 125, 150], 'dist': [1, 2, 3, 5, 8, 10, 15, 20, 25, 2, 4, 6, 12, 5, 8, 3, 4, 7, 2, 5, 1, 6, 9, 11, 18, 3, 7, 8, 10, 13], 'neuf': [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1], 'pieces': [1, 2, 3, 4, 4, 5, 1, 2, 3, 2, 2, 3, 4, 3, 4, 2, 3, 4, 3, 3, 1, 4, 5, 6, 1, 2, 4, 4, 5, 6], 'parking': [0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1], 'etage': [0, 2, 1, 3, 0, 1, 0, 1, 0, 4, 2, 3, 0, 2, 5, 3, 1, 2, 5, 4, 0, 3, 1, 0, 2, 4, 6, 2, 1, 3], 'balcon': [0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1], 'jardin': [0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1], 'ascenseur': [0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1], 'dpe': [4, 3, 4, 3, 5, 4, 6, 5, 6, 2, 4, 3, 1, 4, 3, 2, 4, 2, 1, 3, 5, 2, 3, 4, 6, 2, 3, 1, 3, 1], 'annee': [1985, 2000, 1995, 2005, 1980, 1990, 1975, 1988, 1970, 2020, 1998, 2008, 2022, 2002, 2010, 2018, 1992, 2015, 2021, 2005, 1982, 2012, 2003, 1995, 1978, 2019, 2011, 2023, 2007, 2024], 'etat': [2, 2, 2, 2, 1, 2, 1, 1, 1, 3, 2, 2, 3, 2, 2, 3, 2, 3, 3, 2, 1, 3, 2, 2, 1, 3, 2, 3, 2, 3], 'prix': [180000, 275000, 362000, 418000, 485000, 515000, 115000, 182000, 238000, 315000, 220000, 380000, 540000, 290000, 430000, 298000, 355000, 475000, 325000, 395000, 195000, 445000, 520000, 580000, 145000, 310000, 460000, 495000, 535000, 625000] } df = pd.DataFrame(donnees) # 2. ENTRAÎNEMENT DU MODÈLE X = df[['m2', 'dist', 'neuf', 'pieces', 'parking', 'etage', 'balcon', 'jardin', 'ascenseur', 'dpe', 'annee', 'etat']] y = df['prix'] ia = LinearRegression() ia.fit(X, y) predictions = ia.predict(X) erreur = mean_absolute_error(y, predictions) score_r2 = r2_score(y, predictions) # INTERFACE UTILISATEUR st.title("🏠 AI Immo Predictor") st.markdown("### L'intelligence artificielle au service de votre investissement") # Barre latérale pour les entrées with st.sidebar: st.header("📍 Caractéristiques du Bien") col1, col2 = st.columns(2) with col1: s = st.number_input("Surface (m2)", min_value=10, max_value=500, value=75) p = st.number_input("Pièces", min_value=1, max_value=20, value=3) with col2: d = st.number_input("Distance centre (km)", min_value=0.0, max_value=100.0, value=5.0) etg = st.number_input("Étage", min_value=0, max_value=50, value=2) col3, col4 = st.columns(2) with col3: n = st.selectbox("Neuf ?", ["NON", "OUI"]) park = st.selectbox("Parking ?", ["OUI", "NON"]) balc = st.selectbox("Balcon ?", ["OUI", "NON"]) with col4: jard = st.selectbox("Jardin ?", ["NON", "OUI"]) asc = st.selectbox("Ascenseur ?", ["OUI", "NON"]) etat_input = st.slider("État (1=Rénover, 3=Excellent)", 1, 3, 2) dpe_input = st.slider("DPE (1=A, 7=G)", 1, 7, 3) annee_input = st.number_input("Année de construction", 1900, 2025, 2010) st.divider() prix_voulu = st.number_input("Prix affiché (euros)", min_value=0, value=350000, step=5000) # Conversion des entrées code_neuf = 1 if n == "OUI" else 0 parking = 1 if park == "OUI" else 0 balcon = 1 if balc == "OUI" else 0 jardin = 1 if jard == "OUI" else 0 ascenseur = 1 if asc == "OUI" else 0 # Prédiction entree = np.array([[s, d, code_neuf, p, parking, etg, balcon, jardin, ascenseur, dpe_input, annee_input, etat_input]]) estimation = ia.predict(entree)[0] prix_min = estimation - erreur prix_max = estimation + erreur # AFFICHAGE DES RÉSULTATS col_res1, col_res2, col_res3 = st.columns(3) with col_res1: st.metric("Estimation IA", f"{estimation:,.0f} €") with col_res2: ecart = ((prix_voulu - estimation) / estimation) * 100 st.metric("Écart Marché", f"{ecart:+.1f} %", delta=-ecart, delta_color="inverse") with col_res3: st.metric("Marge d'erreur", f"± {erreur:,.0f} €") # Verdict st.divider() if prix_voulu < (estimation - erreur): st.success(f"### 🔥 EXCELLENTE AFFAIRE !\nVous économisez environ **{estimation - prix_voulu:,.0f} €** par rapport au marché.") st.balloons() elif prix_voulu > (estimation + erreur): st.error(f"### ⚠️ TROP CHER !\nCe bien est surévalué d'environ **{prix_voulu - estimation:,.0f} €**.") else: st.info("### ✅ PRIX CORRECT\nLe prix est parfaitement aligné avec les tendances actuelles du marché.") # ANALYSES VISUELLES POUR CONVAINCRE st.header("📊 Analyses Détaillées") tab1, tab2, tab3 = st.tabs(["Analyse de Prix", "Influence des Critères", "Données du Marché"]) with tab1: # Graphique de la fourchette de prix fig_range = go.Figure() fig_range.add_trace(go.Bar( name='Estimation IA', x=['Prix (€)'], y=[estimation], error_y=dict(type='data', array=[erreur], visible=True), marker_color='#1e3a8a' )) fig_range.add_trace(go.Scatter( name='Prix Vendeur', x=['Prix (€)'], y=[prix_voulu], mode='markers', marker=dict(color='red', size=15, symbol='star') )) fig_range.update_layout(title="Comparaison Estimation vs Prix Vendeur", showlegend=True) st.plotly_chart(fig_range, use_container_width=True) with tab2: # Importance des coefficients carac_noms = ['Surface', 'Distance', 'Neuf', 'Pièces', 'Parking', 'Étage', 'Balcon', 'Jardin', 'Ascenseur', 'DPE', 'Année', 'État'] coefs = ia.coef_ df_coef = pd.DataFrame({'Critère': carac_noms, 'Impact sur le prix (€)': coefs}) df_coef = df_coef.sort_values(by='Impact sur le prix (€)', ascending=True) fig_coef = px.bar(df_coef, x='Impact sur le prix (€)', y='Critère', orientation='h', title="Quels critères influencent le plus le prix ?", color='Impact sur le prix (€)', color_continuous_scale='RdYlGn') st.plotly_chart(fig_coef, use_container_width=True) with tab3: # Corrélation Surface / Prix fig_scatter = px.scatter(df, x='m2', y='prix', color='dist', size='prix', hover_data=['annee', 'pieces'], title="Distribution des prix selon la surface et la distance", labels={'m2': 'Surface (m2)', 'prix': 'Prix (€)', 'dist': 'Distance (km)'}, color_continuous_scale='Viridis') st.plotly_chart(fig_scatter, use_container_width=True) # Footer st.divider() st.markdown(f"""
Modèle entraîné sur {len(df)} transactions récentes | Précision du modèle (R2) : {score_r2:.2%}
AI Immo Predictor v1.0 - Propulsé par Machine Learning
""", unsafe_allow_html=True)