Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

Lopullinen opas K-Means-klusterointiin Scikit-Learnin avulla

esittely

K-tarkoittaa klusterointia on yksi yleisimmin käytetyistä valvomattomista koneoppimisalgoritmeista, jotka muodostavat dataklustereita datainstanssien samankaltaisuuden perusteella.

Tässä oppaassa tarkastellaan ensin yksinkertaista esimerkkiä ymmärtääksemme, kuinka K-Means-algoritmi toimii, ennen kuin otamme sen käyttöön Scikit-Learnin avulla. Sitten keskustelemme siitä, kuinka klusterien lukumäärä (Ks) määritetään K-Meansissa, ja käsitellään myös etäisyysmittauksia, varianssia ja K-Meansin etuja ja haittoja.

Motivoiminen

Kuvittele seuraava tilanne. Eräänä päivänä naapurustossa kävellessäsi huomasit, että siellä oli 10 lähikauppaa ja aloit miettimään, mitkä kaupat olivat samanlaisia ​​– lähempänä toisiaan. Kun etsit tapoja vastata tähän kysymykseen, olet törmännyt mielenkiintoiseen lähestymistapaan, joka jakaa kaupat ryhmiin niiden koordinaattien perusteella kartalla.

Esimerkiksi, jos yksi kauppa sijaitsi 5 km länteen ja 3 km pohjoiseen – määrität (5, 3) koordinoi sille ja edustaa sitä kaaviossa. Piirretään tämä ensimmäinen kohta visualisoidaksesi mitä tapahtuu:

import matplotlib.pyplot as plt

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

Tämä on vasta ensimmäinen kohta, jotta voimme saada käsityksen siitä, kuinka voimme edustaa kauppaa. Oletetaan, että meillä on jo 10 koordinaattia 10 kerätylle myymälälle. Järjestettyään ne a numpy matriisi, voimme myös piirtää niiden sijainnit:

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)

Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

K-Means-algoritmin manuaalinen käyttöönotto

Nyt voimme tarkastella 10 kauppaa kaaviossa, ja suurin ongelma on selvittää, voidaanko ne jakaa eri ryhmiin läheisyyden perusteella? Pelkästään vilkaisemalla nopeasti kaaviota voimme luultavasti huomata kaksi myymäläryhmää – yksi on alemmat pisteet alhaalla vasemmalla ja toinen on yläoikealla olevat pisteet. Ehkä voimme jopa erottaa nämä kaksi keskellä olevaa pistettä erillisenä ryhmänä - siten luoden kolmea eri ryhmää.

Tässä osiossa käydään läpi pisteiden manuaalinen klusterointi – jaetaan ne tiettyyn määrään ryhmiä. Tällä tavalla käymme pohjimmiltaan huolellisesti läpi kaikki vaiheet K-Means-klusterointialgoritmi. Tämän osion loppuun mennessä saat sekä intuitiivisen että käytännön käsityksen kaikista K-Means-klusteroinnin aikana suoritettavista vaiheista. Sen jälkeen siirrämme sen Scikit-Learnille.

Mikä olisi paras tapa määrittää, onko pisteryhmiä kaksi vai kolme? Yksi yksinkertainen tapa olisi yksinkertaisesti valita yksi määrä ryhmiä – esimerkiksi kaksi – ja yrittää sitten ryhmitellä pisteitä valinnan perusteella.

Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

Oletetaan, että olemme päättäneet, että niitä on kaksi ryhmää myymälöistämme (pisteet). Nyt meidän on löydettävä tapa ymmärtää, mitkä pisteet kuuluvat mihinkin ryhmään. Tämä voidaan tehdä valitsemalla yksi piste edustamaan ryhmä 1 ja yksi edustamaan ryhmä 2. Näitä pisteitä käytetään viitteenä mitattaessa etäisyyttä kaikista muista pisteistä kuhunkin ryhmään.

Sillä tavalla sano pointti (5, 3) päätyy kuulumaan ryhmään 1, ja piste (79, 60) ryhmään 2. Kun yrität määrittää uuden pisteen (6, 3) ryhmille, meidän on mitattava sen etäisyys näihin kahteen pisteeseen. Kohdan tapauksessa (6, 3) is lähempänä että (5, 3), joten se kuuluu ryhmään, jota tämä kohta edustaa - ryhmä 1. Näin voimme helposti ryhmitellä kaikki pisteet vastaaviin ryhmiin.

Tässä esimerkissä ryhmien määrän määrittämisen lisäksi (klusterit) – valitsemme myös joitain kohtia a viite etäisyys kunkin ryhmän uusiin pisteisiin.

Tämä on yleinen ajatus ymmärtääksemme yhtäläisyyksiä myymälöidemme välillä. Toteutetaan se käytännössä – voimme ensin valita kaksi vertailupistettä satunnainen. Vertailupiste ryhmä 1 on (5, 3) ja vertailupiste ryhmä 2 on (10, 15). Voimme valita molemmat pisteemme numpy joukko [0] ja [1] indeksit ja tallenna ne sinne g1 (ryhmä 1) ja g2 (ryhmä 2) muuttujat:

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

Tämän jälkeen meidän on laskettava etäisyys kaikista muista pisteistä näihin vertailupisteisiin. Tämä herättää tärkeän kysymyksen – kuinka tuo etäisyys mitataan. Voimme käyttää pohjimmiltaan mitä tahansa etäisyysmittausta, mutta tässä oppaassa käytetään euklidista etäisyyttä_.

Voi olla hyödyllistä tietää, että Euklidinen etäisyysmitta perustuu Pythagoraan lauseeseen:

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

Kun se on mukautettu tason pisteisiin - (a1, b1) ja (a2, b2), edellinen kaava tulee:

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

Etäisyys on neliöjuuri c, joten voimme kirjoittaa kaavan myös seuraavasti:

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

Huomautus: Voit myös yleistää euklidisen etäisyyskaavan moniulotteisille pisteille. Esimerkiksi kolmiulotteisessa avaruudessa pisteillä on kolme koordinaattia – kaavamme heijastaa sitä seuraavalla tavalla:
$$
euklidinen_{jaka} = sqrt[2][(a2 – a1)^2 + (b2 – b1) ^2 + (c2 – c1) ^2)]
$$
Samaa periaatetta noudatetaan riippumatta tilan, jossa toimimme, mittojen määrästä.

Tähän mennessä olemme valinneet pisteet edustamaan ryhmiä ja osaamme laskea etäisyydet. Laitetaan nyt etäisyydet ja ryhmät yhteen liittämällä jokainen keräämämme kauppapiste ryhmään.

Selvittääksemme sen paremmin, julistamme kolme luetteloa. Ensimmäinen, joka tallentaa ensimmäisen ryhmän pisteitä – points_in_g1. Toinen, joka tallentaa pisteitä ryhmästä 2 – points_in_g2ja viimeinen - group, To etiketti pisteet joko 1 (kuuluu ryhmään 1) tai 2 (kuuluu ryhmään 2):

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

Voimme nyt iteroida pisteidemme läpi ja laskea euklidisen etäisyyden niiden ja kunkin ryhmäviitteemme välillä. Jokainen piste tulee olemaan lähempänä johonkin kahdesta ryhmästä – sen perusteella, kumpi ryhmä on lähimpänä, kohdistamme jokaisen pisteen vastaavaan luetteloon ja lisäämme samalla 1 or 2 että group lista:

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')

Katsotaanpa tämän iteroinnin tuloksia nähdäksesi mitä tapahtui:

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

Mikä johtaa:

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] 

Voimme myös piirtää klusterointituloksen eri väreillä määritettyjen ryhmien perusteella Seabornin avulla scatterplot() jossa group kuten hue Perustelu:

import seaborn as sns

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

Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

On selvästi nähtävissä, että vain ensimmäinen pisteemme on asetettu ryhmään 1 ja kaikki muut pisteet ryhmään 2. Tämä tulos poikkeaa siitä, mitä olimme kuvitelleet alussa. Kun otetaan huomioon ero tulostemme ja alkuperäisten odotustemme välillä – voimmeko muuttaa sitä mitenkään? Näyttää olevan olemassa!

Yksi lähestymistapa on toistaa prosessi ja valita eri pisteet ryhmien referensseiksi. Tämä muuttaa tuloksiamme, toivottavasti, vastaamaan paremmin sitä, mitä olemme kuvitelleet alussa. Tällä toisella kerralla emme voineet valita niitä sattumanvaraisesti kuten aiemmin, vaan saamalla a tarkoittaa kaikista jo ryhmitellyistä pisteistämme. Näin uudet pisteet voitaisiin sijoittaa vastaavien ryhmien keskelle.

Esimerkiksi jos toisella ryhmällä oli vain pisteitä (10, 15), (30, 45). Uuden keskeinen pointti olisi (10 + 30)/2 ja (15+45)/2 – joka on yhtä suuri kuin (20, 30).

Koska olemme laittaneet tulokset listoihin, voimme muuntaa ne ensin numpy taulukot, valitse niiden xs, ys ja hanki sitten tarkoittaa:

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

Neuvo: Yritä käyttää numpy ja NumPy-taulukoita niin paljon kuin mahdollista. Ne on optimoitu parantamaan suorituskykyä ja yksinkertaistavat monia lineaarialgebran operaatioita. Aina kun yrität ratkaista jotain lineaarista algebran ongelmaa, sinun tulee ehdottomasti katsoa numpy asiakirjat tarkistaaksesi, onko niitä olemassa numpy menetelmä, joka on suunniteltu ratkaisemaan ongelmasi. Mahdollisuus on, että on!

Auttaaksemme toistamaan prosessia uusilla keskipisteillämme muuttamalla edellinen koodimme funktioksi, suorittamalla se ja katsomalla, onko pisteiden ryhmittelyssä tapahtunut muutoksia:

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

Huomautus: Jos huomaat toistavasi samaa koodia yhä uudelleen ja uudelleen, sinun tulee kääriä koodi erilliseen funktioon. Parhaana käytäntönä pidetään koodin järjestämistä funktioiksi, erityisesti koska ne helpottavat testausta. On helpompi testata ja eristää koodinpala kuin täysi koodi ilman toimintoja.

Kutsutaan funktio ja tallennetaan sen tulokset sisään points_in_g1, points_in_g2ja group muuttujat:

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

Ja piirrä myös sirontakaavio värillisillä pisteillä visualisoidaksesi ryhmien jaon:

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

Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

Näyttää siltä, ​​että pisteidemme ryhmittely on paranee. Mutta silti, kaavion keskellä on kaksi pistettä, jotka voidaan osoittaa jommallekummalle ryhmälle, kun otetaan huomioon niiden läheisyys molempiin ryhmiin. Tähän mennessä kehittämämme algoritmi määrittää molemmat pisteet toiseen ryhmään.

Tämä tarkoittaa, että voimme luultavasti toistaa prosessin vielä kerran ottamalla X:n ja Y:n keskiarvot luoden kaksi uutta keskuspistettä (keskukset) ryhmiimme ja jakamalla ne uudelleen etäisyyden perusteella.

Luodaan myös funktio sentroidien päivittämiseksi. Koko prosessi voidaan nyt pelkistää useisiin kyseisen toiminnon kutsuihin:

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)

Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

Huomaa, että tämän kolmannen iteraation jälkeen jokainen piste kuuluu nyt eri klustereihin. Näyttää siltä, ​​että tulokset paranevat – tehdään se vielä kerran. Nyt mennään neljäs iteraatio menetelmästämme:

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)

Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

Tällä neljännellä kerralla saimme sama tulos kuin edellinen. Joten näyttää siltä, ​​että pisteemme eivät enää vaihda ryhmiä, tuloksemme on saavuttanut jonkinlaisen vakauden – se on päässyt muuttumattomaan tilaan, tai lähentyneet. Lisäksi meillä on täsmälleen sama tulos kuin olimme kuvitellut kahdelle ryhmälle. Voimme myös nähdä, onko tämä saavutettu jako järkevä.

Kerrataanpa nopeasti, mitä olemme tehneet tähän mennessä. Olemme jakaneet 10 myymäläämme maantieteellisesti kahteen osaan – yksi alemmille lounaisille alueille ja toiset koilliseen. Voi olla mielenkiintoista kerätä lisää tietoja jo olemassa olevien tietojen lisäksi – tulot, päivittäinen asiakasmäärä ja paljon muuta. Näin voimme tehdä monipuolisemman analyysin ja mahdollisesti tuottaa mielenkiintoisempia tuloksia.

Tällaisia ​​klusterointitutkimuksia voidaan tehdä, kun jo vakiintunut brändi haluaa valita alueen uuden myymälän avaamiseksi. Tällöin huomioidaan paljon muitakin muuttujia kuin sijainti.

Mitä tekemistä tällä kaikella on K-Means-algoritmin kanssa?

Näitä vaiheita noudattaessasi olet ehkä miettinyt, mitä tekemistä niillä on K-Means-algoritmin kanssa. Toistaiseksi toteuttamamme prosessi on K-Means-algoritmi. Lyhyesti sanottuna olemme määrittäneet ryhmien/klusterien lukumäärän, valinneet satunnaisesti alkupisteitä ja päivittäneet sentroideja jokaisessa iteraatiossa, kunnes klusterit konvergoivat. Olemme pohjimmiltaan suorittaneet koko algoritmin käsin – jokainen vaihe on suoritettu huolellisesti.

- K K-Meansissa on peräisin klustereiden määrä jotka on asetettava ennen iterointiprosessin aloittamista. Meidän tapauksessamme K = 2. Tämä ominaisuus nähdään joskus mm negatiivinen Ottaen huomioon, että on olemassa muita klusterointimenetelmiä, kuten Hierarchical Clustering, joissa ei tarvitse olla kiinteää määrää klustereita etukäteen.

Keinokäytön ansiosta myös K-keino muuttuu herkkä poikkeaville arvoille ja ääriarvoille – ne lisäävät vaihtelua ja vaikeuttavat sentroididemme osuutta. Ole siis tietoinen suoritustarpeesta ääriarvot ja outlier-analyysit ennen klusteroinnin suorittamista K-Means-algoritmilla.

Huomaa myös, että pisteemme segmentoitiin suoriin osiin, klustereita luotaessa ei ole käyriä. Se voi myös olla K-Means-algoritmin haitta.

Huomautus: Kun haluat sen olevan joustavampi ja mukautuvampi ellipseihin ja muihin muotoihin, kokeile a yleistetty K-keskiarvo Gaussin sekoitusmalli. Tämä malli voi mukautua elliptisiin segmentointiklustereihin.

K-Meansilla on myös monia etuja! Toimii hyvin päällä suuret tietokannat joita voi olla vaikea käsitellä, jos käytät tietyntyyppisiä hierarkkisia klusterointialgoritmeja. Se myös takaa lähentymisenja voi helposti yleistää ja sopeuttaa. Lisäksi se on luultavasti eniten käytetty klusterointialgoritmi.

Nyt kun olemme käyneet läpi kaikki K-Means-algoritmissa suoritetut vaiheet ja ymmärtäneet sen kaikki edut ja haitat, voimme vihdoin ottaa K-Meansin käyttöön Scikit-Learn-kirjaston avulla.

K-Means-algoritmin käyttöönotto Scikit-Opi

Tarkistaaksemme tuloksemme uudelleen, tee tämä prosessi uudelleen, mutta nyt käyttämällä 3 riviä koodia sklearn:

from sklearn.cluster import KMeans


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

Tässä tarrat ovat samat kuin aiemmissa ryhmissämme. Piirretään tulos nopeasti:

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

Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

Tuloksena oleva kaavio on sama kuin edellisen osan kuvaaja.

Tutustu käytännönläheiseen, käytännölliseen Gitin oppimisoppaaseemme, jossa on parhaat käytännöt, alan hyväksymät standardit ja mukana tuleva huijauslehti. Lopeta Git-komentojen googlailu ja oikeastaan oppia se!

Huomautus: Pelkästään sen tarkastelu, kuinka olemme suorittaneet K-Means-algoritmin Scikit-Learnin avulla, saattaa antaa vaikutelman, että se on turha ja että sinun ei tarvitse huolehtia siitä liikaa. Vain 3 koodiriviä suorittavat kaikki vaiheet, joista olemme keskustelleet edellisessä osiossa, kun olemme käyneet läpi K-Means-algoritmin vaihe vaiheelta. Mutta, paholainen on yksityiskohdissa tässä tapauksessa! Jos et ymmärrä kaikkia algoritmin vaiheita ja rajoituksia, kohtaat todennäköisesti tilanteen, jossa K-Means-algoritmi antaa tuloksia, joita et odottanut.

Scikit-Learnin avulla voit myös alustaa K-Meansin nopeuttaaksesi lähentymistä asettamalla init='k-means++' Perustelu. Laajemmassa mielessä K-Means++ valitsee silti k alkuperäiset klusterikeskukset satunnaisesti tasaisen jakautumisen jälkeen. Sitten jokainen seuraava klusterin keskus valitaan jäljellä olevista datapisteistä, ei laskemalla vain etäisyysmitta - vaan käyttämällä todennäköisyyttä. Todennäköisyysarvon käyttäminen nopeuttaa algoritmia ja on hyödyllistä käsiteltäessä erittäin suuria tietojoukkoja.

Kyynärpäämenetelmä – Parhaan ryhmien lukumäärän valitseminen

Toistaiseksi niin hyvin! Olemme ryhmitelleet 10 kauppaa pisteiden ja sentroidien välisen euklidisen etäisyyden perusteella. Mutta entä ne kaksi kaavion keskellä olevaa pistettä, joita on hieman vaikeampi ryhmitellä? Eivätkö he voisi muodostaa myös erillisen ryhmän? Teimmekö todella virheen valitessaan K = 2 ryhmät? Ehkä meillä todella oli K = 3 ryhmät? Meillä voi jopa olla enemmän kuin kolme ryhmää, emmekä ole tietoisia siitä.

Tässä esitetty kysymys on kuinka määrittää ryhmien lukumäärä (K) K-Meansissa. Vastataksemme tähän kysymykseen, meidän on ymmärrettävä, olisiko olemassa "parempi" klusteri eri K:n arvolle.

Naiivi tapa selvittää se on ryhmitellä pisteitä eri arvoilla K, niin, varten K=2, K=3, K=4 ja niin edelleen:

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

Mutta klusterointipisteet eri Ks yksin ei riitä ymmärtääksemme, olemmeko valinneet ihanteellisen arvon K. Tarvitsemme tavan arvioida kunkin klusteroinnin laatua K olemme valinneet.

Lasketaan manuaalisesti Cluster Sum of Squares (WCSS) sisällä

Tässä on ihanteellinen paikka esitellä mitta siitä, kuinka paljon klusteripisteemme ovat lähellä toisiaan. Se kuvaa lähinnä kuinka paljon vaihtelu meillä on yhden klusterin sisällä. Tätä toimenpidettä kutsutaan Klusterin neliösumman sisällätai WCSS lyhyesti. Mitä pienempi WCSS on, sitä lähempänä pisteemme ovat, joten meillä on paremmin muodostettu klusteri. WCSS-kaavaa voidaan käyttää mille tahansa määrälle klustereita:

$$
WCSS = summa(Pi_1 – Keskipiste_1)^2 + cdots + summa(Pi_n – Keskipiste_n)^2
$$

Huomautus: Tässä oppaassa käytämme Euklidinen etäisyys sentroidien saamiseksi, mutta myös muita etäisyysmittoja, kuten Manhattania, voitaisiin käyttää.

Nyt voimme olettaa, että olemme valinneet kaksi klusteria ja yrittää toteuttaa WCSS:n ymmärtääksemme paremmin mitä WCSS on ja kuinka sitä käytetään. Kuten kaava kertoo, meidän on laskettava yhteen kaikkien klusteripisteiden ja sentroidien väliset erot. Joten jos ensimmäinen pisteemme ensimmäisestä ryhmästä on (5, 3) ja ensimmäisen ryhmän viimeinen sentroidi (konvergenssin jälkeen) on (16.8, 17.0), WCSS on:

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

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

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

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

$$
WCSS = 335.24
$$

Tämä esimerkki havainnollistaa, kuinka laskemme WCSS:n yhdelle pisteelle klusterista. Mutta klusteri sisältää yleensä useamman kuin yhden pisteen, ja meidän on otettava ne kaikki huomioon WCSS:ää laskettaessa. Teemme sen määrittämällä funktion, joka vastaanottaa joukon pisteitä ja sentroideja ja palauttaa neliöiden summan:

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

Nyt voimme saada kunkin klusterin neliöiden summan:

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

Ja laske tulokset yhteen saadaksesi kokonaissumman WCSS:

g1 + g2

Tämä johtaa:

2964.3999999999996

Joten meidän tapauksessamme milloin K on yhtä suuri kuin 2, koko WCSS on 2964.39. Nyt voimme vaihtaa K:t ja laskea WCSS:n kaikille niille. Näin voimme saada käsityksen siitä, mitä K meidän tulisi valita, että klusterointimme toimii parhaiten.

laskettaessa WCSS Käyttäminen Scikit-Opi

Onneksi meidän ei tarvitse manuaalisesti laskea WCSS:ää jokaiselle K. Kun olet suorittanut K-Means-klusteroinnin tietylle klusterimäärälle, voimme saada sen WCSS:n käyttämällä inertia_ attribuutti. Nyt voimme palata K-Meansiin for silmukka, käytä sitä klustereiden määrän määrittämiseen ja vastaavien WCSS-arvojen luetteloimiseen:

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

Huomaa, että luettelon toinen arvo on täsmälleen sama, jolle olemme laskeneet aiemmin 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]

Jos haluat visualisoida nämä tulokset, piirretään meidän Ks WCSS-arvojen kanssa:

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

Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

Juonissa on keskeytys, kun x = 2, linjan alin kohta ja vielä alempi, kun x = 3. Huomaa, että se muistuttaa meitä kyynärpään muoto. Piirtämällä K:t WCSS:n kanssa käytämme Kyynärpää menetelmä valitaksesi Ks:n määrän. Ja valittu K on täsmälleen alin kyynärpää, niin se olisi 3 sijasta 2, meidän tapauksessamme:

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

Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

Voimme ajaa K-Means-klusterialgoritmin uudelleen nähdäksemme, miltä tietomme näyttäisivät kolme klusteria:

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

Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

Olimme jo tyytyväisiä kahteen klusteriin, mutta kyynärpäämenetelmän mukaan kolme klusteria sopisi paremmin tietoomme. Tässä tapauksessa meillä olisi kolmenlaisia ​​myymälöitä kahden sijaan. Ennen kyynärpäämenetelmän käyttöä mietimme lounaisia ​​ja koillisia myymäläklustereita, nyt meillä on myös myymälät keskustassa. Ehkä se voisi olla hyvä paikka avata toinen myymälä, koska sen lähellä olisi vähemmän kilpailua.

Vaihtoehtoiset klusterin laatutoimenpiteet

On myös muita mittareita, joita voidaan käyttää klusterin laadun arvioinnissa:

  • Siluettipisteet – analysoi klusterin sisäisten pisteiden välisen etäisyyden lisäksi myös itse klusterien välistä etäisyyttä
  • Klusterien välissä Neliöiden summa (BCSS) – WCSS:ää täydentävä mittari
  • Neliöiden summa -virhe (SSE)
  • Suurin säde – mittaa suurimman etäisyyden pisteestä sen painopisteeseen
  • Keskimääräinen säde – suurimman etäisyyden summa pisteestä sen painopisteeseen jaettuna klusterien lukumäärällä.

On suositeltavaa kokeilla ja tutustua jokaiseen niistä, koska ongelmasta riippuen jotkut vaihtoehdot voivat olla soveltuvampia kuin yleisimmin käytetyt mittarit (WCSS ja Silhouette Score).

Loppujen lopuksi, kuten monien datatieteen algoritmien kohdalla, haluamme vähentää varianssia kunkin klusterin sisällä ja maksimoida varianssin eri klustereiden välillä. Joten meillä on enemmän määriteltyjä ja erotettavia klustereita.

K-Meansin käyttäminen toisessa tietojoukossa

Käytetään oppimaamme toisessa tietojoukossa. Tällä kertaa yritämme löytää samanlaisia ​​viinejä.

Huomautus: Voit ladata tietojoukon tätä.

Aloitamme tuomalla pandas lukea wine-clustering CSV (Pilkuilla erotetut arvot) tiedosto a Dataframe rakenne:

import pandas as pd

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

Kun se on ladattu, katsotaanpa viittä ensimmäistä datatietuetta -sovelluksella head() menetelmä:

df.head()

Tämä johtaa:

	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

Meillä on monia mittauksia viinien sisältämistä aineista. Tässä meidän ei myöskään tarvitse muuttaa kategoriallisia sarakkeita, koska ne kaikki ovat numeerisia. Katsotaanpa nyt kuvaavia tilastoja describe() menetelmä:

df.describe().T 

Kuvaustaulukko:

 						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

Taulukkoa katsomalla on selvää, että niitä on tietojen vaihtelua – joillekin sarakkeille, kuten Alchool on enemmän, ja muille, kuten Malic_Acid, vähemmän. Nyt voimme tarkistaa, onko niitä nulltai NaN arvot tietojoukossamme:

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

Tietoja ei tarvitse pudottaa tai syöttää, koska tietojoukossa ei ole tyhjiä arvoja. Voimme käyttää Seabornia pairplot() nähdäksesi tietojen jakautumisen ja tarkistaaksesi, muodostaako tietojoukko sarakepareja, jotka voivat olla mielenkiintoisia klusteroinnin kannalta:

sns.pairplot(df)

Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

Parikaaviota katsoen kaksi saraketta vaikuttaa lupaavilta klusterointitarkoituksiin - Alcohol ja OD280 (joka on menetelmä viinien proteiinipitoisuuden määrittämiseksi). Näyttää siltä, ​​että tontilla on 3 erillistä klusteria, jotka yhdistävät kaksi niistä.

On myös muita sarakkeita, jotka näyttävät olevan korrelaatiossa. Varsinkin Alcohol ja Total_Phenolsja Alcohol ja Flavanoids. Heillä on suuret lineaariset suhteet, jotka voidaan havaita parikaaviossa.

Koska painopisteemme on klusterointi K-Meansin kanssa, valitaan vaikkapa yksi sarakepari Alcohol ja OD280ja testaa tämän tietojoukon kyynärpäämenetelmää.

Huomautus: Kun käytetään useampia tietojoukon sarakkeita, on tarpeen joko piirtää 3-ulotteisesti tai pienentää tiedot pääkomponentit (PCA:n käyttö). Tämä on pätevä ja yleisempi lähestymistapa, muista vain valita pääkomponentit sen mukaan, kuinka paljon ne selittävät, ja muista, että datan ulottuvuuksia pienennettäessä tapahtuu jonkin verran informaatiota – joten käyrä on likiarvo todellisista tiedoista, ei siitä, miten se todellisuudessa on.

Piirretään sirontadiagrammi siten, että nämä kaksi saraketta on asetettu sen akseliksi, jotta voimme tarkastella lähemmin pisteitä, jotka haluamme jakaa ryhmiin:

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

Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

Nyt voimme määrittää sarakkeet ja käyttää kyynärpäämenetelmää klustereiden määrän määrittämiseen. Aloitamme myös algoritmin kanssa kmeans++ vain varmistaaksesi, että se konvergoi nopeammin:

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_)

Olemme laskeneet WCSS:n, jotta voimme piirtää tulokset:

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

Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

Kyynärpäämenetelmän mukaan tässä pitäisi olla 3 klusteria. Viimeistä vaihetta varten ryhmitellään pisteemme kolmeen klusteriin ja piirretään väreillä tunnistetut klusterit:

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_)

Lopullinen opas K-Means-klusterointiin Scikit-Learn PlatoBlockchain Data Intelligencen avulla. Pystysuuntainen haku. Ai.

Voimme nähdä klustereita 0, 1ja 2 kaaviossa. Analyysimme perusteella ryhmä 0 sisältää viinejä, joissa on korkeampi proteiinipitoisuus ja vähemmän alkoholia, ryhmä 1 on viinejä, joissa on korkeampi alkoholipitoisuus ja vähän proteiinia, ja ryhmä 2 sen viineissä on sekä runsaasti proteiinia että alkoholia.

Tämä on erittäin mielenkiintoinen tietojoukko ja rohkaisen sinua menemään analyysiin syvemmälle klusteroimalla tiedot normalisoinnin ja PCA:n jälkeen – myös tulkitsemalla tuloksia ja etsimällä uusia yhteyksiä.

Yhteenveto

K-tarkoittaa klusterointi on yksinkertainen mutta erittäin tehokas valvomaton koneoppimisalgoritmi tietojen klusterointiin. Se klusteroi tiedot datapisteiden välisen euklidisen etäisyyden perusteella. K-Means-klusterointialgoritmilla on monia käyttötarkoituksia tekstiasiakirjojen, kuvien, videoiden ja paljon muuta ryhmittelemään.

Aikaleima:

Lisää aiheesta Stackabus