Impara Machine Learning predittivo con Scikit-Learn e dataset reali.
Introduzione
Benvenuto nella tua prima esercitazione di Machine Learning! Imparerai a costruire un modello di regressione lineare che predice i prezzi delle case basandosi su caratteristiche come metratura, numero di camere e posizione. Useremo Scikit-Learn, la libreria Python più popolare per il ML.
Scenario Reale: Lavorerai come Data Scientist per un'agenzia immobiliare che vuole automatizzare la stima dei prezzi delle case. Costruirai un modello ML che impara dai dati storici e fa previsioni accurate.
ATTENZIONE: COPIA BLOCCATA
Il codice è protetto da sistema anti-copia. Dovrai SCRIVERE manualmente tutto il codice per imparare veramente! 🚫📋
Parte 1: Setup e Dataset
Importazione Librerie ML
1 Crea una nuova cella su Google Colab e importa le librerie:
PYTHON
# IMPORT LIBRERIE PER MACHINE LEARNING
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_absolute_error, mean_squared_error, r2_score
# Configurazione visualizzazione
sns.set_style("whitegrid")
plt.rcParams['figure.figsize'] = (12, 8)
print("✅ Librerie ML importate correttamente!")
print("📊 Librerie disponibili:")
print(f" • NumPy: {np.__version__}")
print(f" • Pandas: {pd.__version__}")
print(f" • Scikit-Learn: importato")
Creazione Dataset Immobiliare
2 Crea il dataset di case per il training:
PYTHON
# 2. CREAZIONE DATASET IMMOBILIARE DI ESEMPIO
np.random.seed(42) # Per risultati riproducibili
# Genera dati sintetici realistici
n_case = 100
# Caratteristiche (features)
metratura = np.random.randint(50, 300, n_case) # m²
camere = np.random.randint(1, 6, n_case) # numero camere
bagni = np.random.randint(1, 4, n_case) # numero bagni
eta = np.random.randint(0, 50, n_case) # anni costruzione
zona = np.random.choice([1, 2, 3], n_case, p=[0.3, 0.5, 0.2]) # 1=centro, 2=periferia, 3=suburbano
# Calcola prezzo base (target variable)
# Formula: prezzo = 2000*metratura + 30000*camere + 20000*bagni - 1000*eta + 50000*zona + rumore
prezzo_base = (2000 * metratura +
30000 * camere +
20000 * bagni -
1000 * eta +
50000 * zona)
# Aggiungi rumore casuale
rumore = np.random.randn(n_case) * 50000
prezzo = prezzo_base + rumore
# Crea DataFrame Pandas
df_case = pd.DataFrame({
'metratura': metratura,
'camere': camere,
'bagni': bagni,
'eta': eta,
'zona': zona,
'prezzo': prezzo
})
# Converti zona in categorie
df_case['zona_desc'] = df_case['zona'].map({1: 'Centro', 2: 'Periferia', 3: 'Suburbano'})
print("🏠 DATASET IMMOBILIARE CREATO")
print("="*50)
print(f"Numero case nel dataset: {len(df_case)}")
print("\nPrime 5 righe del dataset:")
print(df_case.head())
print("\n📊 Statistiche descrittive:")
print(df_case.describe())
Parte 2: Analisi Esplorativa dei Dati (EDA)
Visualizzazione Relazioni
3 Analizza le relazioni tra variabili:
PYTHON
# 3. ANALISI ESPLORATIVA DEI DATI (EDA)
print("🔍 ANALISI ESPLORATIVA DATI IMMOBILIARI")
print("="*50)
# 3.1 Distribuzione prezzi
print("\n📈 DISTRIBUZIONE PREZZI:")
print(f"Prezzo medio: €{df_case['prezzo'].mean():,.0f}")
print(f"Prezzo mediano: €{df_case['prezzo'].median():,.0f}")
print(f"Prezzo minimo: €{df_case['prezzo'].min():,.0f}")
print(f"Prezzo massimo: €{df_case['prezzo'].max():,.0f}")
print(f"Deviazione standard: €{df_case['prezzo'].std():,.0f}")
# 3.2 Correlazioni tra variabili
print("\n📊 MATRICE DI CORRELAZIONE:")
correlation_matrix = df_case[['metratura', 'camere', 'bagni', 'eta', 'zona', 'prezzo']].corr()
print(correlation_matrix.round(2))
# 3.3 Visualizzazione grafica
print("\n🎨 CREAZIONE GRAFICI DI ANALISI...")
# Configura subplots
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
fig.suptitle('Analisi Dataset Immobiliare', fontsize=16, fontweight='bold')
# 1. Distribuzione prezzi
axes[0, 0].hist(df_case['prezzo'], bins=20, edgecolor='black', alpha=0.7, color='skyblue')
axes[0, 0].set_title('Distribuzione Prezzi Case')
axes[0, 0].set_xlabel('Prezzo (€)')
axes[0, 0].set_ylabel('Frequenza')
# 2. Prezzo vs Metratura
axes[0, 1].scatter(df_case['metratura'], df_case['prezzo'], alpha=0.6, color='green')
axes[0, 1].set_title('Prezzo vs Metratura')
axes[0, 1].set_xlabel('Metratura (m²)')
axes[0, 1].set_ylabel('Prezzo (€)')
# 3. Prezzo vs Numero Camere
box_data = [df_case[df_case['camere'] == i]['prezzo'] for i in sorted(df_case['camere'].unique())]
axes[0, 2].boxplot(box_data, labels=sorted(df_case['camere'].unique()))
axes[0, 2].set_title('Prezzo vs Numero Camere')
axes[0, 2].set_xlabel('Numero Camere')
axes[0, 2].set_ylabel('Prezzo (€)')
# 4. Prezzo vs Zona
zone_prezzi = df_case.groupby('zona_desc')['prezzo'].mean()
colors = ['gold', 'lightcoral', 'lightgreen']
axes[1, 0].bar(zone_prezzi.index, zone_prezzi.values, color=colors)
axes[1, 0].set_title('Prezzo Medio per Zona')
axes[1, 0].set_xlabel('Zona')
axes[1, 0].set_ylabel('Prezzo Medio (€)')
axes[1, 0].tick_params(axis='x', rotation=45)
# 5. Heatmap Correlazioni
im = axes[1, 1].imshow(correlation_matrix.values, cmap='coolwarm', aspect='auto')
axes[1, 1].set_title('Matrice di Correlazione')
axes[1, 1].set_xticks(range(len(correlation_matrix.columns)))
axes[1, 1].set_yticks(range(len(correlation_matrix.columns)))
axes[1, 1].set_xticklabels(correlation_matrix.columns, rotation=45)
axes[1, 1].set_yticklabels(correlation_matrix.columns)
plt.colorbar(im, ax=axes[1, 1])
# 6. Prezzo vs Età Costruzione
axes[1, 2].scatter(df_case['eta'], df_case['prezzo'], alpha=0.6, color='purple')
axes[1, 2].set_title('Prezzo vs Età Costruzione')
axes[1, 2].set_xlabel('Età (anni)')
axes[1, 2].set_ylabel('Prezzo (€)')
plt.tight_layout()
plt.show()
print("✅ Analisi EDA completata con successo!")
Parte 3: Preparazione Dati per Machine Learning
Split Train/Test e Preprocessing
4 Prepara i dati per il modello ML:
PYTHON
# 4. PREPARAZIONE DATI PER MACHINE LEARNING
print("⚙️ PREPARAZIONE DATI PER IL MODELLO")
print("="*50)
# 4.1 Definizione Features (X) e Target (y)
# Selezioniamo le caratteristiche più rilevanti
features = ['metratura', 'camere', 'bagni', 'eta', 'zona']
X = df_case[features]
y = df_case['prezzo']
print(f"\nFeatures selezionate: {features}")
print(f"Dimensione X (features): {X.shape}")
print(f"Dimensione y (target): {y.shape}")
# 4.2 Split in Train e Test set
# Usiamo 80% per training e 20% per testing
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
print(f"\n📊 SPLIT DATI COMPLETATO:")
print(f" Training set: {X_train.shape[0]} case ({X_train.shape[0]/len(df_case)*100:.0f}%)")
print(f" Test set: {X_test.shape[0]} case ({X_test.shape[0]/len(df_case)*100:.0f}%)")
# 4.3 Mostra esempio dati di training
print("\n📋 ESEMPIO DATI DI TRAINING (prime 3 righe):")
train_sample = pd.concat([X_train.head(3), y_train.head(3)], axis=1)
print(train_sample)
# 4.4 Normalizzazione delle features (opzionale per regressione lineare)
# Per regressione lineare, spesso non serve normalizzazione
# ma la mostriamo per completezza
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
print("\n🔢 NORMALIZZAZIONE COMPLETATA")
print(" Features scalate con media=0 e deviazione=1")
Parte 4: Addestramento Modello di Regressione
Creazione e Training Modello
5 Crea e addestra il modello di regressione:
PYTHON
# 5. ADDESTRAMENTO MODELLO DI REGRESSIONE LINEARE
print("🤖 ADDESTRAMENTO MODELLO ML")
print("="*50)
# 5.1 Creazione modello
model = LinearRegression()
print("✅ Modello LinearRegression creato")
# 5.2 Addestramento con dati di training
print("\n⚡ Addestramento modello in corso...")
model.fit(X_train_scaled, y_train)
print("✅ Modello addestrato con successo!")
# 5.3 Coefficienti del modello (importanza features)
coefficients = pd.DataFrame({
'feature': features,
'coefficient': model.coef_
}).sort_values('coefficient', ascending=False)
print("\n📊 COEFFICIENTI DEL MODELLO (importanza features):")
print(coefficients)
print(f"\nIntercetta (bias): €{model.intercept_:,.2f}")
# 5.4 Interpretazione coefficienti
print("\n🔍 INTERPRETAZIONE COEFFICIENTI:")
for idx, row in coefficients.iterrows():
segno = "+" if row['coefficient'] > 0 else "-"
effetto = "aumenta" if row['coefficient'] > 0 else "diminuisce"
print(f" • {row['feature']}: {segno}€{abs(row['coefficient']):,.0f} per unità → {effetto} il prezzo")
Valutazione Modello
6 Valuta le performance del modello:
PYTHON
# 6. VALUTAZIONE DEL MODELLO
print("\n📈 VALUTAZIONE PERFORMANCE MODELLO")
print("="*50)
# 6.1 Predizioni sui set di training e test
y_pred_train = model.predict(X_train_scaled)
y_pred_test = model.predict(X_test_scaled)
# 6.2 Calcolo metriche di valutazione
def calculate_metrics(y_true, y_pred, dataset_name):
mae = mean_absolute_error(y_true, y_pred)
mse = mean_squared_error(y_true, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_true, y_pred)
print(f"\n📊 METRICHE {dataset_name.upper()}:")
print(f" • MAE (Mean Absolute Error): €{mae:,.0f}")
print(f" • MSE (Mean Squared Error): €{mse:,.0f}")
print(f" • RMSE (Root Mean Squared Error): €{rmse:,.0f}")
print(f" • R² Score: {r2:.3f}")
return mae, rmse, r2
# Calcola metriche per training e test
mae_train, rmse_train, r2_train = calculate_metrics(y_train, y_pred_train, "training")
mae_test, rmse_test, r2_test = calculate_metrics(y_test, y_pred_test, "test")
# 6.3 Visualizzazione predizioni vs valori reali
print("\n🎨 VISUALIZZAZIONE RISULTATI...")
fig, axes = plt.subplots(1, 2, figsize=(15, 6))
# Training set
axes[0].scatter(y_train, y_pred_train, alpha=0.6, color='blue')
axes[0].plot([y_train.min(), y_train.max()], [y_train.min(), y_train.max()], 'r--', lw=2)
axes[0].set_title('Training Set: Valori Reali vs Predetti')
axes[0].set_xlabel('Prezzo Reale (€)')
axes[0].set_ylabel('Prezzo Predetto (€)')
axes[0].grid(True, alpha=0.3)
# Test set
axes[1].scatter(y_test, y_pred_test, alpha=0.6, color='green')
axes[1].plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
axes[1].set_title('Test Set: Valori Reali vs Predetti')
axes[1].set_xlabel('Prezzo Reale (€)')
axes[1].set_ylabel('Prezzo Predetto (€)')
axes[1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 6.4 Analisi residui
print("\n🔍 ANALISI RESIDUI (errori di predizione):")
residui_test = y_test - y_pred_test
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.scatter(y_pred_test, residui_test, alpha=0.6, color='purple')
plt.axhline(y=0, color='r', linestyle='--')
plt.title('Residui vs Predizioni')
plt.xlabel('Prezzo Predetto (€)')
plt.ylabel('Residuo (€)')
plt.grid(True, alpha=0.3)
plt.subplot(1, 2, 2)
plt.hist(residui_test, bins=20, edgecolor='black', alpha=0.7, color='orange')
plt.title('Distribuzione Residui')
plt.xlabel('Residuo (€)')
plt.ylabel('Frequenza')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
print("✅ Valutazione modello completata!")
Parte 5: Utilizzo Pratico del Modello
Previsioni su Nuove Case
7 Usa il modello per fare previsioni:
PYTHON
# 7. UTILIZZO MODELLO PER PREVISIONI
print("🔮 PREVISIONI SU NUOVE CASE")
print("="*50)
# 7.1 Crea nuove case per la previsione
nuove_case = pd.DataFrame({
'metratura': [120, 85, 200, 150, 90],
'camere': [3, 2, 4, 3, 2],
'bagni': [2, 1, 3, 2, 1],
'eta': [10, 25, 5, 15, 30],
'zona': [2, 1, 3, 2, 1] # 1=centro, 2=periferia, 3=suburbano
})
print("🏠 NUOVE CASE DA VALUTARE:")
nuove_case_display = nuove_case.copy()
nuove_case_display['zona_desc'] = nuove_case_display['zona'].map({1: 'Centro', 2: 'Periferia', 3: 'Suburbano'})
print(nuove_case_display[['metratura', 'camere', 'bagni', 'eta', 'zona_desc']])
# 7.2 Preprocessing nuove case (usando lo stesso scaler)
X_nuove_scaled = scaler.transform(nuove_case)
# 7.3 Fai previsioni
previsioni = model.predict(X_nuove_scaled)
# 7.4 Mostra risultati
print("\n💰 PREZZI PREVISTI:")
risultati = nuove_case.copy()
risultati['zona_desc'] = risultati['zona'].map({1: 'Centro', 2: 'Periferia', 3: 'Suburbano'})
risultati['prezzo_previsto'] = previsioni
for idx, row in risultati.iterrows():
print(f"\nCasa #{idx + 1}:")
print(f" • Metratura: {row['metratura']} m²")
print(f" • Camere: {row['camere']}")
print(f" • Bagni: {row['bagni']}")
print(f" • Età: {row['eta']} anni")
print(f" • Zona: {row['zona_desc']}")
print(f" • 💰 Prezzo stimato: €{row['prezzo_previsto']:,.0f}")
# 7.5 Analisi sensibilità: come cambia il prezzo con le caratteristiche
print("\n📊 ANALISI DI SENSIBILITÀ:")
print("Come cambia il prezzo al variare delle caratteristiche:")
# Casa di riferimento
casa_base = pd.DataFrame({
'metratura': [100],
'camere': [3],
'bagni': [2],
'eta': [10],
'zona': [2]
})
prezzo_base = model.predict(scaler.transform(casa_base))[0]
print(f"\nCasa base (100m², 3 camere, 2 bagni, 10 anni, periferia): €{prezzo_base:,.0f}")
# Variazioni
variazioni = [
("+20m²", {"metratura": 120}),
("+1 camera", {"camere": 4}),
("+1 bagno", {"bagni": 3}),
("+10 anni", {"eta": 20}),
("Centro città", {"zona": 1}),
("Suburbano", {"zona": 3})
]
for desc, cambiamenti in variazioni:
casa_variazione = casa_base.copy()
for key, value in cambiamenti.items():
casa_variazione[key] = value
prezzo_variazione = model.predict(scaler.transform(casa_variazione))[0]
differenza = prezzo_variazione - prezzo_base
segno = "+" if differenza > 0 else ""
print(f" {desc}: €{prezzo_variazione:,.0f} ({segno}€{abs(differenza):,.0f})")
print("\n✅ Sistema di previsione prezzi completato con successo!")
Concetti di Machine Learning Appresi
Congratulazioni! Ora conosci:
- ✓ Regressione Lineare: Modello ML per previsioni numeriche
- ✓ Scikit-Learn: Libreria Python più usata per ML
- ✓ EDA (Exploratory Data Analysis): Analisi preliminare dei dati
- ✓ Train/Test Split: Separazione dati per valutazione modelli
- ✓ Feature Scaling: Normalizzazione dati per ML
- ✓ Metriche di Valutazione: MAE, MSE, RMSE, R² Score
- ✓ Interpretazione Modelli: Coefficienti e loro significato
- ✓ Pipeline ML Completa: Dati → Preprocessing → Training → Valutazione → Previsioni
Prossimi Passi nel Machine Learning
Nella prossima esercitazione imparerai:
- 🌺 Classificazione con dataset Iris
- 📊 Regressione multipla avanzata
- 🔍 Feature engineering e selezione
- 🤖 Algoritmi di ensemble (Random Forest)
- 🧠 Reti neurali per regressione
Hai costruito il tuo primo modello di Machine Learning professionale!