# Fonction pour formater les nombres au style francais (espace comme separateur)
def fmt(n, decimals=0):
return f"{n:,.{decimals}f}".replace(",", " ")
print("=" * 70)
print(" VISUALISATION DES RELATIONS")
print(" Comprendre les liens entre features et prix")
print("=" * 70)
# =================================================================
# 1. CREATION DES GRAPHIQUES
# =================================================================
print("\n" + "-" * 40)
print("1. SCATTER PLOTS: FEATURES vs PRIX")
print("-" * 40)
print("""
Ces graphiques montrent comment le prix varie en fonction de chaque feature.
Un Random Forest peut capturer des relations non-lineaires!
""")
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# Surface vs Prix
axes[0].scatter(df['surface'], df['price'], alpha=0.6, color='#9B7AC4',
edgecolors='black', linewidth=0.5)
axes[0].set_xlabel('Surface (m2)', fontsize=12)
axes[0].set_ylabel('Prix (euros)', fontsize=12)
axes[0].set_title('Surface vs Prix', fontsize=14, fontweight='bold')
axes[0].grid(True, alpha=0.3)
# Ajouter une tendance
z = np.polyfit(df['surface'], df['price'], 1)
p = np.poly1d(z)
axes[0].plot(df['surface'].sort_values(), p(df['surface'].sort_values()),
'r--', linewidth=2, label=f'Tendance lineaire')
axes[0].legend()
# Nb rooms vs Prix
axes[1].scatter(df['nb_rooms'], df['price'], alpha=0.6, color='#C09CF0',
edgecolors='black', linewidth=0.5)
axes[1].set_xlabel('Nombre de pieces', fontsize=12)
axes[1].set_ylabel('Prix (euros)', fontsize=12)
axes[1].set_title('Nb Pieces vs Prix', fontsize=14, fontweight='bold')
axes[1].grid(True, alpha=0.3)
# Moyenne par nombre de pieces
mean_by_rooms = df.groupby('nb_rooms')['price'].mean()
axes[1].plot(mean_by_rooms.index, mean_by_rooms.values, 'ro-',
linewidth=2, markersize=8, label='Moyenne par nb pieces')
axes[1].legend()
plt.tight_layout()
plt.show()
# =================================================================
# 2. INTERPRETATION DES GRAPHIQUES
# =================================================================
print("\n" + "-" * 40)
print("2. INTERPRETATION")
print("-" * 40)
# Calculer le prix moyen par m2
prix_m2 = df['price'].mean() / df['surface'].mean()
print(f"""
GRAPHIQUE 1 - Surface vs Prix:
- Relation {'lineaire' if df['surface'].corr(df['price']) > 0.9 else 'globalement lineaire avec dispersion'}
- Prix moyen par m2: {fmt(prix_m2)} EUR/m2
- La surface est le principal determinant du prix
GRAPHIQUE 2 - Nb Pieces vs Prix:
- Tendance croissante avec le nombre de pieces
- Dispersion plus importante (a nb pieces egal, les prix varient)
- Relation moins directe qu'avec la surface
POUR LE RANDOM FOREST:
- Peut capturer les interactions entre surface et nb_rooms
- N'est pas limite aux relations lineaires
- Chaque arbre peut trouver des regles differentes
""")
# =================================================================
# 3. DISTRIBUTION DES PRIX
# =================================================================
print("\n" + "-" * 40)
print("3. DISTRIBUTION DES PRIX")
print("-" * 40)
plt.figure(figsize=(10, 5))
plt.hist(df['price'], bins=20, color='#9B7AC4', edgecolor='black', alpha=0.7)
plt.axvline(df['price'].mean(), color='#F7E64D', linewidth=2,
linestyle='--', label=f'Moyenne: {fmt(df["price"].mean())} EUR')
plt.axvline(df['price'].median(), color='#27ae60', linewidth=2,
linestyle='--', label=f'Mediane: {fmt(df["price"].median())} EUR')
plt.xlabel('Prix (euros)', fontsize=12)
plt.ylabel('Nombre de biens', fontsize=12)
plt.title('Distribution des prix immobiliers', fontsize=14, fontweight='bold')
plt.legend()
plt.grid(True, alpha=0.3, axis='y')
plt.show()
print(f"""
La distribution des prix permet de comprendre:
- Le marche couvre une gamme de {fmt(df['price'].min())} a {fmt(df['price'].max())} EUR
- La majorite des biens sont proches de la moyenne
- {'Distribution a peu pres symetrique' if abs(df['price'].mean() - df['price'].median()) < df['price'].std()*0.1 else 'Distribution legerement asymetrique'}
""")