Il concetto di “main shift” con il clustering nel machine learning si riferisce alla ricerca del cambiamento principale o dominante nei dati attraverso l’analisi dei cluster. In sostanza, il main shift indica la direzione o il fenomeno predominante nei dati, rivelato tramite il clustering. Quando si applica il clustering ai dati, si cercano gruppi o cluster di punti dati che condividono caratteristiche simili. Identificando il main shift, si cerca di capire quale cluster o gruppo rappresenta il cambiamento principale o dominante nei dati. Questo può essere utile per comprendere i cambiamenti nei comportamenti dei dati nel tempo, individuare anomalie o identificare tendenze significative.
Il Main Shift
Mean Shift è un algoritmo di clustering relativamente più recente rispetto ad alcuni dei suoi predecessori, come K-Means o DBSCAN. È stato introdotto per la prima volta nel 1992 da Dorin Comaniciu e Peter Meer nel loro articolo intitolato “Mean Shift: A Robust Approach Toward Feature Space Analysis”.
L’idea alla base di Mean Shift risale al concetto di “modalità” o “picchi” in un insieme di dati, che si riferisce ai punti in cui la densità dei dati è massima. L’obiettivo dell’algoritmo Mean Shift è identificare queste modalità o picchi nei dati e raggruppare insieme i punti che appartengono a ciascuna modalità.
Il nome “Mean Shift” deriva dal fatto che l’algoritmo opera spostando iterativamente i punti nel dataset verso la direzione della massima crescita della densità, cioè verso la “modalità” più vicina. Questo processo di “shift” dei punti in direzione della massima densità continua finché i punti non convergono verso le modalità dei cluster.
Negli anni successivi alla sua introduzione, Mean Shift è diventato popolare per la sua capacità di identificare cluster di forma arbitraria e di dimensioni variabili senza la necessità di specificare a priori il numero di cluster. È stato utilizzato con successo in diversi campi, tra cui computer vision, analisi dei dati e riconoscimento di pattern.
Definizione del Kernel: Iniziamo definendo una funzione kernel, solitamente una gaussiana, che misura la densità dei punti nei dati. Un esempio di kernel gaussiano è dato da:
Dove
Calcolo della Density Estimate: Utilizzando il kernel, possiamo calcolare la stima della densità dei dati in ogni punto. Questo può essere espresso come:
Dove:
è il numero di punti dati. è il parametro della finestra di banda. è la dimensione dello spazio. sono i punti dati.
Calcolo del Mean Shift Vector: Per ogni punto nel dataset, calcoliamo un vettore che punta verso l’area di massima densità. Questo è ottenuto calcolando il gradient descent della stima della densità:
Dove
Aggiornamento dei Punti: Muoviamo ogni punto nel dataset nella direzione del mean shift vector calcolato:
Convergenza: Ripetiamo i passaggi 3 e 4 fino a quando i punti convergono verso i massimi locali della densità.
Una volta completato il Mean Shift Clustering, identifichiamo il “main shift” osservando le regioni di alta densità ottenute. Queste regioni rappresentano i cluster o gruppi di dati con la maggiore concentrazione.
In sintesi, il main shift con il clustering del machine learning si riferisce alla ricerca delle regioni di massima densità nei dati attraverso l’analisi dei cluster, utilizzando tecniche come il Mean Shift Clustering per identificare i punti di maggiore concentrazione o cambiamento.
Il Mean Shift clustering con scikit-learn
In questo passaggio, generiamo un set di dati di esempio utilizzando la funzione make_blobs()
di scikit-learn. Questa funzione crea un numero specificato di cluster casuali, ciascuno centrato in posizioni casuali nello spazio delle caratteristiche.
from sklearn.cluster import MeanShift
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.6, random_state=0)
# Visualize the generated data
plt.scatter(X[:, 0], X[:, 1], s=50)
plt.title('Generated Data')
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.show()
Eseguendo si ottiene il seguente risultato:
Adesso che abbiamo dei dati possiamo applicarci il Main Shift per individuare i cluster presenti
from sklearn.cluster import MeanShift, estimate_bandwidth
import numpy as np
# Generate sample data
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.6, random_state=0)
# Estimate bandwidth
bandwidth = estimate_bandwidth(X, quantile=0.2, n_samples=len(X))
# Create MeanShift object
ms = MeanShift(bandwidth=bandwidth)
# Fit the model
ms.fit(X)
# Cluster labels
labels = ms.labels_
# Number of clusters obtained
n_clusters = len(np.unique(labels))
print("Number of clusters obtained:", n_clusters)
# Plot the results
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')
plt.title('Mean Shift Clustering')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.show()
Per prima cosa, utilizziamo la funzione estimate_bandwidth()
di scikit-learn per stimare una buona larghezza della finestra di banda basata sui dati. Il parametro quantile
controlla quanto stretta o ampia sarà la finestra di banda rispetto alla distribuzione dei dati. Creiamo un’istanza della classe MeanShift
di scikit-learn e specifichiamo la larghezza della finestra di banda calcolata nel passaggio precedente come parametro bandwidth
. Addestriamo il modello Mean Shift utilizzando i dati di addestramento X
.
Eseguendo il codice si ottiene il risultato atteso:
Il parametro bandwidth
Il parametro di “bandwidth” (larghezza della finestra di banda) è un parametro chiave nell’algoritmo Mean Shift che determina la scala su cui la densità dei dati viene valutata durante il processo di clustering. In altre parole, controlla la distanza a cui vengono considerati i punti circostanti quando si calcola la densità dei dati in un determinato punto.
La necessità del parametro di “bandwidth” deriva dal fatto che Mean Shift si basa sulla ricerca dei massimi locali nella stima della densità dei dati. Una larghezza di banda troppo piccola può portare a una suddivisione eccessiva dei dati in numerosi piccoli cluster, mentre una larghezza di banda troppo grande può portare a una perdita di dettaglio e alla sovrapposizione dei cluster.
In sostanza, la larghezza della finestra di banda influisce direttamente sulla sensibilità del modello Mean Shift nel riconoscere i cluster nei dati. Un valore appropriato di bandwidth è quindi cruciale per ottenere un corretto riconoscimento dei cluster. Se la larghezza della finestra di banda è impostata correttamente, l’algoritmo sarà in grado di identificare i cluster in base alla densità locale dei dati, catturando correttamente le variazioni nei dati e raggruppando insieme i punti che condividono una densità simile.
In pratica, è spesso consigliabile stimare la larghezza della finestra di banda utilizzando tecniche come la stima automatica tramite la funzione estimate_bandwidth()
di scikit-learn, come nel caso dell’esempio che ti ho mostrato in precedenza. Questo permette di adattare la larghezza della finestra di banda in base alla distribuzione dei dati specifici e può migliorare significativamente le prestazioni del clustering con Mean Shift.
Valutazione dei risultati ottenuti
E’ possibile calcolare il coefficiente di validità interni come l’indice di Silhouette per valutare i risultati del clustering ottenuti dal codice di esempio che abbiamo utilizzato. L’indice di Silhouette misura la coesione all’interno dei cluster e la separazione tra i cluster. Possiamo calcolare l’indice di Silhouette utilizzando la libreria scikit-learn.
Ecco come potresti farlo nel contesto del nostro codice di esempio:
from sklearn.metrics import silhouette_score
silhouette_avg = silhouette_score(X, labels)
print("Silhouette Score:", silhouette_avg)
In questo codice, X
rappresenta il nostro set di dati, e labels
sono le etichette dei cluster assegnate dall’algoritmo Mean Shift. Utilizziamo la funzione silhouette_score()
di scikit-learn per calcolare l’indice di Silhouette. Eseguendo otteniamo:
Silhouette Score: 0.6819938690643478
Il valore del Silhouette Score ottenuto, che è circa 0.682, è generalmente considerato un buon risultato. Tuttavia, la valutazione della validità di un Silhouette Score dipende dal contesto specifico dei dati e può variare in base alla natura dei dati e al problema di clustering.
Ecco una guida generale per interpretare il Silhouette Score:
- Un Silhouette Score vicino a 1 indica che i cluster sono stati ben separati e che i punti dati sono stati assegnati in modo coerente ai loro cluster.
- Un Silhouette Score vicino a 0 indica che i cluster possono avere una significativa sovrapposizione o che i punti dati possono essere vicini ai confini tra i cluster.
- Un Silhouette Score vicino a -1 indica che i punti dati potrebbero essere stati assegnati al cluster sbagliato.
Quindi, nel tuo caso, un Silhouette Score di circa 0.682 suggerisce che i cluster trovati dall’algoritmo Mean Shift hanno una buona separazione e coerenza interna. Tuttavia, è importante notare che il Silhouette Score da solo potrebbe non essere sufficiente per determinare completamente la validità dei cluster. È sempre consigliabile considerare anche altre metriche di valutazione e analizzare visivamente i risultati del clustering per ottenere una comprensione completa della qualità del clustering ottenuto.
Esistono altri due indici per la valutazione della bontà dei risultati. Infatti, si possono calcolare anche il coefficiente di Davies-Bouldin e l’indice di Dunn per valutare ulteriormente i risultati del clustering.
Ecco come calcolarli utilizzando la libreria scikit-learn e la libreria scikit-learn-extra
per l’indice di Dunn:
from sklearn.metrics import davies_bouldin_score
from sklearn_extra.cluster import KMedoids
from sklearn.metrics import pairwise_distances
from sklearn.metrics import silhouette_score
import numpy as np
# Calcolo del coefficiente di Davies-Bouldin
davies_bouldin = davies_bouldin_score(X, labels)
print("Davies-Bouldin Score:", davies_bouldin)
# Calcolo dell'indice di Dunn
def dunn_index(X, labels):
clusters = np.unique(labels)
max_diameter = max([np.max(pairwise_distances(X[labels == label])) for label in clusters])
min_intercluster_distance = min([np.min(pairwise_distances(X[labels == label], X[labels != label])) for label in clusters])
return min_intercluster_distance / max_diameter
dunn = dunn_index(X, labels)
print("Dunn Index:", dunn)
In questo codice, stiamo calcolando il coefficiente di Davies-Bouldin utilizzando la funzione davies_bouldin_score()
di scikit-learn e l’indice di Dunn tramite la funzione dunn_index()
che abbiamo definito. Entrambi questi valori ci daranno ulteriori informazioni sulla validità dei risultati del clustering. Un valore più basso per il coefficiente di Davies-Bouldin e un valore più alto per l’indice di Dunn indicano una migliore qualità del clustering. Eseguendo si ottengono:
Davies-Bouldin Score: 0.4375640078237839
Dunn Index: 0.20231427477727162
Il coefficiente di Davies-Bouldin misura la separazione tra i cluster e la coesione all’interno di ciascun cluster. Un valore più basso indica una migliore separazione tra i cluster e una maggiore coesione all’interno di ciascun cluster. Nel nostro caso, il valore di circa 0.438 suggerisce che i cluster hanno una buona separazione e coesione, il che è positivo.
L’indice di Dunn è una misura della separazione tra i cluster rispetto alla dispersione all’interno dei cluster. Un valore più alto indica una maggiore separazione tra i cluster e una minore dispersione all’interno dei cluster. Nel tuo caso, il valore di circa 0.202 suggerisce che la separazione tra i cluster è relativamente bassa rispetto alla dispersione all’interno dei cluster. Tuttavia, è importante notare che l’interpretazione dell’indice di Dunn può essere influenzata dalla scala dei dati e dalla natura dei cluster.
Quando usare il Main Shift?
Mean Shift è un algoritmo di clustering potente e flessibile, ma non è necessariamente la scelta migliore per ogni tipo di dati o problema di clustering. Tuttavia, ci sono alcune situazioni in cui Mean Shift può essere particolarmente efficace rispetto ad altri algoritmi di clustering. Ecco alcune di esse:
- Cluster di forma non convessa: Mean Shift è efficace nel trovare cluster di forma non convessa o di forma irregolare. Poiché non fa alcuna assunzione sulla forma dei cluster, può gestire forme complesse e più flessibili rispetto a metodi basati su ipotesi come K-Means.
- Cluster di dimensioni diverse: Mean Shift non richiede la specifica del numero di cluster a priori e può trovare automaticamente cluster di diverse dimensioni. È particolarmente utile quando i cluster hanno variazioni significative nella densità e nelle dimensioni.
- Cluster con densità variabile: Mean Shift è sensibile alla densità dei dati e può gestire efficacemente cluster con densità variabile. È in grado di adattare la larghezza della finestra di banda per riflettere la variazione della densità dei dati, consentendo di identificare correttamente i cluster anche in regioni di densità diversa.
- Pochi iperparametri da ottimizzare: Mean Shift ha solo un iperparametro principale da ottimizzare, cioè la larghezza della finestra di banda. Questo lo rende relativamente semplice da utilizzare e meno sensibile alla scelta dei parametri rispetto ad altri algoritmi di clustering che richiedono la specifica del numero di cluster.
Tuttavia, Mean Shift potrebbe non essere la scelta migliore in tutte le situazioni. Ad esempio:
- Grande set di dati: Mean Shift può essere computazionalmente costoso su set di dati molto grandi a causa della sua complessità computazionale. In questo caso, algoritmi più efficienti come K-Means o DBSCAN potrebbero essere preferibili.
- Cluster di forma globale definita: Se i cluster sono di forma globale definita e sono chiaramente separabili, algoritmi basati su distanze come K-Means o algoritmi gerarchici possono produrre risultati più efficienti e interpretabili.
- Dati con rumore significativo: Se i dati contengono un elevato livello di rumore o punti anomali, Mean Shift potrebbe avere difficoltà nel gestirli efficacemente. In questo caso, DBSCAN o altri algoritmi di clustering basati su densità potrebbero essere più adatti.