Vediamo un esempio completo passo-passo. Useremo dati realistici per capire ogni concetto.
🚫 COPIA BLOCCATA
# REGRESSIONE MULTIPLA COMPLETA - TUTTO SPIEGATO PASSO PASSO
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.preprocessing import StandardScaler
print("🏠 REGRESSIONE MULTIPLA - PREZZI CASE (TUTTO SPIEGATO)")
print("=" * 80)
print("\n🎯 OBIETTIVO: Predire il prezzo di una casa usando PIÙ informazioni insieme")
print("=" * 80)
# ------------------------------------------------------------
# PASSO 1: CREIAMO DATI REALISTICI (FACILI DA CAPIRE)
# ------------------------------------------------------------
print("\n\n📝 PASSO 1: CREIAMO DATI DI ESEMPIO")
print("-" * 40)
np.random.seed(42) # Per risultati riproducibili
n_case = 200 # 200 case nel nostro dataset
print("Creiamo 200 case con queste caratteristiche:")
# 1. METRATURA (in metri quadri)
# Case normali: tra 80 e 200 m²
metratura = np.random.uniform(80, 200, n_case)
print(f"• Metratura: {metratura.min():.0f} - {metratura.max():.0f} m² (media: {metratura.mean():.0f} m²)")
# 2. NUMERO DI CAMERE
# Case normali: tra 2 e 6 camere
camere = np.random.randint(2, 7, n_case)
print(f"• Camere: {camere.min()} - {camere.max()} (media: {camere.mean():.1f})")
# 3. ETÀ DELLA CASA (in anni)
# Case tra 0 e 50 anni
eta = np.random.uniform(0, 50, n_case)
print(f"• Età: {eta.min():.0f} - {eta.max():.0f} anni (media: {eta.mean():.0f} anni)")
# 4. DISTANZA DAL CENTRO (in km)
# Case tra 1 e 15 km dal centro
distanza = np.random.uniform(1, 15, n_case)
print(f"• Distanza centro: {distanza.min():.0f} - {distanza.max():.0f} km (media: {distanza.mean():.1f} km)")
# ------------------------------------------------------------
# PASSO 2: CALCOLIAMO I PREZZI REALI (CON LOGICA SEMPLICE)
# ------------------------------------------------------------
print("\n\n📝 PASSO 2: CALCOLIAMO I PREZZI REALI")
print("-" * 40)
print("Usiamo una formula semplice per calcolare il prezzo di ogni casa:")
print("Prezzo = (2000 × Metratura) + (30000 × Camere) - (1000 × Età) - (5000 × Distanza) + Rumore")
# Formula del prezzo (facile da capire)
prezzo_base = (
2000 * metratura + # Ogni m² vale 2000€
30000 * camere + # Ogni camera vale 30000€
-1000 * eta + # Ogni anno riduce il valore di 1000€
-5000 * distanza + # Ogni km dal centro riduce di 5000€
np.random.normal(0, 20000, n_case) # Rumore (variazioni casuali)
)
# Assicuriamoci che i prezzi siano realistici (100k - 800k €)
prezzo = np.clip(prezzo_base, 100000, 800000)
print(f"\n💰 PREZZI FINALI:")
print(f"Prezzo minimo: €{prezzo.min():,.0f}")
print(f"Prezzo massimo: €{prezzo.max():,.0f}")
print(f"Prezzo medio: €{prezzo.mean():,.0f}")
# ------------------------------------------------------------
# PASSO 3: CREIAMO IL DATAFRAME (TABELLA DEI DATI)
# ------------------------------------------------------------
print("\n\n📝 PASSO 3: ORGANIZZIAMO I DATI IN UNA TABELLA")
print("-" * 40)
df_case = pd.DataFrame({
'Metratura_m2': metratura,
'Camere': camere,
'Eta_anni': eta,
'DistanzaCentro_km': distanza,
'Prezzo_€': prezzo
})
print("📊 LA NOSTRA TABELLA DATI (prime 8 case):")
print(df_case.head(8).round(0))
print(f"\n📈 DIMENSIONI: {df_case.shape[0]} righe (case) × {df_case.shape[1]} colonne (caratteristiche)")
# ------------------------------------------------------------
# PASSO 4: ANALIZZIAMO LE RELAZIONI TRA I DATI
# ------------------------------------------------------------
print("\n\n📝 PASSO 4: VEDIAMO COME LE CARATTERISTICHE SI RELAZIONANO")
print("-" * 40)
print("🎯 CORRELAZIONI (quanto le cose vanno insieme):")
correlazioni = df_case.corr() # Calcola correlazioni
print(correlazioni.round(2)) # Arrotonda a 2 decimali
print("\n📊 INTERPRETAZIONE:")
print("• Prezzo vs Metratura: {:.2f} (forte positiva)".format(correlazioni.loc['Prezzo_€', 'Metratura_m2']))
print("• Prezzo vs Camere: {:.2f} (media positiva)".format(correlazioni.loc['Prezzo_€', 'Camere']))
print("• Prezzo vs Età: {:.2f} (media negativa)".format(correlazioni.loc['Prezzo_€', 'Eta_anni']))
print("• Prezzo vs Distanza: {:.2f} (media negativa)".format(correlazioni.loc['Prezzo_€', 'DistanzaCentro_km']))
print("\n📈 SU GOOGLE COLAB, SCOMMENTA PER VEDERE I GRAFICI:")
"""
# Grafico 1: Prezzo vs Metratura
plt.figure(figsize=(10, 6))
plt.scatter(df_case['Metratura_m2'], df_case['Prezzo_€'], alpha=0.6)
plt.title('Prezzo vs Metratura')
plt.xlabel('Metratura (m²)')
plt.ylabel('Prezzo (€)')
plt.grid(True, alpha=0.3)
plt.show()
# Grafico 2: Matrice di correlazione
plt.figure(figsize=(8, 6))
sns.heatmap(correlazioni, annot=True, cmap='coolwarm', center=0, fmt='.2f')
plt.title('Come le caratteristiche si influenzano a vicenda')
plt.show()
"""
# ------------------------------------------------------------
# PASSO 5: PREPARIAMO I DATI PER IL MACHINE LEARNING
# ------------------------------------------------------------
print("\n\n📝 PASSO 5: PREPARIAMO I DATI PER L'ANALISI")
print("-" * 40)
print("Dividiamo i dati in due parti:")
print("1. TRAINING (80%): Per insegnare al modello")
print("2. TEST (20%): Per verificare se ha imparato bene")
# Caratteristiche (X) e Prezzo da predire (y)
X = df_case[['Metratura_m2', 'Camere', 'Eta_anni', 'DistanzaCentro_km']]
y = df_case['Prezzo_€']
print(f"\n📊 CARATTERISTICHE (X): {X.shape[0]} case × {X.shape[1]} caratteristiche")
print(f"🎯 PREZZO DA PREDIRE (y): {len(y)} valori")
# Divisione training/test
X_train, X_test, y_train, y_test = train_test_split(
X, y,
test_size=0.2, # 20% per test
random_state=42 # Per risultati riproducibili
)
print(f"\n✅ DIVISIONE COMPLETATA:")
print(f"Case per training: {X_train.shape[0]} ({X_train.shape[0]/len(X)*100:.0f}%)")
print(f"Case per test: {X_test.shape[0]} ({X_test.shape[0]/len(X)*100:.0f}%)")
# ------------------------------------------------------------
# PASSO 6: STANDARDIZZAZIONE (MOLTO IMPORTANTE!)
# ------------------------------------------------------------
print("\n\n📝 PASSO 6: STANDARDIZZIAMO LE CARATTERISTICHE")
print("-" * 40)
print("Perché standardizzare? Perché le caratteristiche hanno scale diverse:")
print("• Metratura: 80-200 m²")
print("• Camere: 2-6 (solo numeri interi)")
print("• Età: 0-50 anni")
print("• Distanza: 1-15 km")
print("\n🎯 Standardizziamo tutto su una scala comune (media=0, deviazione=1)")
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
print("✅ Standardizzazione completata!")
print(f"Media dopo standardizzazione: {X_train_scaled.mean():.2f} (dovrebbe essere circa 0)")
print(f"Deviazione standard: {X_train_scaled.std():.2f} (dovrebbe essere circa 1)")
# ------------------------------------------------------------
# PASSO 7: CREIAMO E ALLENIAMO IL MODELLO
# ------------------------------------------------------------
print("\n\n📝 PASSO 7: CREIAMO IL MODELLO DI REGRESSIONE MULTIPLA")
print("-" * 40)
print("Creiamo il modello...")
model = LinearRegression()
print("Alleniamo il modello con i dati di training...")
model.fit(X_train_scaled, y_train)
print("✅ Modello addestrato con successo!")
print("\n🎯 COSA HA IMPARATO IL MODELLO? (Coefficienti β):")
# Mostriamo i coefficienti in modo chiaro
caratteristiche = ['Metratura', 'Camere', 'Età', 'Distanza Centro']
print("\nPer ogni caratteristica, il modello ha imparato questo peso (β):")
for i, (caratteristica, coef) in enumerate(zip(caratteristiche, model.coef_)):
segno = "+" if coef > 0 else ""
print(f"• {caratteristica:15} : {segno}{coef:,.0f} €")
print(f"\n📐 PREZZO BASE (quando tutto è zero): {model.intercept_:,.0f} €")
print("\n📖 COME INTERPRETARE I COEFFICIENTI:")
print("Per ogni aumento di 1 deviazione standard...")
print("1. Metratura: +{:,}€ al prezzo".format(int(model.coef_[0])))
print("2. Camere: +{:,}€ al prezzo".format(int(model.coef_[1])))
print("3. Età: {:,}€ al prezzo (negativo = riduce il valore)".format(int(model.coef_[2])))
print("4. Distanza Centro: {:,}€ al prezzo (negativo = riduce il valore)".format(int(model.coef_[3])))
# ------------------------------------------------------------
# PASSO 8: FACCIAMO PREVISIONI E VERIFICHIAMO
# ------------------------------------------------------------
print("\n\n📝 PASSO 8: FACCIAMO PREVISIONI E VERIFICHIAMO")
print("-" * 40)
print("Usiamo il modello per predire i prezzi delle case di test...")
y_pred = model.predict(X_test_scaled)
print("✅ Previsioni completate!")
print(f"\n📊 CONFRONTO PRIME 5 CASE DI TEST:")
# Confronto per le prime 5 case
confronto = pd.DataFrame({
'Prezzo Reale': y_test.values[:5],
'Prezzo Predetto': y_pred[:5],
'Differenza': y_test.values[:5] - y_pred[:5]
}).round(0)
print(confronto)
print(f"\n📈 ERRORI MEDI:")
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
print(f"• Errore quadratico medio: {mse:,.0f}")
print(f"• Errore medio: €{rmse:,.0f}")
print(f"• Errore percentuale medio: {(rmse/y_test.mean()*100):.1f}%")
# ------------------------------------------------------------
# PASSO 9: VALUTIAMO LA BONTÀ DEL MODELLO
# ------------------------------------------------------------
print("\n\n📝 PASSO 9: VALUTIAMO QUANTO È BUONO IL MODELLO")
print("-" * 40)
# Calcoliamo R² (coefficiente di determinazione)
r2 = r2_score(y_test, y_pred)
print(f"🎯 R² SCORE: {r2:.3f}")
print(f"\n📊 COSA SIGNIFICA R² = {r2:.3f} ?")
print(f"Il nostro modello spiega il {r2*100:.1f}% della variazione nei prezzi delle case.")
print("Più è vicino a 1, migliore è il modello.")
if r2 > 0.8:
print("✅ OTTIMO! Il modello spiega molto bene i prezzi.")
elif r2 > 0.6:
print("⚠️ BUONO, ma potremmo migliorare aggiungendo più caratteristiche.")
else:
print("❌ POTREMMO FARE MEGLIO. Forse ci mancano caratteristiche importanti.")
print("\n📈 SU GOOGLE COLAB, SCOMMENTA PER VEDERE IL CONFRONTO:")
"""
# Grafico Prezzo Reale vs Predetto
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.6)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
plt.xlabel('Prezzo Reale (€)')
plt.ylabel('Prezzo Predetto (€)')
plt.title('Confronto: Prezzi Reali vs Predetti')
plt.grid(True, alpha=0.3)
plt.show()
# Grafico errori
errori = y_test - y_pred
plt.figure(figsize=(10, 6))
plt.hist(errori, bins=30, edgecolor='black', alpha=0.7)
plt.axvline(x=0, color='red', linestyle='--', lw=2)
plt.xlabel('Errore (Prezzo Reale - Predetto)')
plt.ylabel('Numero di Case')
plt.title('Distribuzione degli Errori')
plt.grid(True, alpha=0.3)
plt.show()
"""
# ------------------------------------------------------------
# PASSO 10: FACCIAMO PREVISIONI SU NUOVE CASE
# ------------------------------------------------------------
print("\n\n📝 PASSO 10: USIAMO IL MODELLO PER NUOVE CASE")
print("-" * 40)
print("Immaginiamo di avere 3 nuove case da valutare:")
nuove_case = pd.DataFrame({
'Metratura_m2': [120, 180, 90],
'Camere': [3, 4, 2],
'Eta_anni': [10, 5, 30],
'DistanzaCentro_km': [5, 2, 12]
})
print("\n🏠 CARATTERISTICHE DELLE NUOVE CASE:")
print(nuove_case)
# Standardizziamo come abbiamo fatto per il training
nuove_case_scaled = scaler.transform(nuove_case)
# Predici i prezzi
prezzi_predetti = model.predict(nuove_case_scaled)
print("\n💰 PREZZI PREDETTI DAL NOSTRO MODELLO:")
for i in range(len(nuove_case)):
print(f"\nCasa {i+1}:")
print(f" • {nuove_case.iloc[i]['Metratura_m2']} m², {nuove_case.iloc[i]['Camere']} camere")
print(f" • {nuove_case.iloc[i]['Eta_anni']} anni, {nuove_case.iloc[i]['DistanzaCentro_km']} km dal centro")
print(f" • 💰 Prezzo stimato: €{prezzi_predetti[i]:,.0f}")
# Aggiungiamo un intervallo di confidenza semplice
print(f"\n📊 INTERVALLO DI CONFIDENZA (approssimato):")
print(f"Considerando un errore medio di €{rmse:,.0f}, il vero prezzo probabilmente è:")
for i, prezzo_pred in enumerate(prezzi_predetti):
print(f"Casa {i+1}: €{prezzo_pred - rmse:,.0f} - €{prezzo_pred + rmse:,.0f}")
# ------------------------------------------------------------
# PASSO 11: CONFRONTO CON REGRESSIONE SEMPLICE
# ------------------------------------------------------------
print("\n\n📝 PASSO 11: CONFRONTO CON REGRESSIONE SEMPLICE")
print("-" * 40)
print("Vediamo se la regressione multipla è davvero migliore...")
# Regressione semplice (solo metratura)
from sklearn.linear_model import LinearRegression as LR_semplice
model_semplice = LR_semplice()
model_semplice.fit(X_train[['Metratura_m2']], y_train)
y_pred_semplice = model_semplice.predict(X_test[['Metratura_m2']])
r2_semplice = r2_score(y_test, y_pred_semplice)
print("🎯 CONFRONTO PERFORMANCE:")
print(f"• Regressione SEMPLICE (solo metratura): R² = {r2_semplice:.3f}")
print(f"• Regressione MULTIPLA (4 caratteristiche): R² = {r2:.3f}")
miglioramento = ((r2 - r2_semplice) / r2_semplice) * 100
print(f"\n📈 MIGLIORAMENTO: +{miglioramento:.1f}% di accuratezza!")
print("\n🎯 PERCHÉ LA REGRESSIONE MULTIPLA È MEGLIO?")
print("1. Considera TUTTE le informazioni disponibili")
print("2. Isola l'effetto di ogni caratteristica")
print("3. Fa previsioni più accurate e realistiche")
print("4. Ci aiuta a capire cosa conta davvero nel prezzo")
# ------------------------------------------------------------
# PASSO 12: CONCLUSIONI E CONSIGLI PRATICI
# ------------------------------------------------------------
print("\n\n📝 PASSO 12: COSA ABBIAMO IMPARATO E COME USARLO")
print("-" * 40)
print("✅ COSA ABBIAMO IMPARATO OGGI:")
print("1. La regressione multipla usa più caratteristiche insieme")
print("2. Ogni caratteristica ha un 'peso' (coefficiente β)")
print("3. Dobbiamo standardizzare le caratteristiche prima dell'analisi")
print("4. R² ci dice quanto il modello spiega i dati")
print("5. Più caratteristiche ≠ sempre meglio, devono essere utili")
print("\n🎯 COME USARE LA REGRESSIONE MULTIPLA NELLA VITA REALE:")
print("1. Raccogli tutte le informazioni rilevanti")
print("2. Controlla che non ci siano errori nei dati")
print("3. Standardizza se le scale sono diverse")
print("4. Dividi in training e test")
print("5. Addestra il modello e interpreta i coefficienti")
print("6. Verifica con R² e errori")
print("7. Usa per fare previsioni su nuovi dati")
print("\n⚠️ COSA EVITARE:")
print("1. Non usare troppe caratteristiche irrilevanti")
print("2. Non dimenticare di standardizzare")
print("3. Non testare sui dati usati per il training")
print("4. Non interpretare correlazioni come causalità")
print("\n📊 RIEPILOGO DEL NOSTRO MODELLO:")
print(f"Equazione: Prezzo = {model.intercept_:,.0f} + {model.coef_[0]:,.0f}×Metratura + {model.coef_[1]:,.0f}×Camere + {model.coef_[2]:,.0f}×Età + {model.coef_[3]:,.0f}×Distanza")
print(f"Accuratezza: R² = {r2:.3f} ({r2*100:.1f}% varianza spiegata)")
print(f"Errore tipico: ±€{rmse:,.0f} per previsione")
print("\n🎉 COMPLIMENTI! HAI MASTERIZZATO LA REGRESSIONE MULTIPLA!")
print("Ora puoi analizzare problemi complessi con più variabili!")