Segmentazione dei clienti in Python Un approccio pratico

Segmentazione dei clienti in Python Un approccio pratico e concreto

 

La segmentazione dei clienti può aiutare le aziende a personalizzare i propri sforzi di marketing e migliorare la soddisfazione del cliente. Ecco come.

Funzionalmente, la segmentazione dei clienti comporta la suddivisione di una base clienti in gruppi o segmenti distinti, basati su caratteristiche e comportamenti comuni. Comprendendo le esigenze e le preferenze di ciascun segmento, le aziende possono fornire campagne di marketing più personalizzate ed efficaci, che portano a una maggiore fidelizzazione del cliente e a una maggiore revenue.

In questo tutorial, esploreremo la segmentazione dei clienti in Python combinando due tecniche fondamentali: analisi RFM (Recency, Frequency, Monetary) e clustering K-Means. L’analisi RFM fornisce un quadro strutturato per valutare il comportamento del cliente, mentre il clustering K-Means offre un approccio basato sui dati per raggruppare i clienti in segmenti significativi. Lavoreremo con un dataset del mondo reale proveniente dall’industria del retail: il dataset Online Retail dal repository di apprendimento automatico UCI.

Dalla pre-elaborazione dei dati all’analisi dei cluster e alla visualizzazione, programmeremo ogni passaggio. Quindi andiamo avanti!

 

Il nostro approccio: Analisi RFM e Clustering K-Means

 

Iniziamo definendo il nostro obiettivo: Applicando l’analisi RFM e il clustering K-Means a questo dataset, vogliamo ottenere informazioni sul comportamento e le preferenze dei clienti.

L’analisi RFM è un metodo semplice ma potente per quantificare il comportamento del cliente. Valuta i clienti basandosi su tre dimensioni chiave:

  • Recency (R): Da quanto tempo un determinato cliente ha effettuato un acquisto?
  • Frequency (F): Quanto spesso effettuano acquisti?
  • Monetary Value (M): Quanto denaro spendono?

Utilizzeremo le informazioni nel dataset per calcolare i valori di recency, frequency e monetary. Successivamente, mapperemo questi valori alla scala di valutazione RFM comunemente utilizzata da 1 a 5.

Se desideri, puoi esplorare e analizzare ulteriormente utilizzando questi punteggi RFM. Ma cercheremo di identificare segmenti di clienti con caratteristiche RFM simili. E per fare ciò, utilizzeremo il clustering K-Means, un algoritmo di apprendimento automatico non supervisionato che raggruppa punti dati simili in cluster.

Quindi iniziamo a programmare!

🔗 Link al notebook di Google Colab.

 

Passo 1 – Importa le librerie e i moduli necessari

 

Per prima cosa, importiamo le librerie necessarie e i moduli specifici quando necessario:

import pandas as pdimport matplotlib.pyplot as pltfrom sklearn.cluster import KMeans

 

Ai fini dell’esplorazione e della visualizzazione dei dati, abbiamo bisogno di pandas e matplotlib, e della classe KMeans dal modulo cluster di scikit-learn per eseguire il clustering K-Means.

 

Passo 2 – Carica il dataset

 

Come accennato, utilizzeremo il dataset Online Retail. Il dataset contiene record dei clienti: informazioni transazionali, inclusi date di acquisto, quantità, prezzi e ID dei clienti.

Leggiamo i dati dal file excel nell’URL in un dataframe di pandas.

# Carica il dataset dal repository UCIurl = "https://archive.ics.uci.edu/ml/machine-learning-databases/00352/Online%20Retail.xlsx"data = pd.read_excel(url)

 

In alternativa, puoi scaricare il dataset e leggere il file excel in un dataframe di pandas.

 

Passo 3 – Esplora e pulisci il dataset

 

Adesso iniziamo ad esplorare il dataset. Guarda le prime righe del dataset:

data.head()

 

 

Ora chiama il metodo describe() sul dataframe per capire meglio le caratteristiche numeriche:

data.describe()

 

Vediamo che la colonna “CustomerID” è attualmente un valore floating point. Quando puliremo i dati, lo convertiremo in un intero:  

Nota anche che il dataset è abbastanza rumoroso. Le colonne “Quantity” e “UnitPrice” contengono valori negativi:

  

Diamo un’occhiata più da vicino alle colonne e ai loro tipi di dati:

data.info()

 

Vediamo che il dataset ha più di 541K record e le colonne “Description” e “CustomerID” contengono valori mancanti:  Prendiamo il conteggio dei valori mancanti in ogni colonna:

# Verifica i valori mancanti in ogni colonna missing_values = data.isnull().sum()print(missing_values)

 

Come previsto, le colonne “CustomerID” e “Description” contengono dei valori mancanti: 

  

Per la nostra analisi, non abbiamo bisogno della descrizione del prodotto contenuta nella colonna “Description”. Tuttavia, abbiamo bisogno di “CustomerID” per i passaggi successivi nella nostra analisi. Quindi eliminiamo i record con “CustomerID” mancanti:

# Elimina le righe con "CustomerID" mancanti data.dropna(subset=['CustomerID'], inplace=True)

 

Ricorda anche che i valori nelle colonne “Quantity” e “UnitPrice” dovrebbero essere strettamente positivi. Ma contengono valori negativi. Quindi eliminiamo anche i record con valori negativi per “Quantity” e “UnitPrice”:

# Rimuovi le righe con Quantity e Price negativi data = data[(data['Quantity'] > 0) & (data['UnitPrice'] > 0)]

 

Convertiamo anche “CustomerID” in un intero:

data['CustomerID'] = data['CustomerID'].astype(int)# Verifica la conversione del tipo di datiprint(data.dtypes)

 

 

Passaggio 4 – Calcola Recency, Frequency e Monetary Value

 

Iniziamo definendo una data di riferimento snapshot_date che è un giorno successivo alla data più recente nella colonna “InvoiceDate”:

snapshot_date = max(data['InvoiceDate']) + pd.DateOffset(days=1)

 

Successivamente, crea una colonna “Total” che contenga Quantity*UnitPrice per tutti i record:

data['Total'] = data['Quantity'] * data['UnitPrice']

 

Per calcolare la Recency, Frequency e MonetaryValue, calcoliamo quanto segue —raggruppato per CustomerID:

  • Per recency, calcoleremo la differenza tra la data di acquisto più recente e una data di riferimento (snapshot_date). Questo ci dà il numero di giorni trascorsi dall’ultimo acquisto del cliente. Quindi i valori più piccoli indicano che un cliente ha effettuato un acquisto più di recente. Ma quando parliamo di punteggi di recency, vorremmo che i clienti che hanno acquistato di recente abbiano un punteggio di recency più alto, giusto? Gestiremo questo nel prossimo passaggio.
  • Perché frequency misura la frequenza con cui un cliente effettua acquisti, lo calcoliamo come il totale del numero di fatture o transazioni uniche effettuate da ciascun cliente.
  • Monetary value quantifica la quantità di denaro che un cliente spende. Quindi troveremo la media del valore monetario totale delle transazioni.
rfm = data.groupby('CustomerID').agg({    'InvoiceDate': lambda x: (snapshot_date - x.max()).days,    'InvoiceNo': 'nunique',    'Total': 'sum'})

 

Rinominiamo le colonne per una migliore leggibilità:

rfm.rename(columns={'InvoiceDate': 'Recency', 'InvoiceNo': 'Frequency', 'Total': 'MonetaryValue'}, inplace=True)rfm.head()

 

 

Passaggio 5 – Mappa i valori RFM su una scala da 1 a 5 

 

Ora mappiamo le colonne “Recency”, “Frequency” e “MonetaryValue” in valori su una scala da 1 a 5, ossia {1,2,3,4,5}.

Assegneremo essenzialmente i valori a cinque differenti fasce e mapperemo ogni fascia a un valore. Per aiutarci a fissare i limiti delle fasce, utilizziamo i valori quantili delle colonne “Recency”, “Frequency” e “MonetaryValue”:

rfm.describe()

 

 

Ecco come definiamo i limiti personalizzati delle fasce:

# Calcola i limiti personalizzati delle fasce per i punteggi di Recency, Frequency e Monetary Scoresrecency_bins = [rfm['Recency'].min()-1, 20, 50, 150, 250, rfm['Recency'].max()]frequency_bins = [rfm['Frequency'].min() - 1, 2, 3, 10, 100, rfm['Frequency'].max()]monetary_bins = [rfm['MonetaryValue'].min() - 3, 300, 600, 2000, 5000, rfm['MonetaryValue'].max()]

 

Ora che abbiamo definito i limiti delle fasce, mappiamo i punteggi alle etichette corrispondenti tra 1 e 5 (inclusi entrambi):

# Calcola il punteggio di Recency basato sulle fasce personalizzate rfm['R_Score'] = pd.cut(rfm['Recency'], bins=recency_bins, labels=range(1, 6), include_lowest=True)# Inveriamo i punteggi di Recency in modo che valori più alti indicano acquisti più recentirfm['R_Score'] = 5 - rfm['R_Score'].astype(int) + 1# Calcola i punteggi di Frequency e Monetary basati sulle fasce personalizzaterfm['F_Score'] = pd.cut(rfm['Frequency'], bins=frequency_bins, labels=range(1, 6), include_lowest=True).astype(int)rfm['M_Score'] = pd.cut(rfm['MonetaryValue'], bins=monetary_bins, labels=range(1, 6), include_lowest=True).astype(int)

 

Nota che il punteggio R_Score, basato sulle fasce, è 1 per gli acquisti recenti e 5 per tutti gli acquisti effettuati più di 250 giorni fa. Ma vorremmo che gli acquisti più recenti abbiano un R_Score di 5 e gli acquisti effettuati più di 250 giorni fa abbiano un R_Score di 1.

Per ottenere la mappatura desiderata, facciamo: 5 - rfm['R_Score'].astype(int) + 1.

Diamo uno sguardo alle prime righe delle colonne R_Score, F_Score e M_Score:

# Stampa le prime righe del DataFrame RFM per verificare i punteggiprint(rfm[['R_Score', 'F_Score', 'M_Score']].head(10))

 

 

Se desideri, puoi utilizzare questi punteggi R, F e M per condurre un’analisi approfondita. O utilizzare il clustering per identificare segmenti con caratteristiche RFM simili. Noi sceglieremo quest’ultima opzione!

 

Passaggio 6 – Esegui il clustering K-Means

 

Il clustering K-Means è sensibile alla scala delle caratteristiche. Poiché i valori R, F e M sono tutti sulla stessa scala, possiamo procedere a eseguire il clustering senza ulteriori ridimensionamenti delle caratteristiche. 

Estraiamo i punteggi R, F e M per eseguire il clustering K-Means:

# Estrai i punteggi RFM per il clustering K-mansX = rfm[['Punteggio_R', 'Punteggio_F', 'Punteggio_M']]

 

Successivamente, dobbiamo trovare il numero ottimale di cluster. A tal fine, eseguiamo l’algoritmo K-Means per una serie di valori K e utilizziamo il metodo del gomito per scegliere il K ottimale:

# Calcola l'inerzia (somma delle distanze quadrate) per diversi valori dik = []for k in range(2, 11):    kmeans = KMeans(n_clusters=k, n_init=10, random_state=42)    kmeans.fit(X)    inertia.append(kmeans.inertia_)# Traccia la curva del gomitolopl.figure(figsize=(8, 6), dpi=150)plt.plot(range(2, 11), inertia, marker='o')plt.xlabel('Numero di cluster (k)')plt.ylabel('Inerzia')plt.title('Curva del gomito per il clustering K-means')plt.grid(True)plt.show()

 

Vediamo che la curva forma un gomito a 4 cluster. Quindi dividiamo la base di clientela in quattro segmenti.

  

Abbiamo fissato K a 4. Quindi eseguiamo l’algoritmo K-Means per ottenere l’assegnazione del cluster per tutti i punti nel dataset:

# Esegui il clustering K-means con il miglior Kbest_kmeans = KMeans(n_clusters=4, n_init=10, random_state=42)rfm['Cluster'] = best_kmeans.fit_predict(X)

 

Step 7 – Interpreta i cluster per identificare i segmenti di clienti 

 

Ora che abbiamo i cluster, cerchiamo di caratterizzarli in base ai punteggi RFM.

# Raggruppa per cluster e calcola i valori medi di ciò che riporta     'Punteggio_R': 'media',    'Punteggio_F': 'media',    'Punteggio_M': 'media'}).reimpostare_indice()

 

I punteggi medi di R, F e M per ogni cluster dovrebbero darti già un’idea delle caratteristiche. 

stampa(cluster_summary)

 

 

Ma visualizziamo i punteggi medi di R, F e M per i cluster in modo che sia facile da interpretare:

colors = ['#3498db', '#2ecc71', '#f39c12', '#C9B1BD']# Traccia i punteggi medi di RFM per ogni clusterplt.figure(figsize=(10, 8), dpi=150)# Traccia la recency mediatatlt.subplot(3, 1, 1)bars = plt.bar(cluster_summary.index, cluster_summary['Punteggio_R'], color=colors)plt.xlabel('Cluster')plt.ylabel('Recency media')plt.title('Recency media per ogni cluster')plt.grid(True, linestyle='--', alpha=0.5)plt.legend(bars, cluster_summary.index, title='Cluster')# Plot Avg Frequenciestlt.subplot(3, 1, 2)bars = plt.bar(cluster_summary.index, cluster_summary['Punteggio_F'], color=colors)plt.xlabel('Cluster')plt.ylabel('Frequenza media')plt.title('Frequenza media per ogni cluster')plt.grid(True, linestyle='--', alpha=0.5)plt.legend(bars, cluster_summary.index, title='Cluster')# Plot Avg Monetaryplt.subplot(3, 1, 3)bars = plt.bar(cluster_summary.index, cluster_summary['Punteggio_M'], color=colors)plt.xlabel('Cluster')plt.ylabel('Valore medio monetario')plt.title('Valore monetario medio per ogni cluster')plt.grid(True, linestyle='--', alpha=0.5)plt.legend(bars, cluster_summary.index, title='Cluster')plt.tight_layout()plt.show()

 

 

Osserva come i clienti in ciascun segmento possono essere caratterizzati in base ai valori di recentità, frequenza e valore monetario:

  • Cluster 0: Di tutti e quattro i cluster, questo cluster ha il maggiore valore di recentità, frequenza e valore monetario. Chiamiamo i clienti in questo cluster campioni (o acquirenti potenti).
  • Cluster 1: Questo cluster è caratterizzato da un valore moderato di recentità, frequenza e valore monetario. Questi clienti spendono ancora di più e acquistano con maggiore frequenza rispetto ai cluster 2 e 3. Chiamiamoli clienti fedeli.
  • Cluster 2: I clienti in questo cluster tendono a spendere di meno. Non comprano spesso e non hanno fatto un acquisto di recente. Questi sono probabilmente clienti inattivi o clienti a rischio.
  • Cluster 3: Questo cluster è caratterizzato da una recentità elevata e da una frequenza relativamente più bassa e da un valore monetario moderato. Quindi questi sono clienti recenti che possono diventare potenziali clienti a lungo termine.

Ecco alcuni esempi di come puoi adattare gli sforzi di marketing – per mirare ai clienti in ciascun segmento – per migliorare l’interazione e la fidelizzazione dei clienti:

  • Per i Campioni / Acquirenti Potenti: Offrire sconti speciali personalizzati, accesso anticipato e altri privilegi premium per farli sentire valorizzati e apprezzati.
  • Per i Clienti Fedeli: Campagne di apprezzamento, bonus per i riferimenti e ricompense per la fedeltà.
  • Per i Clienti a Rischio: Sforzi di rientro che includono sconti o promozioni per incoraggiare gli acquisti.
  • Per i Clienti Recenti: Campagne mirate per informarli sul marchio e sconti sugli acquisti successivi.

È anche utile capire quale percentuale di clienti si trova nei diversi segmenti. Ciò aiuterà ulteriormente a razionalizzare gli sforzi di marketing e far crescere la tua attività.

Visualizziamo la distribuzione dei diversi cluster utilizzando un grafico a torta:

cluster_counts = rfm['Cluster'].value_counts()colors = ['#3498db', '#2ecc71', '#f39c12','#C9B1BD']# Calcolare il numero totale di clientitotal_customers = cluster_counts.sum()# Calcolare la percentuale di clienti in ogni clusterpercentage_customers = (cluster_counts / total_customers) * 100labels = ['Campioni (Acquirenti Potenti)', 'Clienti Fedeli', 'Clienti a Rischio', 'Clienti Recenti']# Creare un grafico a torta plt.figure(figsize = (8, 8), dpi = 200)plt.pie(percentage_customers, labels = labels, autopct = '%1.1f%%', startangle = 90, colors = colors)plt.title('Percentuale di Clienti in Ciascun Cluster')plt.legend(cluster_summary['Cluster'], title = 'Cluster', loc = 'upper left')plt.show()

 

 

Ecco fatto! Per questo esempio, abbiamo una distribuzione abbastanza uniforme dei clienti nei segmenti. Quindi possiamo investire tempo e sforzi per mantenere i clienti esistenti, rientrare in contatto con i clienti a rischio ed educare i clienti recenti.

 

Conclusioni

 

Ecco a cosa siamo arrivati! Siamo passati da oltre 154.000 record di clienti a 4 cluster in 7 semplici passaggi. Spero che tu capisca come la segmentazione dei clienti ti consenta di prendere decisioni basate sui dati che influenzano la crescita aziendale e la soddisfazione dei clienti, permettendo:

  • Personalizzazione: La segmentazione consente alle aziende di adattare i messaggi di marketing, le raccomandazioni di prodotti e le promozioni alle esigenze e agli interessi specifici di ciascun gruppo di clienti.
  • Miglior Targeting: Identificando i clienti ad alto valore e a rischio, le aziende possono allocare le risorse in modo più efficiente, dedicando gli sforzi dove è più probabile ottenere risultati.
  • Fidelizzazione dei Clienti: La segmentazione aiuta le aziende a creare strategie di fidelizzazione capendo cosa mantiene i clienti coinvolti e soddisfatti.

Come prossimo passo, prova ad applicare questo approccio a un altro dataset, documenta il tuo percorso e condividilo con la comunità! Ma ricorda, la segmentazione efficace dei clienti e l’esecuzione di campagne mirate richiede una buona comprensione della tua base di clienti e di come essa evolve nel tempo. Quindi è necessaria un’analisi periodica per perfezionare le tue strategie nel tempo.

 

Crediti del Dataset

 

Il Online Retail Dataset è concesso in licenza con una licenza Creative Commons Attribution 4.0 International (CC BY 4.0):

Online Retail. (2015). UCI Machine Learning Repository. https://doi.org/10.24432/C5BW33.  Bala Priya C è una sviluppatrice e scrittrice tecnica dall’India. Le piace lavorare all’intersezione tra matematica, programmazione, data science e creazione di contenuti. Le sue aree di interesse e competenza includono DevOps, data science e natural language processing. Ama leggere, scrivere, programmare e bere caffè! Al momento sta lavorando per imparare e condividere la sua conoscenza con la comunità degli sviluppatori scrivendo tutorial, guide pratiche, pezzi di opinione e altro ancora.

[Bala Priya C](https://twitter.com/balawc27) è una sviluppatrice e scrittrice tecnica dall’India. Le piace lavorare all’intersezione tra matematica, programmazione, data science e creazione di contenuti. Le sue aree di interesse e competenza includono DevOps, data science e natural language processing. Ama leggere, scrivere, programmare e bere caffè! Al momento sta lavorando per imparare e condividere la sua conoscenza con la comunità degli sviluppatori scrivendo tutorial, guide pratiche, pezzi di opinione e altro ancora.