Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Guida definitiva al clustering K-Means con Scikit-Learn

Introduzione

Raggruppamento dei mezzi K è uno degli algoritmi di apprendimento automatico non supervisionato più utilizzati che formano cluster di dati in base alla somiglianza tra le istanze di dati.

In questa guida, daremo prima un'occhiata a un semplice esempio per capire come funziona l'algoritmo K-Means prima di implementarlo utilizzando Scikit-Learn. Quindi, discuteremo come determinare il numero di cluster (K) in K-medie e copriremo anche le metriche di distanza, la varianza e i vantaggi e svantaggi delle K-medie.

Motivazione

Immagina la seguente situazione. Un giorno, passeggiando per il quartiere, hai notato che c'erano 10 minimarket e hai iniziato a chiederti quali negozi fossero simili, più vicini l'uno all'altro. Durante la ricerca di modi per rispondere a questa domanda, ti sei imbattuto in un approccio interessante che divide i negozi in gruppi in base alle loro coordinate su una mappa.

Ad esempio, se un negozio si trova a 5 km a ovest e 3 km a nord, lo assegneresti (5, 3) coordinate ad esso e rappresentarlo in un grafico. Tracciamo questo primo punto per visualizzare cosa sta succedendo:

import matplotlib.pyplot as plt

plt.title("Store With Coordinates (5, 3)")
plt.scatter(x=5, y=3)

Questo è solo il primo punto, quindi possiamo farci un'idea di come possiamo rappresentare un negozio. Supponiamo di avere già 10 coordinate per i 10 negozi raccolti. Dopo averli organizzati in a numpy array, possiamo anche tracciare le loro posizioni:

import numpy as np

points = np.array([[5, 3], [10, 15], [15, 12], [24, 10], [30, 45], [85, 70], [71, 80], [60, 78], [55, 52],[80, 91]])

xs = points[:,0] 
ys = points[:,1]  

plt.title("10 Stores Coordinates")
plt.scatter(x=xs, y=ys)

Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Come implementare manualmente l'algoritmo K-Means

Ora possiamo guardare i 10 negozi su un grafico e il problema principale è trovare un modo per dividerli in diversi gruppi in base alla vicinanza? Solo dando una rapida occhiata al grafico, probabilmente lo noteremo due gruppi di negozi – uno è il punto inferiore in basso a sinistra e l'altro è il punto in alto a destra. Forse possiamo anche differenziare quei due punti nel mezzo come un gruppo separato, creando quindi tre diversi gruppi.

In questa sezione, esamineremo il processo di raggruppamento manuale dei punti, dividendoli nel numero di gruppi specificato. In questo modo, essenzialmente esamineremo attentamente tutti i passaggi del Algoritmo di clustering K-Means. Alla fine di questa sezione, acquisirai una comprensione sia intuitiva che pratica di tutti i passaggi eseguiti durante il clustering K-Means. Successivamente, lo delegheremo a Scikit-Learn.

Quale sarebbe il modo migliore per determinare se ci sono due o tre gruppi di punti? Un modo semplice sarebbe quello di scegliere semplicemente un numero di gruppi, ad esempio due, e quindi provare a raggruppare i punti in base a quella scelta.

Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Diciamo che abbiamo deciso che ci sono due gruppi dei nostri negozi (punti). Ora, dobbiamo trovare un modo per capire quali punti appartengono a quale gruppo. Questo potrebbe essere fatto scegliendo un punto da rappresentare gruppo 1 e uno da rappresentare gruppo 2. Tali punti verranno utilizzati come riferimento durante la misurazione della distanza da tutti gli altri punti a ciascun gruppo.

In questo modo, dì punto (5, 3) finisce per appartenere al gruppo 1, e punto (79, 60) al gruppo 2. Quando si tenta di assegnare un nuovo punto (6, 3) ai gruppi, dobbiamo misurare la sua distanza da quei due punti. Nel caso del punto (6, 3) is più vicino Vai all’email (5, 3), quindi appartiene al gruppo rappresentato da quel punto – gruppo 1. In questo modo, possiamo facilmente raggruppare tutti i punti nei gruppi corrispondenti.

In questo esempio, oltre a determinare il numero di gruppi (cluster) – stiamo anche scegliendo alcuni punti per essere a riferimento di distanza per i nuovi punti di ogni gruppo.

Questa è l'idea generale per capire le somiglianze tra i nostri negozi. Mettiamolo in pratica: possiamo prima scegliere i due punti di riferimento a casuale. Il punto di riferimento di gruppo 1 sarà (5, 3) e il punto di riferimento di gruppo 2 sarà (10, 15). Possiamo selezionare entrambi i punti del ns numpy array per [0] ed [1] indicizza e li archivia g1 (gruppo 1) e g2 (gruppo 2) variabili:

g1 = points[0]
g2 = points[1]

Dopo aver fatto ciò, dobbiamo calcolare la distanza da tutti gli altri punti a quei punti di riferimento. Ciò solleva una domanda importante: come misurare quella distanza. Possiamo essenzialmente utilizzare qualsiasi misura di distanza, ma, ai fini di questa guida, utilizziamo Distanza euclidea_.

Può essere utile sapere che la misura della distanza euclidea si basa sul teorema di Pitagora:

$$
c^2 = a^2 + b^2
$$

Quando adattato a punti in un piano – (a1, b1) ed (a2, b2), la formula precedente diventa:

$$
c^2 = (a2-a1)^2 + (b2-b1)^2
$$

La distanza sarà la radice quadrata di c, quindi possiamo anche scrivere la formula come:

$$
euclidea_{dist} = sqrt[2][(a2 – a1)^2 + (b2 – b1) ^2)]
$$

Nota: Puoi anche generalizzare la formula della distanza euclidea per punti multidimensionali. Ad esempio, in uno spazio tridimensionale, i punti hanno tre coordinate: la nostra formula lo riflette nel modo seguente:
$$
euclidea_{dist} = sqrt[2][(a2 – a1)^2 + (b2 – b1) ^2 + (c2 – c1) ^2)]
$$
Lo stesso principio viene seguito indipendentemente dal numero di dimensioni dello spazio in cui operiamo.

Finora abbiamo selezionato i punti per rappresentare i gruppi e sappiamo come calcolare le distanze. Ora, mettiamo insieme le distanze e i gruppi assegnando ciascuno dei nostri punti negozio raccolti a un gruppo.

Per visualizzarlo meglio, dichiareremo tre liste. Il primo a memorizzare punti del primo gruppo – points_in_g1. Il secondo per memorizzare punti dal gruppo 2 – points_in_g2, e l'ultimo - group, etichetta i punti come entrambi 1 (appartiene al gruppo 1) o 2 (appartiene al gruppo 2):

points_in_g1 = []
points_in_g2 = []
group = []

Ora possiamo scorrere i nostri punti e calcolare la distanza euclidea tra loro e ciascuno dei nostri riferimenti di gruppo. Ogni punto sarà più vicino a uno dei due gruppi: in base a quale gruppo è più vicino, assegneremo ciascun punto all'elenco corrispondente, aggiungendo anche 1 or 2 Vai all’email group elenco:

for p in points:
    x1, y1 = p[0], p[1]
    euclidean_distance_g1 = np.sqrt((g1[0] - x1)**2 + (g1[1] - y1)**2)
    euclidean_distance_g2 = np.sqrt((g2[0] - x1)**2 + (g2[1] - y1)**2)
    if euclidean_distance_g1 < euclidean_distance_g2:
        points_in_g1.append(p)
        group.append('1')
    else:
        points_in_g2.append(p)
        group.append('2')

Diamo un'occhiata ai risultati di questa iterazione per vedere cosa è successo:

print(f'points_in_g1:{points_in_g1}n 
npoints_in_g2:{points_in_g2}n 
ngroup:{group}')

Che si traduce in:

points_in_g1:[array([5, 3])]
 
points_in_g2:[array([10, 15]), array([15, 12]), 
              array([24, 10]), array([30, 45]), 
              array([85, 70]), array([71, 80]),
              array([60, 78]), array([55, 52]), 
              array([80, 91])]
 
group:[1, 2, 2, 2, 2, 2, 2, 2, 2, 2] 

Possiamo anche tracciare il risultato del clustering, con colori diversi in base ai gruppi assegnati, usando Seaborn's scatterplot() con la group come hue argomento:

import seaborn as sns

sns.scatterplot(x=points[:, 0], y=points[:, 1], hue=group)

Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

È chiaramente visibile che solo il nostro primo punto è assegnato al gruppo 1 e tutti gli altri punti sono stati assegnati al gruppo 2. Questo risultato differisce da quello che avevamo immaginato all'inizio. Considerando la differenza tra i nostri risultati e le nostre aspettative iniziali, c'è un modo in cui potremmo cambiarlo? Sembra che ci sia!

Un approccio consiste nel ripetere il processo e scegliere punti diversi come riferimenti dei gruppi. Questo cambierà i nostri risultati, si spera, più in linea con ciò che abbiamo immaginato all'inizio. Questa seconda volta, potremmo sceglierli non a caso come abbiamo fatto in precedenza, ma ottenendo un significare di tutti i nostri punti già raggruppati. In questo modo, quei nuovi punti potrebbero essere posizionati nel mezzo dei gruppi corrispondenti.

Ad esempio, se il secondo gruppo avesse solo punti (10, 15), (30, 45). La nuova centrale punto sarebbe (10 + 30)/2 ed (15+45)/2 – che è uguale a (20, 30).

Poiché abbiamo inserito i nostri risultati in elenchi, possiamo prima convertirli in numpy array, seleziona i loro xs, ys e quindi ottieni il significare:

g1_center = [np.array(points_in_g1)[:, 0].mean(), np.array(points_in_g1)[:, 1].mean()]
g2_center = [np.array(points_in_g2)[:, 0].mean(), np.array(points_in_g2)[:, 1].mean()]
g1_center, g2_center

Consigli: Prova ad usare numpy e gli array NumPy il più possibile. Sono ottimizzati per prestazioni migliori e semplificano molte operazioni di algebra lineare. Ogni volta che stai cercando di risolvere un problema di algebra lineare, dovresti assolutamente dare un'occhiata a numpy documentazione per verificare se esiste numpy metodo studiato per risolvere il tuo problema. La possibilità è che ci sia!

Per aiutare a ripetere il processo con i nostri nuovi punti centrali, trasformiamo il nostro codice precedente in una funzione, eseguiamolo e vediamo se ci sono stati cambiamenti nel modo in cui i punti sono raggruppati:

def assigns_points_to_two_groups(g1_center, g2_center):
    points_in_g1 = []
    points_in_g2 = []
    group = []

    for p in points:
        x1, y1 = p[0], p[1]
        euclidean_distance_g1 = np.sqrt((g1_center[0] - x1)**2 + (g1_center[1] - y1)**2)
        euclidean_distance_g2 = np.sqrt((g2_center[0] - x1)**2 + (g2_center[1] - y1)**2)
        if euclidean_distance_g1 < euclidean_distance_g2:
            points_in_g1.append(p)
            group.append(1)
        else:
            points_in_g2.append(p)
            group.append(2)
    return points_in_g1, points_in_g2, group

Nota: Se noti che continui a ripetere lo stesso codice più e più volte, dovresti racchiudere quel codice in una funzione separata. È considerata una buona pratica organizzare il codice in funzioni, soprattutto perché facilitano il test. È più facile testare e isolare una parte di codice rispetto a un codice completo senza alcuna funzione.

Chiamiamo la funzione e memorizziamo i suoi risultati in points_in_g1, points_in_g2e group variabili:

points_in_g1, points_in_g2, group = assigns_points_to_two_groups(g1_center, g2_center)
points_in_g1, points_in_g2, group

E traccia anche il grafico a dispersione con i punti colorati per visualizzare la divisione dei gruppi:

sns.scatterplot(x=points[:, 0], y=points[:, 1], hue=group)

Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Sembra che il raggruppamento dei nostri punti lo sia migliorare. Tuttavia, ci sono due punti nel mezzo del grafico che potrebbero essere assegnati a entrambi i gruppi quando si considera la loro vicinanza a entrambi i gruppi. L'algoritmo che abbiamo sviluppato finora assegna entrambi questi punti al secondo gruppo.

Ciò significa che probabilmente possiamo ripetere il processo ancora una volta prendendo la media delle X e delle Y, creando due nuovi punti centrali (centroidi) ai nostri gruppi e riassegnandoli in base alla distanza.

Creiamo anche una funzione per aggiornare i centroidi. L'intero processo ora può essere ridotto a più chiamate di quella funzione:

def updates_centroids(points_in_g1, points_in_g2):
    g1_center = np.array(points_in_g1)[:, 0].mean(), np.array(points_in_g1)[:, 1].mean()
    g2_center = np.array(points_in_g2)[:, 0].mean(), np.array(points_in_g2)[:, 1].mean()
    return g1_center, g2_center

g1_center, g2_center = updates_centroids(points_in_g1, points_in_g2)
points_in_g1, points_in_g2, group = assigns_points_to_two_groups(g1_center, g2_center)
sns.scatterplot(x=points[:, 0], y=points[:, 1], hue=group)

Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Si noti che dopo questa terza iterazione, ciascuno dei punti ora appartiene a cluster diversi. Sembra che i risultati stiano migliorando: facciamolo ancora una volta. Ora andando al quarta iterazione del nostro metodo:

g1_center, g2_center = updates_centroids(points_in_g1, points_in_g2)
points_in_g1, points_in_g2, group = assigns_points_to_two_groups(g1_center, g2_center)
sns.scatterplot(x=points[:, 0], y=points[:, 1], hue=group)

Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Questa quarta volta abbiamo ottenuto lo stesso risultato come il precedente. Quindi sembra che i nostri punti non cambieranno più i gruppi, il nostro risultato ha raggiunto una sorta di stabilità – è arrivato a uno stato immutabile, o convergente. Oltre a ciò, abbiamo esattamente lo stesso risultato che avevamo previsto per i 2 gruppi. Possiamo anche vedere se questa divisione raggiunta ha senso.

Ricapitoliamo rapidamente ciò che abbiamo fatto finora. Abbiamo diviso geograficamente i nostri 10 negozi in due sezioni: una nelle regioni del sud-ovest inferiore e altre nel nord-est. Può essere interessante raccogliere più dati oltre a quelli che già abbiamo: entrate, numero giornaliero di clienti e molti altri. In questo modo possiamo condurre un'analisi più ricca e possibilmente generare risultati più interessanti.

Studi di clustering come questo possono essere condotti quando un marchio già affermato vuole scegliere un'area per aprire un nuovo negozio. In tal caso, oltre alla posizione, vengono prese in considerazione molte altre variabili.

Cosa ha a che fare tutto questo con l'algoritmo K-Means?

Mentre segui questi passaggi, potresti esserti chiesto cosa hanno a che fare con l'algoritmo K-Means. Il processo che abbiamo condotto finora è il Algoritmo K-Means. In breve, abbiamo determinato il numero di gruppi/cluster, scelto casualmente i punti iniziali e aggiornato i centroidi in ogni iterazione fino alla convergenza dei cluster. Fondamentalmente abbiamo eseguito l'intero algoritmo a mano, conducendo attentamente ogni passaggio.

Il K in K-Mean viene da numero di cluster che devono essere impostati prima di avviare il processo di iterazione. Nel nostro caso K = 2. Questa caratteristica è talvolta vista come negativo. considerando che esistono altri metodi di clustering, come il clustering gerarchico, che non necessitano di avere un numero fisso di cluster in anticipo.

A causa del suo uso di mezzi, anche K-mean diventa sensibile a valori anomali e valori estremi – migliorano la variabilità e rendono più difficile per i nostri centroidi fare la loro parte. Quindi, sii consapevole della necessità di esibirti valori estremi e analisi dei valori anomali prima di eseguire un clustering utilizzando l'algoritmo K-Means.

Inoltre, nota che i nostri punti sono stati segmentati in parti diritte, non ci sono curve durante la creazione dei cluster. Questo può anche essere uno svantaggio dell'algoritmo K-Means.

Nota: Quando hai bisogno che sia più flessibile e adattabile a ellissi e altre forme, prova a usare a Modello generalizzato della miscela gaussiana K-means. Questo modello può adattarsi ai cluster di segmentazione ellittica.

K-Means ne ha anche molti vantaggi! Si comporta bene grandi quantità di dati che può diventare difficile da gestire se si utilizzano alcuni tipi di algoritmi di clustering gerarchico. Anche garantisce la convergenza, e può facilmente generalizzare ed adattare. Oltre a ciò, è probabilmente l'algoritmo di clustering più utilizzato.

Ora che abbiamo esaminato tutti i passaggi eseguiti nell'algoritmo K-Means e compreso tutti i suoi pro e contro, possiamo finalmente implementare K-Means utilizzando la libreria Scikit-Learn.

Come implementare l'algoritmo K-Means utilizzando Scikit-Impara

Per ricontrollare il nostro risultato, eseguiamo nuovamente questo processo, ma ora utilizzando 3 righe di codice con sklearn:

from sklearn.cluster import KMeans


kmeans = KMeans(n_clusters=2, random_state=42) 
kmeans.fit(points)
kmeans.labels_

Qui, le etichette sono le stesse dei nostri gruppi precedenti. Tracciamo rapidamente il risultato:

sns.scatterplot(x = points[:,0], y = points[:,1], hue=kmeans.labels_)

Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

La trama risultante è la stessa della sezione precedente.

Dai un'occhiata alla nostra guida pratica e pratica per l'apprendimento di Git, con le migliori pratiche, gli standard accettati dal settore e il cheat sheet incluso. Smetti di cercare su Google i comandi Git e in realtà imparare esso!

Nota: Basta guardare come abbiamo eseguito l'algoritmo K-Means usando Scikit-Learn potrebbe darti l'impressione che sia un gioco da ragazzi e che non devi preoccuparti troppo. Solo 3 righe di codice eseguono tutti i passaggi che abbiamo discusso nella sezione precedente quando abbiamo esaminato passo dopo passo l'algoritmo K-Means. Ma, il diavolo è nei dettagli in questo caso! Se non capisci tutti i passaggi e le limitazioni dell'algoritmo, molto probabilmente ti troverai di fronte alla situazione in cui l'algoritmo K-Means ti dà risultati che non ti aspettavi.

Con Scikit-Learn, puoi anche inizializzare K-Means per una convergenza più rapida impostando il init='k-means++' discussione. In termini più ampi, K-Mezzi++ sceglie ancora il k centri iniziali del cluster in modo casuale seguendo una distribuzione uniforme. Quindi, ogni successivo centro del cluster viene scelto dai punti dati rimanenti non calcolando solo una misura della distanza, ma utilizzando la probabilità. L'uso della probabilità velocizza l'algoritmo ed è utile quando si ha a che fare con set di dati molto grandi.

Il metodo del gomito: scegliere il miglior numero di gruppi

Fin qui tutto bene! Abbiamo raggruppato 10 negozi in base alla distanza euclidea tra punti e centroidi. Ma che dire di quei due punti nel mezzo del grafico che sono un po' più difficili da raggruppare? Non potrebbero formare anche loro un gruppo separato? Abbiamo davvero commesso un errore scegliendo K = 2 gruppi? Forse l'abbiamo fatto davvero K = 3 gruppi? Potremmo anche avere più di tre gruppi e non esserne consapevoli.

La domanda che viene posta qui è come determinare il numero di gruppi (K) in K-medie. Per rispondere a questa domanda, dobbiamo capire se ci sarebbe un cluster "migliore" per un diverso valore di K.

Il modo ingenuo per scoprirlo è raggruppare punti con diversi valori di K, quindi per K=2, K=3, K=4 e così via:

for number_of_clusters in range(1, 11): 
    kmeans = KMeans(n_clusters = number_of_clusters, random_state = 42)
    kmeans.fit(points) 

Ma, punti di raggruppamento per diversi Ks da solo non sarà abbastanza per capire se abbiamo scelto il valore ideale per K. Abbiamo bisogno di un modo per valutare la qualità del clustering per ciascuno K abbiamo scelto.

Calcolo manuale del All'interno della somma dei quadrati dei cluster (WCSS)

Ecco il luogo ideale per introdurre una misura di quanto i nostri punti raggruppati siano vicini l'uno all'altro. Descrive essenzialmente quanto varianza abbiamo all'interno di un singolo cluster. Questa misura è chiamata All'interno della somma dei quadrati dei cluster, o WCSS in breve. Più piccolo è il WCSS, più vicini sono i nostri punti, quindi abbiamo un cluster più ben formato. La formula WCSS può essere utilizzata per un numero qualsiasi di cluster:

$$
WCSS = somma(Pi_1 – Centroide_1)^2 + cdots + somma(Pi_n – Centroide_n)^2
$$

Nota: In questa guida utilizziamo il Distanza euclidea per ottenere i centroidi, ma potrebbero essere utilizzate anche altre misure di distanza, come Manhattan.

Ora possiamo supporre di aver scelto di avere due cluster e provare a implementare il WCSS per capire meglio cos'è il WCSS e come usarlo. Come afferma la formula, dobbiamo sommare le differenze al quadrato tra tutti i punti del cluster e i centroidi. Quindi, se lo è il nostro primo punto del primo gruppo (5, 3) e il nostro ultimo centroide (dopo la convergenza) del primo gruppo è (16.8, 17.0), il WCSS sarà:

$$
WCSS = somma((5,3) – (16.8, 17.0))^2
$$

$$
WCSS = somma((5-16.8) + (3-17.0))^2
$$

$$
WCSS = somma((-11.8) + (-14.0))^2
$$

$$
WCSS = somma((-25.8))^2
$$

$$
WCSS = 335.24
$$

Questo esempio illustra come calcoliamo il WCSS per un punto dal cluster. Ma il cluster di solito contiene più di un punto e dobbiamo tenerne conto tutti quando calcoliamo il WCSS. Lo faremo definendo una funzione che riceve un cluster di punti e centroidi e restituisce la somma dei quadrati:

def sum_of_squares(cluster, centroid):
    squares = []
    for p in cluster:
        squares.append((p - centroid)**2)
        ss = np.array(squares).sum()
    return ss

Ora possiamo ottenere la somma dei quadrati per ogni cluster:

g1 = sum_of_squares(points_in_g1, g1_center)
g2 = sum_of_squares(points_in_g2, g2_center)

E somma i risultati per ottenere il totale WCSS:

g1 + g2

Questo risulta in:

2964.3999999999996

Quindi, nel nostro caso, quando K è uguale a 2, il totale WCSS è 2964.39. Ora possiamo cambiare Ks e calcolare il WCSS per tutti loro. In questo modo, possiamo avere un'idea di cosa K dovremmo scegliere di fare in modo che il nostro clustering funzioni al meglio.

Calcolo WCSS utilizzando Scikit-Impara

Fortunatamente, non è necessario calcolare manualmente il WCSS per ciascuno K. Dopo aver eseguito il clustering K-Means per il dato nuber di cluster, possiamo ottenere il suo WCSS usando il inertia_ attributo. Ora possiamo tornare alla nostra K-Mean for loop, utilizzalo per modificare il numero di cluster ed elenca i valori WCSS corrispondenti:

wcss = [] 
for number_of_clusters in range(1, 11): 
    kmeans = KMeans(n_clusters = number_of_clusters, random_state = 42)
    kmeans.fit(points) 
    wcss.append(kmeans.inertia_)
wcss

Si noti che il secondo valore nell'elenco è esattamente lo stesso per cui abbiamo calcolato prima K = 2:

[18272.9, # For k=1 
 2964.3999999999996, # For k=2
 1198.75, # For k=3
 861.75,
 570.5,
 337.5,
 175.83333333333334,
 79.5,
 17.0,
 0.0]

Per visualizzare quei risultati, tracciamo il nostro Ks insieme ai valori WCSS:

ks = [1, 2, 3, 4, 5 , 6 , 7 , 8, 9, 10]
plt.plot(ks, wcss)

Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

C'è un'interruzione su una trama quando x = 2, un punto basso nella linea e uno ancora più basso quando x = 3. Si noti che ci ricorda il forma di gomito. Tracciando il K insieme al WCSS, stiamo usando il Metodo del gomito per scegliere il numero di Ks. E il scelto K è esattamente il punto più basso del gomito, quindi, sarebbe 3 invece di 2, nel nostro caso:

ks = [1, 2, 3, 4, 5 , 6 , 7 , 8, 9, 10]
plt.plot(ks, wcss);
plt.axvline(3, linestyle='--', color='r')

Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Possiamo eseguire di nuovo l'algoritmo del cluster K-Means, per vedere come sarebbero i nostri dati tre gruppi:

kmeans = KMeans(n_clusters=3, random_state=42)
kmeans.fit(points)
sns.scatterplot(x = points[:,0], y = points[:,1], hue=kmeans.labels_)

Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Eravamo già soddisfatti di due cluster, ma secondo il metodo del gomito, tre cluster si adatterebbero meglio ai nostri dati. In questo caso, avremmo tre tipi di negozi invece di due. Prima di utilizzare il metodo del gomito, abbiamo pensato ai cluster di negozi sud-ovest e nord-est, ora abbiamo anche i negozi al centro. Forse potrebbe essere una buona posizione per aprire un altro negozio poiché avrebbe meno concorrenza nelle vicinanze.

Misure alternative di qualità del cluster

Ci sono anche altre misure che possono essere utilizzate durante la valutazione della qualità del cluster:

  • Punteggio silhouette – analizza non solo la distanza tra i punti intra-cluster ma anche tra i cluster stessi
  • Tra cluster Somma di quadrati (BCSS) – metrica complementare al WCSS
  • Errore somma dei quadrati (SE)
  • Raggio massimo – misura la distanza maggiore da un punto al suo baricentro
  • Raggio medio – la somma della distanza maggiore da un punto al suo baricentro divisa per il numero di cluster.

Si consiglia di sperimentare e conoscere ciascuno di essi poiché, a seconda del problema, alcune delle alternative possono essere più applicabili rispetto alle metriche più utilizzate (WCSS e punteggio silhouette).

Alla fine, come con molti algoritmi di data science, vogliamo ridurre la varianza all'interno di ciascun cluster e massimizzare la varianza tra i diversi cluster. Quindi abbiamo cluster più definiti e separabili.

Applicazione di K-Means su un altro set di dati

Usiamo ciò che abbiamo imparato su un altro set di dati. Questa volta cercheremo di trovare gruppi di vini simili.

Nota: Puoi scaricare il set di dati qui.

Iniziamo importando pandas leggere il wine-clustering CSV (Valori separati da virgola) file in a Dataframe struttura:

import pandas as pd

df = pd.read_csv('wine-clustering.csv')

Dopo averlo caricato, diamo un'occhiata ai primi cinque record di dati con il file head() Metodo:

df.head()

Questo risulta in:

	Alcohol 	Malic_Acid 	Ash 	Ash_Alcanity 	Magnesium 	Total_Phenols 	Flavanoids 	Nonflavanoid_Phenols 	Proanthocyanins 	Color_Intensity 	Hue 	OD280 	Proline
0 	14.23 		1.71 		2.43 	15.6 			127 		2.80 			3.06 		0.28 					2.29 				5.64 				1.04 	3.92 	1065
1 	13.20 		1.78 		2.14 	11.2 			100 		2.65 			2.76 		0.26 					1.28 				4.38 				1.05 	3.40 	1050
2 	13.16 		2.36 		2.67 	18.6 			101 		2.80 			3.24 		0.30 					2.81 				5.68 				1.03 	3.17 	1185
3 	14.37 		1.95 		2.50 	16.8 			113 		3.85 			3.49 		0.24 					2.18 				7.80 				0.86 	3.45 	1480
4 	13.24 		2.59 		2.87 	21.0 			118 		2.80 			2.69 		0.39 					1.82 				4.32 				1.04 	2.93 	735

Abbiamo molte misurazioni delle sostanze presenti nei vini. Qui, inoltre, non avremo bisogno di trasformare le colonne categoriali perché sono tutte numeriche. Ora, diamo un'occhiata alle statistiche descrittive con il describe() Metodo:

df.describe().T 

La tabella di descrizione:

 						count 	mean 		std 		min 	25% 	50% 	75% 		max
Alcohol 				178.0 	13.000618 	0.811827 	11.03 	12.3625 13.050 	13.6775 	14.83
Malic_Acid 				178.0 	2.336348 	1.117146 	0.74 	1.6025 	1.865 	3.0825 		5.80
Ash 					178.0 	2.366517 	0.274344 	1.36 	2.2100 	2.360 	2.5575 		3.23
Ash_Alcanity 			178.0 	19.494944 	3.339564 	10.60 	17.2000 19.500 	21.5000 	30.00
Magnesium 				178.0 	99.741573 	14.282484 	70.00 	88.0000 98.000 	107.0000 	162.00
Total_Phenols 			178.0 	2.295112 	0.625851 	0.98 	1.7425 	2.355 	2.8000 		3.88
Flavanoids 				178.0 	2.029270 	0.998859 	0.34 	1.2050 	2.135 	2.8750 		5.08
Nonflavanoid_Phenols 	178.0 	0.361854 	0.124453 	0.13 	0.2700 	0.340 	0.4375 		0.66
Proanthocyanins 		178.0 	1.590899 	0.572359 	0.41 	1.2500 	1.555 	1.9500 		3.58
Color_Intensity 		178.0 	5.058090 	2.318286 	1.28 	3.2200 	4.690 	6.2000 		13.00
Hue 					178.0 	0.957449 	0.228572 	0.48 	0.7825 	0.965 	1.1200 		1.71
OD280 					178.0 	2.611685 	0.709990 	1.27 	1.9375 	2.780 	3.1700 		4.00
Proline 				178.0 	746.893258 	314.907474 	278.00 	500.500 673.500 985.0000 	1680.00

Guardando il tavolo è chiaro che c'è qualcosa variabilità dei dati – per alcune colonne come Alchool c'è di più, e per altri, come Malic_Acid, meno. Ora possiamo verificare se ce ne sono null, o NaN valori nel nostro set di dati:

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 178 entries, 0 to 177
Data columns (total 13 columns):
 #   Column                Non-Null Count  Dtype  
---  ------                --------------  -----  
 0   Alcohol               178 non-null    float64
 1   Malic_Acid            178 non-null    float64
 2   Ash                   178 non-null    float64
 3   Ash_Alcanity          178 non-null    float64
 4   Magnesium             178 non-null    int64  
 5   Total_Phenols         178 non-null    float64
 6   Flavanoids            178 non-null    float64
 7   Nonflavanoid_Phenols  178 non-null    float64
 8   Proanthocyanins       178 non-null    float64
 9   Color_Intensity       178 non-null    float64
 10  Hue                   178 non-null    float64
 11  OD280                 178 non-null    float64
 12  Proline               178 non-null    int64  
dtypes: float64(11), int64(2)
memory usage: 18.2 KB

Non è necessario eliminare o inserire dati, considerando che non ci sono valori vuoti nel set di dati. Possiamo usare un Seaborn pairplot() per vedere la distribuzione dei dati e per verificare se il set di dati forma coppie di colonne che possono essere interessanti per il clustering:

sns.pairplot(df)

Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Osservando il pairplot, due colonne sembrano promettenti ai fini del clustering: Alcohol ed OD280 (che è un metodo per determinare la concentrazione proteica nei vini). Sembra che ci siano 3 cluster distinti su lotti che ne combinano due.

Ci sono anche altre colonne che sembrano essere in correlazione. Soprattutto Alcohol ed Total_Phenolse Alcohol ed Flavanoids. Hanno grandi relazioni lineari che possono essere osservate nel pairplot.

Poiché il nostro obiettivo è il clustering con K-Means, scegliamo una coppia di colonne, diciamo Alcohol ed OD280e testare il metodo del gomito per questo set di dati.

Nota: Quando si utilizzano più colonne del set di dati, sarà necessario tracciare in 3 dimensioni o ridurre i dati a componenti principali (uso di PCA). Questo è un approccio valido e più comune, assicurati di scegliere i componenti principali in base a quanto spiegano e tieni presente che quando si riducono le dimensioni dei dati, c'è una certa perdita di informazioni, quindi il grafico è un approssimazione dei dati reali, non come sono realmente.

Tracciamo il grafico a dispersione con quelle due colonne impostate come asse per dare un'occhiata più da vicino ai punti che vogliamo dividere in gruppi:

sns.scatterplot(data=df, x='OD280', y='Alcohol')

Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Ora possiamo definire le nostre colonne e utilizzare il metodo del gomito per determinare il numero di cluster. Inizieremo anche l'algoritmo con kmeans++ solo per assicurarsi che converga più rapidamente:

values = df[['OD280', 'Alcohol']]

wcss_wine = [] 
for i in range(1, 11): 
    kmeans = KMeans(n_clusters = i, init = 'k-means++', random_state = 42)
    kmeans.fit(values) 
    wcss_wine.append(kmeans.inertia_)

Abbiamo calcolato il WCSS, quindi possiamo tracciare i risultati:

clusters_wine = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
plt.plot(clusters_wine, wcss_wine)
plt.axvline(3, linestyle='--', color='r')

Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Secondo il metodo del gomito dovremmo avere 3 cluster qui. Per il passaggio finale, raggruppiamo i nostri punti in 3 cluster e tracciamo quei cluster identificati dai colori:

kmeans_wine = KMeans(n_clusters=3, random_state=42)
kmeans_wine.fit(values)
sns.scatterplot(x = values['OD280'], y = values['Alcohol'], hue=kmeans_wine.labels_)

Guida definitiva al clustering K-Means con Scikit-Learn PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Possiamo vedere i grappoli 0, 1e 2 nel grafico. Sulla base della nostra analisi, gruppo 0 ha vini con un contenuto proteico maggiore e una minore gradazione alcolica, gruppo 1 ha vini con gradazione alcolica più elevata e basso contenuto proteico, e gruppo 2 ha sia un alto contenuto proteico che un alto contenuto alcolico nei suoi vini.

Questo è un set di dati molto interessante e ti incoraggio ad approfondire l'analisi raggruppando i dati dopo la normalizzazione e la PCA, anche interpretando i risultati e trovando nuove connessioni.

Conclusione

K-Mezzi il clustering è un algoritmo di apprendimento automatico non supervisionato semplice ma molto efficace per il clustering dei dati. Raggruppa i dati in base alla distanza euclidea tra i punti dati. L'algoritmo di clustering di K-Means ha molti usi per raggruppare documenti di testo, immagini, video e molto altro.

Timestamp:

Di più da Impilamento