🔍 Clustering con K-Means: Scopri Pattern Nascosti nei Dati

Impara l’apprendimento non supervisionato per raggruppare dati simili

Introduzione

Benvenuto nel mondo del clustering! A differenza della classificazione supervisionata, il clustering è un algoritmo di apprendimento non supervisionato che trova automaticamente gruppi (cluster) di dati simili. K-Means è l’algoritmo di clustering più popolare e imparerai a usarlo per segmentare clienti, trovare anomalie e scoprire pattern nascosti.

Scenario Reale:
Lavorerai come Data Analyst per un’azienda e-commerce che vuole segmentare i suoi clienti in gruppi omogenei per creare campagne di marketing personalizzate. Scoprirai pattern nascosti nei comportamenti d’acquisto senza sapere in anticipo quanti gruppi esistono.

⚠️ ATTENZIONE: COPIA BLOCCATA

Il codice è protetto da sistema anti-copia. Dovrai SCRIVERE manualmente tutto il codice per imparare veramente! 🚫📋

Parte 1: Setup e Creazione Dataset Clienti

▶ Importazione Librerie e Creazione Dati

1
Crea una nuova cella su Google Colab e importa le librerie:
PYTHON
# IMPORT LIBRERIE PER CLUSTERING E VISUALIZZAZIONE
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score, davies_bouldin_score
from sklearn.decomposition import PCA
import warnings
warnings.filterwarnings('ignore')

# Configurazione visualizzazione
sns.set_style("whitegrid")
plt.rcParams['figure.figsize'] = (14, 8)
plt.rcParams['font.size'] = 12

print("✅ Librerie per clustering importate correttamente!")
print("📊 Algoritmi disponibili: K-Means, Metriche di valutazione, PCA")

▶ Creazione Dataset Clienti E-commerce

2
Crea un dataset realistico di clienti e-commerce:
PYTHON
# 2. CREAZIONE DATASET CLIENTI E-COMMERCE
print("🛒 CREAZIONE DATASET CLIENTI E-COMMERCE")
print("="*50)

np.random.seed(42)  # Per risultati riproducibili
n_clienti = 300

# Creiamo 3 gruppi distinti di clienti (cluster naturali)
# Gruppo 1: Clienti occasionali (basso valore)
cluster1_size = int(n_clienti * 0.3)
annual_spend_1 = np.random.normal(200, 50, cluster1_size)
visit_freq_1 = np.random.normal(4, 1, cluster1_size)
avg_order_1 = np.random.normal(25, 5, cluster1_size)
return_rate_1 = np.random.normal(0.1, 0.02, cluster1_size)

# Gruppo 2: Clienti regolari (valore medio)
cluster2_size = int(n_clienti * 0.4)
annual_spend_2 = np.random.normal(800, 150, cluster2_size)
visit_freq_2 = np.random.normal(12, 2, cluster2_size)
avg_order_2 = np.random.normal(65, 10, cluster2_size)
return_rate_2 = np.random.normal(0.05, 0.01, cluster2_size)

# Gruppo 3: Clienti premium (alto valore)
cluster3_size = n_clienti - cluster1_size - cluster2_size
annual_spend_3 = np.random.normal(2000, 400, cluster3_size)
visit_freq_3 = np.random.normal(25, 4, cluster3_size)
avg_order_3 = np.random.normal(120, 20, cluster3_size)
return_rate_3 = np.random.normal(0.02, 0.005, cluster3_size)

# Combina tutti i dati
annual_spend = np.concatenate([annual_spend_1, annual_spend_2, annual_spend_3])
visit_freq = np.concatenate([visit_freq_1, visit_freq_2, visit_freq_3])
avg_order = np.concatenate([avg_order_1, avg_order_2, avg_order_3])
return_rate = np.concatenate([return_rate_1, return_rate_2, return_rate_3])

# Etichette vere (solo per validazione, nel clustering reale non le abbiamo)
true_labels = np.array([0]*cluster1_size + [1]*cluster2_size + [2]*cluster3_size)

# Crea DataFrame
df_clienti = pd.DataFrame({
    'customer_id': range(1, n_clienti + 1),
    'annual_spend': annual_spend,
    'visit_frequency': visit_freq,
    'avg_order_value': avg_order,
    'return_rate': return_rate,
    'true_cluster': true_labels  # Solo per validazione
})

# Aggiungi qualche rumore per rendere più realistico
df_clienti['annual_spend'] = np.abs(df_clienti['annual_spend'])  # Evita valori negativi
df_clienti['visit_frequency'] = np.abs(df_clienti['visit_frequency'])
df_clienti['avg_order_value'] = np.abs(df_clienti['avg_order_value'])
df_clienti['return_rate'] = np.clip(df_clienti['return_rate'], 0, 0.2)

print(f"📊 DATASET CLIENTI CREATO:")
print(f"  • Numero clienti: {len(df_clienti)}")
print(f"  • Cluster veri: 3 gruppi (Occasionali, Regolari, Premium)")
print(f"  • Dimensioni cluster: {cluster1_size}, {cluster2_size}, {cluster3_size}")

print(f"\n📋 PRIME 10 RIGHE DEL DATASET:")
print(df_clienti.head(10))

print(f"\n📈 STATISTICHE DESCRITTIVE:")
print(df_clienti[['annual_spend', 'visit_frequency', 'avg_order_value', 'return_rate']].describe())

print(f"\n🎯 DISTRIBUZIONE CLUSTER VERI:")
cluster_names = {0: 'Occasionali', 1: 'Regolari', 2: 'Premium'}
for cluster_id, cluster_name in cluster_names.items():
    count = (df_clienti['true_cluster'] == cluster_id).sum()
    percent = (count / len(df_clienti)) * 100
    print(f"  • {cluster_name}: {count} clienti ({percent:.1f}%)")

Parte 2: Analisi Esplorativa e Preprocessing

▶ Visualizzazione Dati e Normalizzazione

3
Analizza e prepara i dati per il clustering:
PYTHON
# 3. ANALISI ESPLORATIVA E PREPROCESSING
print("🔍 ANALISI ESPLORATIVA DATI CLIENTI")
print("="*50)

# 3.1 Visualizzazione distribuzioni
print("\n🎨 VISUALIZZAZIONE DISTRIBUZIONI...")

fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle('Distribuzione Caratteristiche Clienti', fontsize=16, fontweight='bold')

features = ['annual_spend', 'visit_frequency', 'avg_order_value', 'return_rate']
titles = ['Spesa Annuale (€)', 'Frequenza Visite', 'Valore Medio Ordine (€)', 'Tasso di Reso']
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFD166']

for idx, (feature, title, color) in enumerate(zip(features, titles, colors)):
    ax = axes[idx // 2, idx % 2]
    
    # Istogramma
    ax.hist(df_clienti[feature], bins=30, edgecolor='black', alpha=0.7, color=color)
    
    # Linee verticali per media e mediane
    mean_val = df_clienti[feature].mean()
    median_val = df_clienti[feature].median()
    
    ax.axvline(mean_val, color='red', linestyle='--', linewidth=2, label=f'Media: {mean_val:.1f}')
    ax.axvline(median_val, color='green', linestyle='--', linewidth=2, label=f'Mediana: {median_val:.1f}')
    
    ax.set_title(title, fontsize=13)
    ax.set_xlabel(title.split(' ')[0])
    ax.set_ylabel('Frequenza')
    ax.legend()
    ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

# 3.2 Matrice di correlazione
print("\n📊 MATRICE DI CORRELAZIONE:")
correlation_matrix = df_clienti[features].corr()

plt.figure(figsize=(10, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0, 
            square=True, linewidths=1, cbar_kws={"shrink": 0.8}, fmt='.2f')
plt.title('Correlazione tra Caratteristiche Clienti', fontsize=14, pad=20)
plt.tight_layout()
plt.show()

# 3.3 Normalizzazione delle features (CRUCIALE per K-Means!)
print("\n🔢 NORMALIZZAZIONE FEATURES PER K-MEANS:")
print("K-Means è sensibile alla scala delle features, quindi normalizziamo!")

# Seleziona solo le features per il clustering (escludiamo ID e cluster vero)
X = df_clienti[features].values

# Standardizzazione (media=0, deviazione=1)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

print(f"  • Features originali shape: {X.shape}")
print(f"  • Features scalate shape: {X_scaled.shape}")

# Crea DataFrame scalato per visualizzazione
df_scaled = pd.DataFrame(X_scaled, columns=[f + '_scaled' for f in features])
df_scaled['true_cluster'] = df_clienti['true_cluster']

print(f"\n📋 PRIME 5 RIGHE DATI SCALATI:")
print(df_scaled.head())

print(f"\n📈 STATISTICHE DATI SCALATI:")
print(df_scaled[[f + '_scaled' for f in features]].describe())

print("\n✅ Dati preparati per il clustering K-Means!")

Parte 3: Determinazione K Ottimale

▶ Metodo Elbow e Silhouette Score

4
Trova il numero ottimale di cluster con metodi scientifici:
PYTHON
# 4. DETERMINAZIONE NUMERO OTTIMALE DI CLUSTER (K)
print("🎯 TROVA IL NUMERO OTTIMALE DI CLUSTER")
print("="*50)

# Testiamo diversi valori di K
k_range = range(2, 11)
inertias = []
silhouette_scores = []
davies_bouldin_scores = []

print("🔬 Testando diversi valori di K...")
for k in k_range:
    # Esegui K-Means
    kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
    kmeans.fit(X_scaled)
    
    # Calcola metriche
    inertias.append(kmeans.inertia_)
    
    # Silhouette score (range: -1 to 1, più alto è meglio)
    silhouette_avg = silhouette_score(X_scaled, kmeans.labels_)
    silhouette_scores.append(silhouette_avg)
    
    # Davies-Bouldin score (più basso è meglio)
    db_score = davies_bouldin_score(X_scaled, kmeans.labels_)
    davies_bouldin_scores.append(db_score)
    
    print(f"  K={k}: Inertia={kmeans.inertia_:.1f}, "
          f"Silhouette={silhouette_avg:.3f}, DB={db_score:.3f}")

print("\n✅ Calcolo metriche completato!")

# 4.1 Visualizzazione Elbow Method
print("\n🎨 VISUALIZZAZIONE METODO ELBOW...")

fig, axes = plt.subplots(1, 3, figsize=(18, 6))

# Plot 1: Elbow Method (Inertia)
axes[0].plot(k_range, inertias, 'bo-', linewidth=2, markersize=8)
axes[0].set_xlabel('Numero di Cluster (K)')
axes[0].set_ylabel('Inertia')
axes[0].set_title('Elbow Method: Inertia vs K')
axes[0].grid(True, alpha=0.3)

# Aggiungi punto di gomito (elbow point)
# Calcoliamo la differenza delle differenze per trovare il gomito
diff_inertia = np.diff(inertias)
diff2_inertia = np.diff(diff_inertia)
elbow_k = k_range[np.argmin(diff2_inertia) + 1]
axes[0].axvline(x=elbow_k, color='red', linestyle='--', alpha=0.7, 
                label=f'Gomito suggerito: K={elbow_k}')
axes[0].legend()

# Plot 2: Silhouette Score
axes[1].plot(k_range, silhouette_scores, 'go-', linewidth=2, markersize=8)
axes[1].set_xlabel('Numero di Cluster (K)')
axes[1].set_ylabel('Silhouette Score')
axes[1].set_title('Silhouette Score vs K')
axes[1].grid(True, alpha=0.3)

# Trova K con silhouette massima
best_silhouette_k = k_range[np.argmax(silhouette_scores)]
axes[1].axvline(x=best_silhouette_k, color='red', linestyle='--', alpha=0.7,
                label=f'Max Silhouette: K={best_silhouette_k}')
axes[1].legend()

# Plot 3: Davies-Bouldin Score
axes[2].plot(k_range, davies_bouldin_scores, 'ro-', linewidth=2, markersize=8)
axes[2].set_xlabel('Numero di Cluster (K)')
axes[2].set_ylabel('Davies-Bouldin Score')
axes[2].set_title('Davies-Bouldin Score vs K')
axes[2].grid(True, alpha=0.3)

# Trova K con DB minimo
best_db_k = k_range[np.argmin(davies_bouldin_scores)]
axes[2].axvline(x=best_db_k, color='red', linestyle='--', alpha=0.7,
                label=f'Min DB: K={best_db_k}')
axes[2].legend()

plt.tight_layout()
plt.show()

# 4.2 Analisi risultati e scelta K ottimale
print("\n📊 ANALISI RISULTATI:")
print(f"  • Metodo Elbow suggerisce: K = {elbow_k}")
print(f"  • Silhouette Score massimo: K = {best_silhouette_k} (score: {max(silhouette_scores):.3f})")
print(f"  • Davies-Bouldin minimo: K = {best_db_k} (score: {min(davies_bouldin_scores):.3f})")

# Scegliamo K=3 (sappiamo che i dati sono stati generati con 3 cluster)
k_optimal = 3
print(f"\n🎯 K OTTIMALE SCELTO: {k_optimal}")
print("   (Basato sulla conoscenza dei dati e coerenza tra i metodi)")

Parte 4: Esecuzione K-Means e Analisi Cluster

▶ Addestramento K-Means e Analisi Risultati

5
Esegui K-Means e analizza i cluster trovati:
PYTHON
# 5. ESECUZIONE K-MEANS CON K OTTIMALE
print("⚡ ESECUZIONE K-MEANS CON K=3")
print("="*50)

# 5.1 Esegui K-Means
kmeans = KMeans(n_clusters=k_optimal, random_state=42, n_init=20)
kmeans.fit(X_scaled)

# Aggiungi etichette cluster al DataFrame originale
df_clienti['cluster'] = kmeans.labels_
df_clienti['cluster_name'] = df_clienti['cluster'].map({0: 'Cluster 1', 1: 'Cluster 2', 2: 'Cluster 3'})

# Centroidi (nelle coordinate scalate e originali)
centroids_scaled = kmeans.cluster_centers_
centroids_original = scaler.inverse_transform(centroids_scaled)

print("✅ K-Means eseguito con successo!")
print(f"\n📊 INFORMAZIONI CLUSTER:")
print(f"  • Inertia finale: {kmeans.inertia_:.1f}")
print(f"  • Numero iterazioni: {kmeans.n_iter_}")

# 5.2 Distribuzione cluster
print(f"\n🎯 DISTRIBUZIONE CLUSTER TROVATI:")
for cluster_id in range(k_optimal):
    count = (df_clienti['cluster'] == cluster_id).sum()
    percent = (count / len(df_clienti)) * 100
    print(f"  • Cluster {cluster_id}: {count} clienti ({percent:.1f}%)")

# 5.3 Confronto con cluster veri (solo perché li conosciamo)
print(f"\n🔍 CONFRONTO CON CLUSTER VERI (solo per validazione):")
confusion_matrix = pd.crosstab(df_clienti['true_cluster'], df_clienti['cluster'], 
                               rownames=['Vero'], colnames=['Predetto'])
print(confusion_matrix)

# 5.4 Analisi centroidi (profili cluster)
print(f"\n📈 PROFILI CLUSTER (Centroidi):")
centroids_df = pd.DataFrame(centroids_original, columns=features)
centroids_df['cluster'] = range(k_optimal)

print("\nCentroidi nelle coordinate originali:")
print(centroids_df.round(2))

# 5.5 Visualizzazione cluster in 2D (usando PCA per riduzione dimensionale)
print("\n🎨 VISUALIZZAZIONE CLUSTER IN 2D (PCA)...")

# Riduci a 2 dimensioni con PCA per visualizzazione
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

# Aggiungi componenti PCA al DataFrame
df_clienti['pca1'] = X_pca[:, 0]
df_clienti['pca2'] = X_pca[:, 1]

# Calcola varianza spiegata
explained_variance = pca.explained_variance_ratio_
print(f"  • Varianza spiegata PCA1: {explained_variance[0]*100:.1f}%")
print(f"  • Varianza spiegata PCA2: {explained_variance[1]*100:.1f}%")
print(f"  • Varianza totale spiegata: {sum(explained_variance)*100:.1f}%")

# Visualizzazione
fig, axes = plt.subplots(1, 2, figsize=(16, 7))

# Plot 1: Cluster trovati da K-Means
scatter1 = axes[0].scatter(df_clienti['pca1'], df_clienti['pca2'], 
                          c=df_clienti['cluster'], cmap='viridis', 
                          alpha=0.7, s=50, edgecolor='black', linewidth=0.5)
axes[0].set_xlabel(f'PCA1 ({explained_variance[0]*100:.1f}% varianza)')
axes[0].set_ylabel(f'PCA2 ({explained_variance[1]*100:.1f}% varianza)')
axes[0].set_title('Cluster Trovati da K-Means')
plt.colorbar(scatter1, ax=axes[0], label='Cluster')

# Plot centroidi
centroids_pca = pca.transform(centroids_scaled)
axes[0].scatter(centroids_pca[:, 0], centroids_pca[:, 1], 
               c='red', marker='X', s=200, label='Centroidi', edgecolor='black')
axes[0].legend()

# Plot 2: Cluster veri (solo per confronto)
scatter2 = axes[1].scatter(df_clienti['pca1'], df_clienti['pca2'], 
                          c=df_clienti['true_cluster'], cmap='viridis', 
                          alpha=0.7, s=50, edgecolor='black', linewidth=0.5)
axes[1].set_xlabel(f'PCA1 ({explained_variance[0]*100:.1f}% varianza)')
axes[1].set_ylabel(f'PCA2 ({explained_variance[1]*100:.1f}% varianza)')
axes[1].set_title('Cluster Veri (per validazione)')
plt.colorbar(scatter2, ax=axes[1], label='Cluster Vero')

plt.tight_layout()
plt.show()

print("✅ Analisi cluster completata!")

Parte 5: Interpretazione Cluster e Strategie Marketing

▶ Profilazione Clienti e Strategie

6
Interpreta i cluster e crea strategie di marketing:
PYTHON
# 6. INTERPRETAZIONE CLUSTER E STRATEGIE MARKETING
print("💡 INTERPRETAZIONE CLUSTER E STRATEGIE")
print("="*50)

# 6.1 Analisi dettagliata per cluster
print("\n📊 ANALISI DETTAGLIATA PER CLUSTER:")

# Calcola medie per cluster
cluster_stats = df_clienti.groupby('cluster')[features].mean()
cluster_stats['count'] = df_clienti.groupby('cluster').size()
cluster_stats['percentage'] = (cluster_stats['count'] / len(df_clienti)) * 100

print("\nMedie per cluster (valori originali):")
print(cluster_stats.round(2))

# 6.2 Normalizza per confronto tra cluster
print("\n📈 CONFRONTO NORMALIZZATO TRA CLUSTER:")
# Normalizza rispetto alla media globale
global_means = df_clienti[features].mean()
cluster_normalized = cluster_stats[features].copy()

for feature in features:
    cluster_normalized[feature] = (cluster_stats[feature] / global_means[feature]) * 100

print("\nValori normalizzati (% rispetto alla media globale):")
print(cluster_normalized.round(1))

# 6.3 Visualizzazione radar chart per profili cluster
print("\n🎨 PROFILI CLUSTER IN RADAR CHART...")

from math import pi

# Prepara dati per radar chart
categories = ['Spesa Annuale', 'Frequenza Visite', 'Valore Ordine', 'Tasso Reso']
N = len(categories)

# Crea angoli per ogni asse
angles = [n / float(N) * 2 * pi for n in range(N)]
angles += angles[:1]  # Chiudi il cerchio

fig, ax = plt.subplots(figsize=(10, 10), subplot_kw=dict(projection='polar'))

# Colori per cluster
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1']

for cluster_id in range(k_optimal):
    # Prepara valori (normalizzati tra 0 e 1 per radar chart)
    values = cluster_normalized.loc[cluster_id].values.tolist()
    values += values[:1]  # Chiudi il cerchio
    
    # Plot
    ax.plot(angles, values, color=colors[cluster_id], linewidth=2, 
            label=f'Cluster {cluster_id} ({cluster_stats.loc[cluster_id, "percentage"]:.1f}%)')
    ax.fill(angles, values, color=colors[cluster_id], alpha=0.25)

# Configura assi
ax.set_xticks(angles[:-1])
ax.set_xticklabels(categories, fontsize=12)
ax.set_ylim(0, 200)  # 200% della media
ax.set_yticks([50, 100, 150, 200])
ax.set_yticklabels(['50%', '100%', '150%', '200%'], fontsize=10)
ax.grid(True, alpha=0.3)

plt.title('Profili Cluster Clienti (% rispetto alla media globale)', 
          fontsize=14, pad=20)
plt.legend(loc='upper right', bbox_to_anchor=(1.3, 1.0))
plt.tight_layout()
plt.show()

# 6.4 Interpretazione e strategie di marketing
print("\n💡 INTERPRETAZIONE CLUSTER:")
cluster_names = ['Clienti Occasionali', 'Clienti Regolari', 'Clienti Premium']
cluster_descriptions = [
    "Bassa spesa, poche visite, ordini piccoli, alto tasso di reso",
    "Spesa media, visite regolari, ordini di valore medio, basso tasso di reso", 
    "Alta spesa, molte visite, ordini di grande valore, tasso di reso molto basso"
]

for cluster_id in range(k_optimal):
    print(f"\n🔍 CLUSTER {cluster_id} - {cluster_names[cluster_id]}:")
    print(f"  • Dimensione: {cluster_stats.loc[cluster_id, 'count']} clienti "
          f"({cluster_stats.loc[cluster_id, 'percentage']:.1f}%)")
    print(f"  • Profilo: {cluster_descriptions[cluster_id]}")
    
    # Statistiche specifiche
    print(f"  • Spesa annuale media: €{cluster_stats.loc[cluster_id, 'annual_spend']:.0f} "
          f"({cluster_normalized.loc[cluster_id, 'annual_spend']:.0f}% della media)")
    print(f"  • Visite mensili medie: {cluster_stats.loc[cluster_id, 'visit_frequency']:.1f}")
    print(f"  • Valore ordine medio: €{cluster_stats.loc[cluster_id, 'avg_order_value']:.0f}")
    print(f"  • Tasso di reso: {cluster_stats.loc[cluster_id, 'return_rate']*100:.1f}%")

print("\n🎯 STRATEGIE MARKETING PERSONALIZZATE:")
strategies = [
    "🎯 Cluster 0 (Occasionali): Programma fidelizzazione, sconti primo acquisto, email reminder",
    "🎯 Cluster 1 (Regolari): Programma loyalty, sconti fedeltà, contenuti educativi, early access",
    "🎯 Cluster 2 (Premium): VIP treatment, concierge personale, regali esclusivi, eventi privati"
]

for strategy in strategies:
    print(f"  {strategy}")

# 6.5 Esempi pratici: assegnazione nuovi clienti
print("\n🔮 ESEMPI: ASSEGNAZIONE NUOVI CLIENTI AI CLUSTER")

# Crea nuovi clienti "sconosciuti"
nuovi_clienti = np.array([
    [150, 3, 20, 0.12],   # Sembra un cliente occasionale
    [750, 10, 60, 0.06],  # Sembra un cliente regolare
    [2200, 22, 130, 0.03] # Sembra un cliente premium
])

# Normalizza i nuovi dati
nuovi_clienti_scaled = scaler.transform(nuovi_clienti)

# Predici cluster
cluster_predetti = kmeans.predict(nuovi_clienti_scaled)

print("\n{:^5} | {:^25} | {:^20} | {:^15}".format(
    "Cliente", "Caratteristiche", "Cluster Assegnato", "Tipo Cliente"))
print("-" * 70)

for i, (cliente, cluster) in enumerate(zip(nuovi_clienti, cluster_predetti)):
    caratteristiche = f"€{cliente[0]:.0f}, {cliente[1]:.0f}v, €{cliente[2]:.0f}, {cliente[3]*100:.1f}%"
    tipo_cliente = cluster_names[cluster]
    
    print("{:^7} | {:^25} | {:^20} | {:^15}".format(
        f"C{i+1}", caratteristiche, f"Cluster {cluster}", tipo_cliente))

print(f"\n✅ Segmentazione clienti completata con successo!")
print(f"🎯 K-Means ha identificato {k_optimal} gruppi di clienti con comportamenti distinti")
print(f"📈 Ora puoi creare campagne di marketing personalizzate per ogni cluster!")

Concetti di Clustering Appresi

Congratulazioni! Ora conosci:

  • Clustering: Apprendimento non supervisionato per raggruppare dati simili
  • K-Means: L'algoritmo di clustering più popolare e utilizzato
  • Determinazione K ottimale: Metodo Elbow, Silhouette Score, Davies-Bouldin
  • Normalizzazione: Importanza della standardizzazione per K-Means
  • Centroidi: Punti centrali dei cluster e loro interpretazione
  • Metriche di valutazione: Inertia, Silhouette, Davies-Bouldin
  • PCA: Riduzione dimensionale per visualizzazione cluster
  • Customer Segmentation: Applicazione pratica del clustering al marketing
  • Interpretazione cluster: Trasformare numeri in strategie business

Prossimi Passi nel Clustering

Nella prossima esercitazione imparerai:

  • 🌐 Clustering gerarchico (Hierarchical Clustering)
  • 🔍 DBSCAN per cluster di forma arbitraria
  • 📊 Clustering su dati testuali (NLP clustering)
  • 🤖 Clustering con reti neurali (Autoencoders)
  • 🎯 Valutazione cluster con metriche avanzate

Hai padroneggiato il clustering K-Means e la segmentazione clienti!

Torna in alto