Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learniga

Sissejuhatus

K-tähendab rühmitamist on üks kõige laialdasemalt kasutatavaid järelevalveta masinõppe algoritme, mis moodustavad andmekogumeid, mis põhinevad andmeeksemplaride sarnasusel.

Selles juhendis vaatame kõigepealt lihtsat näidet, et mõista, kuidas K-Meansi algoritm töötab, enne kui rakendame seda Scikit-Learni abil. Seejärel arutame, kuidas määrata klastrite arvu (Ks) K-Meansis ning käsitleme ka kauguse mõõdikuid, dispersiooni ning K-Meansi plusse ja miinuseid.

Motiveerimine

Kujutage ette järgmist olukorda. Ühel päeval ümbruskonnas ringi liikudes märkasite, et seal on 10 esmatarbekauplust ja hakkasite mõtlema, millised poed on sarnased – üksteisele lähemal. Otsides sellele küsimusele vastuseid, olete kohanud huvitavat lähenemist, mis jagab kauplused rühmadesse nende koordinaatide alusel kaardil.

Näiteks kui üks pood asuks 5 km läänes ja 3 km põhjas, siis määraksite (5, 3) koordineerib seda ja esitab selle graafikul. Joonistame selle esimese punkti, et visualiseerida, mis toimub:

import matplotlib.pyplot as plt

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

See on alles esimene punkt, et saaksime aimu, kuidas saaksime kauplust esindada. Oletame, et meil on juba 10 kogutud kaupluse 10 koordinaati. Pärast nende korraldamist a numpy massiivi, saame joonistada ka nende asukohad:

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)

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

Kuidas K-Meansi algoritmi käsitsi rakendada

Nüüd saame vaadelda 10 kauplust graafikul ja peamine probleem on leida, kas neid saab läheduse alusel jagada erinevatesse rühmadesse? Lihtsalt graafikule kiire pilk peale heites märkame seda ilmselt kaks kaupluste rühma – üks on alumised punktid all vasakule ja teine ​​on ülemised paremad punktid. Võib-olla saame need kaks punkti keskel isegi eristada eraldi rühmana – seega luues kolm erinevat rühma.

Selles jaotises käsitleme punktide käsitsi rühmitamist – jagame need etteantud arvu rühmadesse. Nii vaatame sisuliselt hoolikalt läbi kõik selle etapid K-Meansi klasterdamisalgoritm. Selle jaotise lõpuks saate nii intuitiivse kui ka praktilise arusaamise kõigist K-Meansi rühmitamise käigus tehtud sammudest. Pärast seda delegeerime selle Scikit-Learnile.

Kuidas oleks parim viis määrata, kas punkte on kaks või kolm? Üks lihtne viis oleks lihtsalt valida üks arv rühmi – näiteks kaks – ja seejärel proovida punkte selle valiku alusel rühmitada.

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

Oletame, et oleme otsustanud, et neid on kaks rühma meie kauplustest (punktid). Nüüd peame leidma viisi, kuidas mõista, millised punktid millisesse rühma kuuluvad. Seda saab teha, valides esindamiseks ühe punkti grupp 1 ja üks esindama grupp 2. Neid punkte kasutatakse võrdlusalusena, kui mõõdetakse kaugust kõigist teistest punktidest iga rühmani.

Sel viisil öelge punkt (5, 3) kuulub 1. rühma ja punkt (79, 60) gruppi 2. Uue punkti määramisel (6, 3) rühmade jaoks peame mõõtma selle kaugust nende kahe punktini. Punkti puhul (6, 3) is lähemale Euroopa (5, 3), seega kuulub see selle punktiga esindatud rühma – grupp 1. Nii saame hõlpsasti rühmitada kõik punktid vastavatesse rühmadesse.

Selles näites lisaks rühmade arvu määramisele (klastrite) – valime ka mõned punktid a viide distantsi iga rühma uute punktide saamiseks.

See on üldine mõte, et mõista meie kaupluste sarnasusi. Paneme selle ellu – kõigepealt saame valida kaks võrdluspunkti juhuslik. Võrdluspunkt grupp 1 on (5, 3) ja võrdluspunkt grupp 2 on (10, 15). Saame valida mõlemad oma punktid numpy massiivi järgi [0] ja [1] indeksid ja salvestage need sisse g1 (1. rühm) ja g2 (2. rühm) muutujad:

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

Pärast seda peame arvutama kauguse kõigist teistest punktidest nende võrdluspunktideni. See tõstatab olulise küsimuse – kuidas seda vahemaad mõõta. Põhimõtteliselt saame kasutada mis tahes kauguse mõõtmist, kuid selle juhendi jaoks kasutame eukleidilist kaugust_.

Võib olla kasulik teada, et Eukleidiline kauguse mõõt põhineb Pythagorase teoreemil:

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

Kui see on kohandatud tasapinna punktidega - (a1, b1) ja (a2, b2), muutub eelmine valem:

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

Kaugus on ruutjuur c, seega saame valemi kirjutada ka järgmiselt:

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

Märge: Eukleidilise kauguse valemit saate ka üldistada mitmemõõtmeliste punktide jaoks. Näiteks kolmemõõtmelises ruumis on punktidel kolm koordinaati – meie valem peegeldab seda järgmiselt:
$$
eukleidiline_{dist} = sqrt[2][(a2 – a1)^2 + (b2 – b1) ^2 + (c2 – c1) ^2)]
$$
Sama põhimõtet järgitakse olenemata ruumi mõõtmete arvust, kus me tegutseme.

Seni oleme valinud punktid rühmade esindamiseks ja teame, kuidas kaugusi arvutada. Nüüd paneme vahemaad ja rühmad kokku, määrates iga meie kogutud poepunkti rühma.

Selle paremaks visualiseerimiseks kuulutame välja kolm loendit. Esimene, kes salvestab esimese rühma punkte – points_in_g1. Teine, kes talletab 2. grupi punkte – points_in_g2ja viimane - group, Et etikett punktid nagu kas 1 (kuulub gruppi 1) või 2 (kuulub gruppi 2):

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

Nüüd saame oma punkte korrata ja arvutada eukleidilise kauguse nende ja iga meie rühma viite vahel. Iga punkt saab olema lähemale ühte kahest rühmast – vastavalt sellele, milline grupp on lähim, määrame iga punkti vastavasse loendisse, lisades samal ajal 1 or 2 Euroopa group nimekiri:

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

Vaatame selle iteratsiooni tulemusi, et näha, mis juhtus:

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

Mille tulemuseks on:

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] 

Seaborni abil saame ka rühmitamise tulemuse joonistada erinevate värvidega vastavalt määratud rühmadele scatterplot() koos group kui hue argument:

import seaborn as sns

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

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

On selgelt näha, et 1. rühma on määratud ainult meie esimene punkt ja kõik ülejäänud punktid 2. rühma. See tulemus erineb sellest, mida me alguses ette kujutasime. Arvestades erinevust meie tulemuste ja esialgsete ootuste vahel – kas me saame seda kuidagi muuta? Tundub, et on!

Üks lähenemisviis on korrata protsessi ja valida rühmade viideteks erinevad punktid. See muudab meie tulemusi loodetavasti rohkem kooskõlas sellega, mida me alguses ette kujutasime. Sel teisel korral saime neid valida mitte juhuslikult, nagu varem, vaid hankides a keskmine kõigist meie juba grupeeritud punktidest. Nii saaks need uued punktid paigutada vastavate rühmade keskele.

Näiteks kui teisel rühmal oleks ainult punkte (10, 15), (30, 45). Uus kesk- point oleks (10 + 30)/2 ja (15+45)/2 – mis on võrdne (20, 30).

Kuna oleme oma tulemused pannud loenditesse, saame need esmalt teisendada numpy massiivid, valige nende xs, ys ja hankige seejärel keskmine:

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

Nõuanne: Proovige kasutada numpy ja NumPy massiive nii palju kui võimalik. Need on optimeeritud parema jõudluse saavutamiseks ja lihtsustavad paljusid lineaaralgebra toiminguid. Kui proovite lahendada mõnda lineaaralgebra ülesannet, peaksite kindlasti vaatama numpy dokumentatsioon, et kontrollida, kas neid on numpy meetod, mis on loodud teie probleemi lahendamiseks. Võimalus on, et see on olemas!

Protsessi kordamiseks meie uute keskpunktidega muutkem meie eelmine kood funktsiooniks, käivitage see ja vaadake, kas punktide rühmitamises on toimunud muudatusi:

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

Märge: Kui märkate, et kordate sama koodi ikka ja jälle, peaksite selle koodi mähkima eraldi funktsiooniks. Parimaks tavaks peetakse koodi korraldamist funktsioonideks, eriti kuna need hõlbustavad testimist. Kooditükki on lihtsam testida ja isoleerida kui täiskoodi ilma funktsioonideta.

Kutsume funktsiooni ja salvestame selle tulemused points_in_g1, points_in_g2ja group muutujad:

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

Rühmade jaotuse visualiseerimiseks joonistage ka värviliste punktidega hajuvusdiagramm:

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

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

Näib, et meie punktide rühmitus on Läheb paremaks. Kuid siiski on graafiku keskel kaks punkti, mida saab mõlemale rühmale määrata, kui arvestada nende lähedust mõlemale rühmale. Seni välja töötatud algoritm määrab mõlemad punktid teise rühma.

See tähendab, et võime seda protsessi tõenäoliselt korrata veel kord, võttes X-i ja Y-i keskmised, luues kaks uut keskpunkti (tsentroidid) meie rühmadesse ja määrates need ümber kauguse alusel.

Loome ka funktsiooni tsentroidide värskendamiseks. Kogu protsessi saab nüüd taandada selle funktsiooni mitmeks väljakutseks:

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)

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

Pange tähele, et pärast seda kolmandat iteratsiooni kuuluvad kõik punktid nüüd erinevatesse klastritesse. Tundub, et tulemused lähevad paremaks – teeme seda veel kord. Nüüd läheme juurde neljas iteratsioon meie meetodist:

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)

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

See neljas kord saime sama tulemus nagu eelmine. Seega tundub, et meie punktid ei vaheta enam gruppe, meie tulemus on saavutanud mingisuguse stabiilsuse – muutunud muutumatusse olekusse või lähenes. Peale selle on meil täpselt sama tulemus, nagu olime kahe rühma puhul ette kujutanud. Samuti näeme, kas sellel saavutatud jaotusel on mõtet.

Teeme kiirelt kokkuvõtte, mida oleme seni teinud. Oleme jaganud oma 10 kauplust geograafiliselt kaheks osaks – üks madalamates edelapiirkondades ja teised kirdeosas. Huvitav võib olla koguda rohkem andmeid peale juba olemasolevate – tulu, igapäevane klientide arv ja palju muud. Nii saame läbi viia põhjalikuma analüüsi ja ehk genereerida huvitavamaid tulemusi.

Selliseid rühmitusuuringuid saab läbi viia siis, kui juba väljakujunenud bränd soovib valida uue poe avamiseks piirkonna. Sel juhul võetakse peale asukoha arvesse palju rohkem muutujaid.

Mis on sellel kõigel pistmist K-Meansi algoritmiga?

Neid samme järgides võisite mõelda, mis on neil pistmist K-Meansi algoritmiga. Protsess, mille oleme seni läbi viinud, on K-Meansi algoritm. Lühidalt, oleme määranud rühmade/klastrite arvu, valinud juhuslikult algpunktid ja värskendanud tsentroidid igas iteratsioonis, kuni klastrid lähenesid. Põhimõtteliselt oleme kogu algoritmi käsitsi läbi viinud – iga sammu hoolikalt läbi viinud.

. K aastal K-Means pärineb klastrite arv mis tuleb enne iteratsiooniprotsessi alustamist seadistada. Meie puhul K=2. Seda omadust nähakse mõnikord kui negatiivne arvestades, et on ka teisi klastrite moodustamise meetodeid, näiteks hierarhiline rühmitus, millel ei pea olema eelnevalt fikseeritud arvu klastreid.

Tänu oma vahendite kasutamisele muutub ka K-vahend tundlik kõrvalekallete ja äärmuslike väärtuste suhtes – need suurendavad varieeruvust ja raskendavad meie tsentroididel oma osa täitmist. Seega olge teadlik esinemisvajadusest äärmuslikud väärtused ja kõrvalekallete analüüs enne K-Meansi algoritmi kasutades rühmitamist.

Samuti pange tähele, et meie punktid olid segmenteeritud sirgeteks osadeks, klastrite loomisel pole kõveraid. See võib olla ka K-Meansi algoritmi puuduseks.

Märge: Kui soovite, et see oleks paindlikum ja kohandatav ellipsi ja muude kujunditega, proovige kasutada a üldistatud K-tähendab Gaussi segumudel. See mudel võib kohaneda elliptiliste segmenteerimisklastritega.

K-Meansil on ka palju eelised! See toimib hästi suurte andmekogumite mille käsitlemine võib muutuda keeruliseks, kui kasutate teatud tüüpi hierarhilisi rühmitamisalgoritme. See samuti tagab konvergentsi, ja saab kergesti üldistada ja kohandama. Peale selle on see tõenäoliselt enimkasutatav klasterdamisalgoritm.

Nüüd, kui oleme läbi vaadanud kõik K-Meansi algoritmis tehtud sammud ning mõistnud kõiki selle plusse ja miinuseid, saame lõpuks K-Meansi Scikit-Learni teeki kasutades rakendada.

Kuidas rakendada K-Meansi algoritmi kasutades scikit-õppida

Tulemuse kahekordseks kontrollimiseks teeme seda protsessi uuesti, kuid nüüd kasutatakse 3 koodirida koos sklearn:

from sklearn.cluster import KMeans


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

Siin on sildid samad, mis meie eelmistel rühmadel. Joonistame tulemuse kiiresti:

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

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

Saadud graafik on sama, mis eelmises jaotises.

Tutvuge meie praktilise ja praktilise Giti õppimise juhendiga, mis sisaldab parimaid tavasid, tööstusharus aktsepteeritud standardeid ja kaasas olevat petulehte. Lõpetage Giti käskude guugeldamine ja tegelikult õppima seda!

Märge: Ainuüksi vaadates, kuidas oleme Scikit-Learni abil K-Meansi algoritmi täitnud, võib jääda mulje, et see on mõttetu ja et te ei pea selle pärast liiga palju muretsema. Vaid 3 koodirida täidavad kõik eelmises jaotises käsitletud sammud, kui oleme K-Meansi algoritmi samm-sammult üle vaadanud. Aga, kurat on detailides sel juhul! Kui te ei mõista kõiki algoritmi samme ja piiranguid, seisate tõenäoliselt silmitsi olukorraga, kus K-Meansi algoritm annab teile tulemusi, mida te ei oodanud.

Scikit-Learniga saate ka K-Meansi lähtestada kiiremaks lähenemiseks, määrates init='k-means++' argument. Laiemas plaanis K-Means++ valib ikkagi k algsed klastrikeskused juhuslikult, järgides ühtlast jaotust. Seejärel valitakse iga järgmine klastri keskpunkt ülejäänud andmepunktide hulgast mitte ainult kauguse mõõtmise, vaid tõenäosuse arvutamise teel. Tõenäosuse kasutamine kiirendab algoritmi ja on abiks väga suurte andmekogumitega tegelemisel.

Küünarnuki meetod – parima rühmade arvu valimine

Siiamaani on kõik korras! Oleme koondanud 10 kauplust punktide ja tsentroidide vahelise eukleidilise kauguse alusel. Aga kuidas on lood nende kahe punktiga graafiku keskel, mida on veidi raskem rühmitada? Kas nad ei võiks ka omaette rühma moodustada? Kas me tegelikult tegime valiku tegemisel vea K = 2 rühmad? Võib-olla meil tegelikult oli K = 3 rühmad? Meil võib olla isegi rohkem kui kolm rühma ja me pole sellest teadlikud.

Siin küsitav küsimus on kuidas määrata K-keskmistes rühmade arv (K).. Sellele küsimusele vastamiseks peame mõistma, kas K erineva väärtuse jaoks oleks "parem" klaster.

Naiivne viis selle väljaselgitamiseks on erinevate väärtustega punktide rühmitamine K, nii, jaoks K=2, K=3, K=4 ja nii edasi:

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

Kuid punktide koondamine erinevatele Ks üksi ei piisa et mõista, kas oleme valinud ideaalse väärtuse K. Me vajame viisi, kuidas hinnata igaühe klastrite kvaliteeti K oleme valinud.

Käsitsi arvutades Cluster Sum of Squares (WCSS)

Siin on ideaalne koht mõõtmaks, kui palju meie rühmitatud punktid üksteisele lähedal on. See kirjeldab sisuliselt, kui palju dispersioon meil on ühes klastris. Seda meedet nimetatakse Klastri ruutude summa seesvõi WCSS lühidalt. Mida väiksem on WCSS, seda lähemal on meie punktid, seega on meil paremini moodustatud klaster. WCSS-i valemit saab kasutada mis tahes arvu klastrite jaoks:

$$
WCSS = summa(Pi_1 – tsentroid_1)^2 + cdots + summa(Pi_n – tsentroid_n)^2
$$

Märge: Selles juhendis kasutame Eukleidese kaugus tsentroidide saamiseks, kuid kasutada võib ka muid kauguse mõõte, näiteks Manhattanit.

Nüüd võime eeldada, et oleme valinud kaks klastrit ja proovime rakendada WCSS-i, et mõista paremini, mis see WCSS on ja kuidas seda kasutada. Nagu valem ütleb, peame kokku võtma kõigi klastri punktide ja tsentroidide ruudu erinevused. Seega, kui meie esimene punkt esimesest rühmast on (5, 3) ja meie viimane tsentroid (pärast konvergentsi) esimesest rühmast 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
$$

See näide illustreerib, kuidas arvutame klastri ühe punkti WCSS-i. Kuid klaster sisaldab tavaliselt rohkem kui ühte punkti ja me peame neid kõiki WCSS-i arvutamisel arvesse võtma. Teeme seda, määratledes funktsiooni, mis võtab vastu punktide ja tsentroidide klastri ning tagastab ruutude summa:

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

Nüüd saame iga klastri ruutude summa:

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

Ja kogusumma saamiseks võtke tulemused kokku WCSS:

g1 + g2

Selle tulemuseks on:

2964.3999999999996

Niisiis, meie puhul, millal K on võrdne 2-ga, on kogu WCSS 2964.39. Nüüd saame vahetada K-sid ja arvutada nende kõigi jaoks WCSS-i. Nii saame ülevaate sellest, mida K peaksime valima, et meie rühmitus toimiks kõige paremini.

Arvutamisel WCSS Kasutamine scikit-õppida

Õnneks ei pea me igaühe jaoks WCSS-i käsitsi arvutama K. Pärast antud arvu klastrite jaoks K-Meansi klastrimist saame selle WCSS-i hankida, kasutades inertia_ atribuut. Nüüd võime minna tagasi oma K-Meansi juurde for tsükkel, kasutage seda klastrite arvu määramiseks ja vastavate WCSS-i väärtuste loetlemiseks:

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

Pange tähele, et loendi teine ​​väärtus on täpselt sama, mille jaoks oleme varem arvutanud 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]

Nende tulemuste visualiseerimiseks joonistagem meie Ks koos WCSS väärtustega:

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

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

Krundil on katkestus, kui x = 2, joone madalpunkt ja veelgi madalam, kui x = 3. Pange tähele, et see tuletab meile meelde küünarnuki kuju. Joonistades K-d koos WCSS-iga, kasutame Küünarnuki meetod Ks-i arvu valimiseks. Ja valitud K on täpselt madalaim küünarnuki punkt, nii oleks 3 asemel 2, meie puhul:

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

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

Saame uuesti käivitada K-Meansi klastri algoritmi, et näha, kuidas meie andmed koos välja näevad kolm klastrit:

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

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

Kahe klastriga olime juba rahul, kuid küünarnuki meetodi järgi sobiks meie andmetega paremini kolm klastrit. Sel juhul oleks meil kahe kaupluse asemel kolme sorti. Enne küünarnuki meetodi kasutamist mõtlesime edela- ja kirdepoolsetele kaupluste klastritele, nüüd on meil poed ka keskuses. Võib-olla võiks see olla hea koht teise poe avamiseks, kuna selle läheduses oleks vähem konkurentsi.

Alternatiivsed klastri kvaliteedimeetmed

Klastrite kvaliteedi hindamisel saab kasutada ka muid meetmeid:

  • Silueti skoor – analüüsib mitte ainult klastrisiseste punktide vahelist kaugust, vaid ka klastrite endi vahelist kaugust
  • Klastrite vahel Ruudude summa (BCSS) – WCSS-i täiendav mõõdik
  • Ruudude summa viga (ESS)
  • Maksimaalne raadius – mõõdab suurimat kaugust punktist selle tsentroidini
  • Keskmine raadius – suurima kauguse summa punktist selle tsentroidini, jagatud klastrite arvuga.

Soovitatav on neid kõiki katsetada ja tundma õppida, sest olenevalt probleemist võivad mõned alternatiivid olla rakendatavamad kui kõige laialdasemalt kasutatavad mõõdikud. (WCSS ja silhouette skoor).

Lõpuks, nagu paljude andmeteaduse algoritmide puhul, tahame vähendada dispersiooni igas klastris ja maksimeerida erinevust erinevate klastrite vahel. Seega on meil rohkem määratletud ja eraldatavaid klastreid.

K-Meansi rakendamine teisele andmekogumile

Kasutame õpitut mõnes teises andmekogumis. Seekord proovime leida sarnaseid veine.

Märge: Saate andmestiku alla laadida siin.

Alustame importimisega pandas lugeda wine-clustering CSV (Komadega eraldatud väärtused) faili a Dataframe Struktuur:

import pandas as pd

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

Pärast selle laadimist piilume rakendusega viit esimest andmekirjet head() meetod:

df.head()

Selle tulemuseks on:

	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

Meil on palju veinides sisalduvate ainete mõõtmisi. Siin ei pea me ka kategoorilisi veerge teisendama, kuna need kõik on numbrilised. Vaatame nüüd kirjeldavat statistikat describe() meetod:

df.describe().T 

Kirjeldav tabel:

 						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

Tabelit vaadates on selge, et neid on andmete varieeruvus – mõne veeru jaoks, näiteks Alchool on rohkem ja teistele, nagu Malic_Acid, vähem. Nüüd saame kontrollida, kas neid on nullvõi NaN väärtused meie andmekogumis:

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

Arvestades, et andmekogumis pole tühje väärtusi, pole vaja andmeid maha jätta ega sisestada. Me võime kasutada Seaborni pairplot() et näha andmete jaotust ja kontrollida, kas andmestik moodustab veergude paare, mis võivad klastrite jaoks olla huvitavad:

sns.pairplot(df)

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

Paaridiagrammi vaadates tunduvad kaks veergu paljulubavad rühmitamise eesmärgil – Alcohol ja OD280 (mis on meetod valgusisalduse määramiseks veinides). Näib, et kruntidel on 3 erinevat klastrit, mis ühendavad neist kahte.

On ka teisi veerge, mis näivad olevat korrelatsioonis. Eelkõige Alcohol ja Total_Phenolsja Alcohol ja Flavanoids. Neil on suurepärased lineaarsed seosed, mida saab paarisdiagrammil jälgida.

Kuna meie fookuses on K-Meansiga rühmitamine, valime näiteks ühe veergude paari Alcohol ja OD280ja testige selle andmestiku jaoks küünarnuki meetodit.

Märge: Andmestiku rohkemate veergude kasutamisel on vaja kas joonistada 3-mõõtmeline graafik või vähendada andmeid põhikomponendid (PCA kasutamine). See on kehtiv ja levinum lähenemine, lihtsalt vali põhikomponendid kindlasti selle põhjal, kui palju nad selgitavad, ja pidage meeles, et andmemõõtmete vähendamisel tekib teatav teabekadu – nii et graafik on ligikaudne tegelikest andmetest, mitte sellest, kuidas see tegelikult on.

Joonistame hajuvusdiagrammi nende kahe veeruga, mis on seatud selle teljeks, et vaadata lähemalt punkte, mida tahame rühmadesse jagada:

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

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

Nüüd saame määratleda oma veerud ja kasutada klastrite arvu määramiseks küünarnuki meetodit. Algoritmi käivitame ka rakendusega kmeans++ lihtsalt veendumaks, et see läheneb kiiremini:

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

Oleme WCSS-i arvutanud, et saaksime tulemused joonistada:

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

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

Küünarnuki meetodi järgi peaks meil siin olema 3 klastrit. Viimases etapis koondame oma punktid 3 klastrisse ja joonistame need klastrid, mis on tuvastatud värvide järgi:

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

Lõplik juhend K-Meansi rühmitamiseks Scikit-Learni PlatoBlockchaini andmeanalüüsiga. Vertikaalne otsing. Ai.

Näeme klastreid 0, 1ja 2 graafikus. Meie analüüsi põhjal grupp 0 sisaldab kõrgema valgusisaldusega ja madalama alkoholisisaldusega veine, grupp 1 on suurema alkoholisisaldusega ja madala valgusisaldusega veine ning grupp 2 on oma veinides nii kõrge valgusisaldusega kui ka kõrge alkoholisisaldusega.

See on väga huvitav andmestik ja soovitan teil analüüsiga edasi minna, rühmitades andmed pärast normaliseerimist ja PCA-d – ka tulemusi tõlgendades ja uusi seoseid otsides.

Järeldus

K-tähendab rühmitamine on lihtne, kuid väga tõhus järelevalveta masinõppe algoritm andmete rühmitamiseks. See koondab andmed eukleidilise kauguse alusel andmepunktide vahel. K-Meansi rühmitusalgoritmil on palju kasutusvõimalusi tekstidokumentide, piltide, videote ja palju muu rühmitamiseks.

Ajatempel:

Veel alates Stackabus