mhdbbbbb's picture
Create app.py
07dcd48 verified
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("""
<style>
.main {
background-color: #f8f9fa;
}
.stMetric {
background-color: #ffffff;
padding: 15px;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.stAlert {
border-radius: 10px;
}
h1, h2, h3 {
color: #1e3a8a;
}
</style>
""", 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"""
<div style='text-align: center; color: gray;'>
Modèle entraîné sur {len(df)} transactions récentes | Précision du modèle (R2) : {score_r2:.2%}<br>
<i>AI Immo Predictor v1.0 - Propulsé par Machine Learning</i>
</div>
""", unsafe_allow_html=True)