Pythoni ja Scikit-Learni PlatoBlockchaini andmeanalüüsiga hierarhilise klastrite lõplik juhend. Vertikaalne otsing. Ai.

Lõplik Pythoni ja Scikit-Learni hierarhilise rühmitamise juhend

Sissejuhatus

Selles juhendis keskendume selle rakendamisele Hierarhiline klasterdamisalgoritm Scikit-Learniga turundusprobleemi lahendamiseks.

Pärast juhendi lugemist saate aru:

  • Millal rakendada hierarhilist klasterdamist
  • Andmestiku visualiseerimine, et mõista, kas see sobib rühmitamiseks
  • Funktsioonide eeltöötlus ja andmestiku põhjal uute funktsioonide kavandamine
  • Kuidas PCA abil andmestiku mõõtmeid vähendada
  • Kuidas kasutada ja lugeda dendrogrammi rühmade eraldamiseks
  • Millised on erinevad linkimismeetodid ja kaugusmõõdikud, mida rakendatakse dendrogrammides ja rühmitusalgoritmides?
  • Millised on aglomeratiivsed ja jagunevad klastristrateegiad ja kuidas need toimivad
  • Kuidas rakendada Scikit-Learniga aglomeratiivset hierarhilist klasterdamist
  • Millised on kõige sagedasemad probleemid klasterdamisalgoritmidega tegelemisel ja kuidas neid lahendada

Märge: Saate alla laadida märkmiku, mis sisaldab kogu selles juhendis olevat koodi siin.

Motiveerimine

Kujutage ette stsenaariumi, mille puhul olete osa turundusosakonnaga liideses olevast andmeteaduse meeskonnast. Turundus on juba mõnda aega kogunud klientide ostuandmeid ja nad tahavad kogutud andmete põhjal aru saada, kas sarnasused klientide vahel. Need sarnasused jagavad kliendid rühmadesse ja kliendirühmade olemasolu aitab sihtida kampaaniaid, tutvustusi, konversioone ja luua paremaid kliendisuhteid.

Kas saate kuidagi aidata kindlaks teha, millised kliendid on sarnased? Kui paljud neist kuuluvad samasse rühma? Ja kui palju erinevaid gruppe on?

Üks võimalus neile küsimustele vastata on kasutada a Klastrite loomine Algoritm, nagu K-Means, DBSCAN, Hierarchical Clustering jne. Üldiselt leiavad klasterdamisalgoritmid andmepunktide vahel sarnasusi ja rühmitavad need.

Sel juhul on meie turundusandmed üsna väikesed. Meil on teavet vaid 200 kliendi kohta. Turundusmeeskonda silmas pidades on oluline, et saaksime neile selgelt selgitada, kuidas klastrite arvust lähtuvalt otsuseid langetati, seega selgitame neile, kuidas algoritm tegelikult töötab.

Kuna meie andmed on väikesed ja seletatavus on oluline tegur, saame võimendada Hierarhiline klasterdamine selle probleemi lahendamiseks. Seda protsessi tuntakse ka kui Hierarhiline klasterdamisanalüüs (HCA).

Üks HCA eeliseid on see, et see on tõlgendatav ja töötab hästi väikestes andmekogumites.

Teine asi, mida selle stsenaariumi puhul arvesse võtta, on see, et HCA on järelevalveta algoritm. Andmete rühmitamisel ei saa me kontrollida, kas tuvastame õigesti, et kasutaja kuulub konkreetsesse rühma (me ei tea rühmi). Puuduvad sildid, millega saaksime tulemusi võrrelda. Kui tuvastasime grupid õigesti, kinnitab seda hiljem turundusosakond igapäevaselt (mõõdetuna selliste mõõdikutega nagu ROI, konversioonimäärad jne).

Nüüd, kui oleme aru saanud probleemist, mida püüame lahendada ja kuidas seda lahendada, saame hakata oma andmeid vaatama!

Lühike uurimuslik andmete analüüs

Märge: Saate alla laadida selles juhendis kasutatud andmestiku siin.

Pärast andmestiku allalaadimist pange tähele, et see on a CSV (komadega eraldatud väärtused) fail nimega shopping-data.csv. Andmete uurimise ja töötlemise hõlbustamiseks laadime need a DataFrame Pandade kasutamine:

import pandas as pd


path_to_file = 'home/projects/datasets/shopping-data.csv'
customer_data = pd.read_csv(path_to_file)

Marketing teatas, et on kogunud 200 kliendikirjet. Saame kontrollida, kas allalaaditud andmed on täielikud 200 reaga, kasutades shape atribuut. See ütleb meile, mitu rida ja veerge meil on vastavalt:

customer_data.shape

Selle tulemuseks on:

(200, 5)

Suurepärane! Meie andmed on täielikud 200 reaga (kliendikirjed) ja meil on ka 5 veergu (Funktsioonid). Et näha, milliseid omadusi turundusosakond on klientidelt kogunud, näeme veergude nimesid columns atribuut. Selleks käivitage:

customer_data.columns

Ülaltoodud skript tagastab:

Index(['CustomerID', 'Genre', 'Age', 'Annual Income (k$)',
       'Spending Score (1-100)'],
      dtype='object')

Siin näeme, et turundus on tekitanud a CustomerID, kogus kokku Genre, Age, Annual Income (tuhandetes dollarites) ja a Spending Score 1-100 iga 200 kliendi kohta. Kui küsiti selgitust, ütlesid nad, et väärtused Spending Score veerg tähistab, kui sageli inimene kulutab raha kaubanduskeskuses skaalal 1–100. Teisisõnu, kui kliendi skoor on 0, ei kuluta see inimene kunagi raha ja kui skoor on 100, oleme just märganud suurim kulutaja.

Vaatame kiirelt selle skoori jaotust, et kontrollida meie andmekogus olevate kasutajate kulutamisharjumusi. Seal on Pandad hist() meetod tuleb appi:

customer_data['Spending Score (1-100)'].hist()

img

Histogrammi vaadates näeme, et enam kui 35 kliendil on hinded vahepealsed 40 ja 60, siis on vähem kui 25 hinde vahel 70 ja 80. Nii et enamik meie kliente on tasakaalustatud kulutajad, millele järgnesid mõõdukad kuni suured kulutused. Samuti näeme, et pärast on rida 0, jaotusest vasakul ja teine ​​rida enne 100 jaotusest paremal. Need tühjad ruumid tähendavad ilmselt seda, et jaotus ei sisalda mittekulutavaid tegureid, mille hindeks oleks 0, ja et pole ka suuri kulutusi, mille hind on 100.

Et kontrollida, kas see on tõsi, võime vaadata jaotuse minimaalset ja maksimaalset väärtust. Neid väärtusi saab hõlpsasti leida kirjeldavast statistikast, nii et saame kasutada describe() meetod teiste arvväärtuste jaotuste mõistmiseks:


customer_data.describe().transpose()

See annab meile tabeli, kust saame lugeda meie andmestiku muude väärtuste jaotusi:

 						count 	mean 	std 		min 	25% 	50% 	75% 	max
CustomerID 				200.0 	100.50 	57.879185 	1.0 	50.75 	100.5 	150.25 	200.0
Age 					200.0 	38.85 	13.969007 	18.0 	28.75 	36.0 	49.00 	70.0
Annual Income (k$) 		200.0 	60.56 	26.264721 	15.0 	41.50 	61.5 	78.00 	137.0
Spending Score (1-100) 	200.0 	50.20 	25.823522 	1.0 	34.75 	50.0 	73.00 	99.0

Meie hüpotees on kinnitatud. The min väärtus Spending Score is 1 ja max on 99. Nii et meil ei ole 0 or 100 skoori kulutajad. Heidame siis pilgu teistele transponeeritud veergudele describe laud. Kui vaadata mean ja std veergude puhul näeme seda Age the,en mean is 38.85 ja std umbes 13.97. Sama juhtub ka Annual IncomeKoos mean of 60.56 ja std 26.26Ning Spending Score koos mean of 50 ja std of 25.82. Kõigi funktsioonide jaoks on mean on kaugel standardhälbest, mis näitab meie andmed on suure varieeruvusega.

Et paremini mõista, kuidas meie andmed varieeruvad, joonistame graafiku Annual Income jaotus:

customer_data['Annual Income (k$)'].hist()

Mis annab meile:

img

Pange tähele histogrammil, et suurem osa meie andmetest, rohkem kui 35 klienti, on koondunud numbri lähedale 60, meie peal mean, horisontaalteljel. Aga mis juhtub, kui liigume levitamise lõppu? Vasakule liikudes on 60.560 34.300 dollari keskmisest järgmiseks väärtuseks 60.560 26.260 dollarit – keskmine (26.260 34.300 dollarit) miinus standardvariatsioon (8.040 60 dollarit). Kui läheme oma andmete jaotusest kaugemale vasakule, kehtib sarnane reegel, lahutame praegusest väärtusest (8 26.260 dollarit) standardvariatsiooni (XNUMX XNUMX dollarit). Seetõttu saame väärtuseks XNUMX $. Pange tähele, kuidas meie andmed muutusid kiiresti XNUMX XNUMX dollarilt XNUMX XNUMX dollarini. See “hüppab” iga kord XNUMX XNUMX dollarit – see on väga erinev ja seetõttu on meil nii suur varieeruvus.

img

Andmete varieeruvus ja suurus on klastrite analüüsimisel olulised, kuna enamiku klasterdamisalgoritmide kauguse mõõtmised on andmemahtude suhtes tundlikud. Suuruse erinevus võib muuta klastrite moodustamise tulemusi, muutes ühe punkti teisele lähemale või kaugemal, kui see tegelikult on, moonutades tegelikku andmete rühmitamist.

Seni oleme näinud oma andmete kuju, mõningaid nende jaotusi ja kirjeldavat statistikat. Pandade abil saame loetleda ka oma andmetüübid ja vaadata, kas kõik meie 200 rida on täidetud või on null väärtused:

customer_data.info()

Selle tulemuseks on:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 200 entries, 0 to 199
Data columns (total 5 columns):
 #   Column                  Non-Null Count  Dtype 
---  ------                  --------------  ----- 
 0   CustomerID              200 non-null    int64 
 1   Genre                   200 non-null    object
 2   Age                     200 non-null    int64 
 3   Annual Income (k$)      200 non-null    int64 
 4   Spending Score (1-100)  200 non-null    int64 
dtypes: int64(4), object(1)
memory usage: 7.9+ KB

Siin näeme, et neid pole null väärtused andmetes ja et meil on ainult üks kategooriline veerg – Genre. Selles etapis on oluline silmas pidada, millised omadused tunduvad huvitavad, mida klastrimudelisse lisada. Kui tahame oma mudelile lisada veeru Žanr, peame selle väärtused teisendama kategooriline et numbriline.

Vaatame, kuidas Genre täidetakse, vaadates kiirelt meie andmete esimest 5 väärtust:

customer_data.head() 

Selle tulemuseks on:

    CustomerID 	Genre 	Age 	Annual Income (k$) 	Spending Score (1-100)
0 	1 			Male 	19 		15 					39
1 	2 			Male 	21 		15 					81
2 	3 			Female 	20 		16 					6
3 	4 			Female 	23 		16 					77
4 	5 			Female 	31 		17 					40

Tundub, et sellel on ainult Female ja Male kategooriad. Võime selles kindlad olla, kui vaatame koos selle ainulaadsetele väärtustele unique:

customer_data['Genre'].unique()

See kinnitab meie oletust:

array(['Male', 'Female'], dtype=object)

Seni teame, et meil on ainult kaks žanrit, kui plaanime seda funktsiooni oma mudelis kasutada, Male saaks ümber kujundada 0 ja Female et 1. Samuti on oluline kontrollida žanrite vahelist proportsiooni, et näha, kas need on tasakaalus. Me saame seda teha koos value_counts() meetod ja selle argument normalize=True vahelise protsendi näitamiseks Male ja Female:

customer_data['Genre'].value_counts(normalize=True)

See annab väljundi:

Female    0.56
Male      0.44
Name: Genre, dtype: float64

Meil on andmekogumis 56% naisi ja 44% mehi. Erinevus nende vahel on vaid 16% ja meie andmed ei ole 50/50, vaid on piisavalt tasakaalustatud et mitte probleeme tekitada. Kui tulemused oleksid 70/30, 60/40, siis oleks võinud vaja minna kas rohkem andmeid koguma või mingisugust andmete suurendamise tehnikat selle suhte tasakaalustatumaks muutmiseks.

Seni kõik funktsioonid, kuid Age, on põgusalt uuritud. Millistes muredes Age, on tavaliselt huvitav jagada see prügikastidesse, et saaksite kliente nende vanuserühmade alusel segmenteerida. Kui me seda teeme, peaksime vanusekategooriad enne mudelisse lisamist üheks numbriks teisendama. Nii loeksime kategooria 15-20 aasta asemel kokku, kui palju kliente on 15-20 kategooria ja see oleks number uues veerus nimega 15-20.

Nõuanne: Selles juhendis esitame ainult lühiajalise uurimusliku andmeanalüüsi. Kuid võite minna kaugemale ja peaksite minema kaugemale. Näete, kas žanri ja vanuse järgi on sissetulekute ja punktide erinevusi. See mitte ainult ei rikasta analüüsi, vaid viib paremate mudelitulemusteni. Uurimusliku andmete analüüsiga tutvumiseks vaadake jaotist EDA peatükis "Praktiline majahinna ennustamine – masinõpe Pythonis" Juhendatud projekt.

Pärast oletamist, mida saaks teha nii kategoorilise – kui ka kategoorilise olemisega – Genre ja Age veergudel, rakendame käsitletut.

Muutujate kodeerimine ja funktsioonide projekteerimine

Alustame jagamisega Age rühmadesse, mis varieeruvad 10 võrra, nii et meil on 20-30, 30-40, 40-50 jne. Kuna meie noorim klient on 15-aastane, saame alustada 15-aastaselt ja lõpetada 70-aastaselt, mis on andmetes vanima kliendi vanus. Alustades kell 15 ja lõpetades kell 70, oleks meil 15-20, 20-30, 30-40, 40-50, 50-60 ja 60-70 intervallid.

Gruppida või konteiner Age väärtused nendesse intervallidesse, saame kasutada Pandasid cut() meetodi abil need prügikastideks lõigata ja seejärel prügikastid uuele määrata Age Groups veerg:

intervals = [15, 20, 30, 40, 50, 60, 70]
col = customer_data['Age']
customer_data['Age Groups'] = pd.cut(x=col, bins=intervals)


customer_data['Age Groups'] 

Selle tulemuseks on:

0      (15, 20]
1      (20, 30]
2      (15, 20]
3      (20, 30]
4      (30, 40]
         ...   
195    (30, 40]
196    (40, 50]
197    (30, 40]
198    (30, 40]
199    (20, 30]
Name: Age Groups, Length: 200, dtype: category
Categories (6, interval[int64, right]): [(15, 20] < (20, 30] < (30, 40] < (40, 50] < (50, 60] < (60, 70]]

Pange tähele, et veergude väärtuste vaatamisel on olemas ka rida, mis määrab, et meil on 6 kategooriat ja kuvatakse kõik bineeritud andmeintervallid. Sel viisil oleme oma varasemad numbrilised andmed kategoriseerinud ja loonud uue Age Groups funktsioon.

Ja kui palju kliente meil igas kategoorias on? Seda saame kiiresti teada, rühmitades veeru ja loendades väärtused koos groupby() ja count():

customer_data.groupby('Age Groups')['Age Groups'].count()

Selle tulemuseks on:

Age Groups
(15, 20]    17
(20, 30]    45
(30, 40]    60
(40, 50]    38
(50, 60]    23
(60, 70]    17
Name: Age Groups, dtype: int64

On lihtne märgata, et enamik kliente on vanuses 30–40 aastat, järgnevad 20–30-aastased ja seejärel 40–50-aastased kliendid. See on hea teave ka turundusosakonnale.

Praegu on meil kaks kategoorilist muutujat, Age ja Genre, mille peame oma mudelis kasutamiseks teisendama numbriteks. Selle ümberkujundamiseks on palju erinevaid viise – me kasutame Pandasid get_dummies() meetod, mis loob iga intervalli ja žanri jaoks uue veeru ja täidab seejärel selle väärtused 0-de ja 1-dega – sellist operatsiooni nimetatakse üks kuum kodeering. Vaatame, kuidas see välja näeb:


customer_data_oh = pd.get_dummies(customer_data)

customer_data_oh 

See annab meile saadud tabelist eelvaate:

img

Väljundiga on lihtne näha, et veerg Genre jagati veergudeks – Genre_Female ja Genre_Male. Kui klient on naine, Genre_Female on võrdne 1, ja kui klient on meessoost, on see võrdne 0.

Samuti Age Groups veerg jaotati 6 veergu, üks iga intervalli jaoks, näiteks Age Groups_(15, 20], Age Groups_(20, 30], ja nii edasi. Samamoodi nagu Genre, kui klient on 18-aastane, Age Groups_(15, 20] väärtus ei 1 ja kõigi teiste veergude väärtus on 0.

. eelis ühekuulise kodeeringu puhul on veergude väärtuste esitamise lihtsus, toimuvast on lihtne aru saada – samas kui puuduseks on see, et oleme nüüd loonud 8 täiendavat veergu, kokkuvõtteks juba olemasolevate veergudega.

Hoiatus: kui teil on andmestik, milles ühe kuumusega kodeeritud veergude arv ületab ridade arvu, on andmete mõõtmetega seotud probleemide vältimiseks kõige parem kasutada muud kodeerimismeetodit.

One-hot-kodeering lisab meie andmetele ka nullid, muutes need hõredamaks, mis võib osutuda probleemiks mõnede andmete hõreduse suhtes tundlike algoritmide puhul.

Meie rühmitamise vajaduste jaoks näib ühe kuuma kodeering töötavat. Kuid me saame andmed joonistada, et näha, kas meil on tõesti rühmitamiseks erinevad rühmad.

Põhiline joonistamine ja mõõtmete vähendamine

Meie andmestikul on 11 veergu ja on mõned viisid, kuidas neid andmeid visualiseerida. Esimene on selle 10-mõõtmelise graafiku abil (sellega palju õnne). Kümme, sest Customer_ID veergu ei arvestata. Teine on meie esialgsete numbriliste tunnuste joonistamine ja kolmas on meie 10 tunnuse teisendamine kaheks – seega mõõtmete vähendamise teostamine.

Iga andmepaari joonistamine

Kuna 10 mõõtme joonistamine on veidi võimatu, valime teise lähenemisviisi – joonistame oma esialgsed omadused. Saame oma klastrianalüüsi jaoks valida neist kaks. Üks viis, kuidas näeme kõiki meie andmepaare kombineerituna, on Seaborn pairplot():

import seaborn as sns


customer_data = customer_data.drop('CustomerID', axis=1)

sns.pairplot(customer_data)

Mis kuvab:

img

Lühidalt võime märgata hajuvusgraafikuid, millel näib olevat andmerühmi. Üks, mis tundub huvitav, on hajuvusjoon, mis ühendab Annual Income ja Spending Score. Pange tähele, et teiste muutujate hajuvusdiagrammide vahel pole selget eraldust. Maksimaalselt võime öelda, et punktides on kaks erinevat punktide kontsentratsiooni Spending Score vs Age hajuvusdiagramm.

Mõlemad hajuvusdiagrammid, mis koosnevad Annual Income ja Spending Score on sisuliselt samad. Me näeme seda kaks korda, kuna x- ja y-telg olid vahetatud. Vaadates mõnda neist, näeme, mis näib olevat viis erinevat rühma. Joonistame Seaborniga just need kaks omadust scatterplot() et lähemalt vaadata:

sns.scatterplot(x=customer_data['Annual Income (k$)'],
                y=customer_data['Spending Score (1-100)'])

img

Lähemalt vaadates saame kindlasti eristada 5 erinevat andmerühma. Näib, et meie kliente saab rühmitada selle põhjal, kui palju nad aastas teenivad ja kui palju kulutavad. See on veel üks oluline punkt meie analüüsis. On oluline, et võtaksime oma klientide rühmitamisel arvesse ainult kahte funktsiooni. Muu teave, mis meil nende kohta on, ei kuulu võrrandisse. See annab analüüsile tähenduse – kui teame, kui palju klient teenib ja kulutab, leiame lihtsalt vajalikud sarnasused.

img

See on suurepärane! Seni on meil mudeli koostamiseks juba kaks muutujat. Lisaks sellele, mida see esindab, muudab see mudeli ka lihtsamaks, tagasihoidlikumaks ja paremini seletatavaks.

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: Andmeteadus eelistab tavaliselt võimalikult lihtsaid lähenemisviise. Mitte ainult sellepärast, et seda on ettevõtte jaoks lihtsam selgitada, vaid ka seetõttu, et see on otsesem – 2 funktsiooni ja seletatava mudeliga on selge, mida mudel teeb ja kuidas see töötab.

Andmete joonistamine pärast PCA kasutamist

Tundub, et meie teine ​​lähenemine on ilmselt parim, kuid vaatame ka meie kolmandat lähenemist. See võib olla kasulik, kui me ei saa andmeid joonistada, kuna neil on liiga palju dimensioone või kui andmed ei ole koondunud ega rühmades selgelt eraldatud. Kui sellised olukorrad ilmnevad, on soovitatav proovida andmete dimensioone vähendada meetodi abil Põhikomponentide analüüs (PCA).

Märge: Enamik inimesi kasutab PCA-d mõõtmete vähendamiseks enne visualiseerimist. On ka teisi meetodeid, mis aitavad enne rühmitamist andmeid visualiseerida, näiteks Müraga rakenduste tiheduspõhine ruumiline rühmitamine (DBSCAN) ja Iseorganiseerivad kaardid (SOM) rühmitamine. Mõlemad on klasterdamisalgoritmid, kuid neid saab kasutada ka andmete visualiseerimiseks. Kuna klastrianalüüsil pole kuldset standardit, on oluline võrrelda erinevaid visualiseerimisi ja erinevaid algoritme.

PCA vähendab meie andmete mõõtmeid, püüdes samal ajal säilitada nii palju teavet kui võimalik. Saame esmalt aimu, kuidas PCA töötab, ja seejärel saame valida, mitme andmemõõtmeni me oma andmeid redutseerime.

Iga funktsioonipaari puhul vaatab PCA, kas ühe muutuja suuremad väärtused vastavad teise muutuja suurematele väärtustele, ja teeb sama ka väiksemate väärtuste puhul. Seega arvutab see sisuliselt välja, kui palju funktsioonide väärtused üksteise suhtes erinevad – me nimetame seda nendeks kovariantsus. Seejärel jagatakse need tulemused maatriksiks, saades a kovariatsioonimaatriks.

Pärast kovariatsioonimaatriksi saamist püüab PCA leida seda kõige paremini selgitava funktsioonide lineaarse kombinatsiooni – see sobib lineaarsete mudelitega, kuni tuvastab selle, mis selgitab maksimaalne dispersiooni suurus.

märkused: PCA on lineaarne teisendus ja lineaarsus on tundlik andmete skaala suhtes. Seetõttu töötab PCA kõige paremini, kui kõik andmeväärtused on samal skaalal. Seda saab teha veeru lahutamisega keskmine selle väärtustest ja jagades tulemuse selle standardhälbega. Seda nimetatakse andmete standardimine. Enne PCA kasutamist veenduge, et andmed on skaleeritud! Kui te pole kindel, kuidas seda teha, lugege meie artiklit Funktsioonide skaleerimine Scikit-Learniga masinõppeks Pythonis!

Parima leitud joonega (lineaarne kombinatsioon) saab PCA oma telgede suunad, nn omavektorid, ja selle lineaarsed koefitsiendid, omaväärtused. Omavektorite ja omaväärtuste või telgede suundade ja koefitsientide kombinatsioon on Põhikomponendid PCA. Ja just siis saame valida oma dimensioonide arvu iga funktsiooni selgitatud dispersiooni põhjal, mõistes, milliseid põhikomponente tahame säilitada või neist loobuda, lähtudes sellest, kui suurt dispersiooni need seletavad.

Pärast põhikomponentide saamist kasutab PCA omavektoreid, et moodustada tunnuste vektor, mis suunab andmed ümber algsetelt telgedelt põhikomponentidega esindatavatele – nii vähendatakse andmete mõõtmeid.

Märge: Üks oluline detail, mida siinkohal arvesse võtta, on see, et PCA koondab oma lineaarse olemuse tõttu suurema osa seletatud dispersioonist esimestesse põhikomponentidesse. Seega, kui vaadata selgitatud dispersiooni, siis tavaliselt piisab meie kahest esimesest komponendist. Kuid see võib mõnel juhul olla eksitav – proovige rühmitamisel võrrelda erinevaid graafikuid ja algoritme, et näha, kas need annavad sarnaseid tulemusi.

Enne PCA rakendamist peame valima nende vahel Age veerg või Age Groups veerud meie varem ühe kuumusega kodeeritud andmetes. Kuna mõlemad veerud esindavad sama teavet, mõjutab selle kahekordne sisestamine meie andmete dispersiooni. Kui Age Groups veerg on valitud, eemaldage lihtsalt Age veerus Pandade abil drop() meetod ja määrake see uuesti customer_data_oh muutuja:

customer_data_oh = customer_data_oh.drop(['Age'], axis=1)
customer_data_oh.shape 

Nüüd on meie andmetel 10 veergu, mis tähendab, et saame veergude kaupa hankida ühe põhikomponendi ja valida, kui paljusid neist kasutame, mõõtes, kui palju ühe uue dimensiooni juurutamine meie andmete dispersiooni rohkem selgitab.

Teeme seda Scikit-Learniga PCA. Arvutame iga mõõtme selgitatud dispersiooni, mis on antud explained_variance_ratio_ ja seejärel vaadake nende kumulatiivset summat koos cumsum() :

from sklearn.decomposition import PCA

pca = PCA(n_components=10)
pca.fit_transform(customer_data_oh)
pca.explained_variance_ratio_.cumsum()

Meie kumulatiivsed selgitatud dispersioonid on järgmised:

array([0.509337  , 0.99909504, 0.99946364, 0.99965506, 0.99977937,
       0.99986848, 0.99993716, 1.        , 1.        , 1.        ])

Näeme, et esimene dimensioon selgitab 50% andmetest ja teise dimensiooniga kombineerituna selgitavad need 99% protsenti. See tähendab, et esimesed 2 mõõdet selgitavad juba 99% meie andmetest. Nii saame rakendada kahe komponendiga PCA-d, hankida peamised komponendid ja joonistada need:

from sklearn.decomposition import PCA

pca = PCA(n_components=2)
pcs = pca.fit_transform(customer_data_oh)

pc1_values = pcs[:,0]
pc2_values = pcs[:,1]
sns.scatterplot(x=pc1_values, y=pc2_values)

img

Andmegraafik pärast PCA-d on väga sarnane diagrammiga, mis kasutab ainult kahte andmete veergu ilma PCA-ta. Pange tähele, et punktid, mis moodustavad rühmi, on pärast PCA-d lähemal ja veidi kontsentreeritumad kui varem.

img

Hierarhilise struktuuri visualiseerimine dendrogrammidega

Siiani oleme uurinud andmeid, ühe kiirelt kodeeritud kategoorilisi veerge, otsustanud, millised veerud sobivad rühmitamiseks, ja vähendanud andmete mõõtmeid. Diagrammid näitavad, et meie andmetes on 5 klastrit, kuid on ka teine ​​viis punktide vaheliste seoste visualiseerimiseks ja klastrite arvu määramiseks – luues dendrogramm (tavaliselt valesti kirjutatud kui dendogramm). dendro vahendid puu ladina keeles.

. dendrogramm on andmestiku punktide sidumise tulemus. See on hierarhilise klastrite moodustamise protsessi visuaalne esitus. Ja kuidas hierarhiline klastrite moodustamise protsess toimib? Noh... see oleneb – tõenäoliselt olete vastus, mida olete andmeteaduses juba palju kuulnud.

Hierarhilise klastrite mõistmine

Kui Hierarhiline klasterdamisalgoritm (HCA) hakkab punkte linkima ja klastreid otsima, võib see kõigepealt jagada punktid 2 suureks rühmaks ja seejärel jagada need kaks rühma kaheks väiksemaks rühmaks, milles on kokku 2 rühma, mis on lõhestav ja ülevalt alla lähenemist.

Teise võimalusena võib see toimida ka vastupidiselt – see võib vaadata kõiki andmepunkte, leida 2 üksteisele lähemal olevat punkti, linkida need ja seejärel leida teised punktid, mis on nendele lingitud punktidele kõige lähemal, ning jätkata kahe rühma loomist. alates põhjani. Milline on aglomeratiivne lähenemisviisi, mida me arendame.

Aglomeratiivse hierarhilise rühmitamise etapid

Aglomeratiivse lähenemisviisi veelgi selgemaks muutmiseks on olemas järgmised sammud Aglomeratiivne hierarhiline klaster (AHC) algoritm:

  1. Alguses käsitlege iga andmepunkti ühe klastrina. Seetõttu on klastrite arv alguses K – samas kui K on täisarv, mis tähistab andmepunktide arvu.
  2. Moodustage klaster, ühendades kaks lähimat andmepunkti, mille tulemuseks on K-1 klastrid.
  3. Moodustage rohkem klastreid, ühendades kaks lähimat klastrit, mille tulemuseks on K-2 klastrid.
  4. Korrake ülaltoodud kolme sammu, kuni moodustub üks suur kobar.

märkused: Lihtsustuse huvides ütleme sammudes 2 ja 3 "kaks lähimat" andmepunkti. Kuid punktide ühendamiseks on rohkem võimalusi, nagu näeme veidi hiljem.

If you invert the steps of the ACH algorithm, going from 4 to 1 – those would be the steps to *Divitive Hierarchical Clustering (DHC)*.

Pange tähele, et HCA-d võivad olla lahutavad ja ülalt-alla või aglomeratiivsed ja alt-üles. Ülalt-alla DHC-lähenemine töötab kõige paremini, kui teil on vähem, kuid suuremaid klastreid, seega on see arvutuslikult kulukam. Teisest küljest on alt-üles AHC-lähenemine sobilik siis, kui teil on palju väiksemaid klastreid. See on arvutuslikult lihtsam, rohkem kasutatud ja kättesaadavam.

Märge: Kas ülalt alla või alt üles, algab klastrite moodustamise protsessi dendrogrammi esitus alati kaheks jagamisega ja lõpeb iga üksiku punkti eristamisega, kui selle alusstruktuur on kahendpuust.

Joonistame oma kliendiandmete dendrogrammi, et visualiseerida andmete hierarhilisi seoseid. Seekord kasutame scipy teek meie andmekogumi dendrogrammi loomiseks:

import scipy.cluster.hierarchy as shc
import matplotlib.pyplot as plt

plt.figure(figsize=(10, 7))
plt.title("Customers Dendrogram")


selected_data = customer_data_oh.iloc[:, 1:3]
clusters = shc.linkage(selected_data, 
            method='ward', 
            metric="euclidean")
shc.dendrogram(Z=clusters)
plt.show()

Skripti väljund näeb välja selline:

img

Ülaltoodud skriptis oleme loonud oma punktidega klastrid ja alamklastrid ning määratlenud, kuidas meie punktid seostuvad (rakendatud ward meetod) ja kuidas mõõta punktide vahelist kaugust (kasutades euclidean meetriline).

Dendrogrammi graafiku abil saab visualiseerida kirjeldatud DHC ja AHC protsesse. Ülalt-alla lähenemisviisi visualiseerimiseks alustage dendrogrammi ülaosast ja minge alla ning tehke vastupidist, alustades alla ja liikudes üles, et visualiseerida alt-üles lähenemisviisi.

Ühendusmeetodid

On palju muid sidumismeetodeid. Kui mõistate rohkem nende toimimist, saate valida oma vajadustele sobiva. Lisaks annab igaüks neist rakendamisel erinevaid tulemusi. Klasterdusanalüüsis pole kindlat reeglit, võimalusel uuri probleemi olemust, et näha, milline sobib kõige paremini, katseta erinevaid meetodeid ja kontrolli tulemusi.

Mõned sidumismeetodid on järgmised:

  • Üksikühendus: nimetatud ka kui Lähim naaber (NN). Klastrite vaheline kaugus määratakse nende lähimate liikmete vahelise kaugusega.

img

  • Täielik sidumine: nimetatud ka kui Kaugem naaber (FN), Kaugeima punkti algoritmvõi Voor Heesi algoritm. Klastrite vaheline kaugus määratakse nende kaugeimate liikmete vahelise kaugusega. See meetod on arvutuslikult kallis.

img

  • Keskmine seos: tuntud ka kui UPGMA (Kaalumata paarirühma meetod aritmeetilise keskmisega). Iga klastri punktide arvu protsent arvutatakse kahe klastri punktide arvu suhtes, kui need liidetakse.

img

  • Kaalutud ühendus: tuntud ka kui WPGMA (Kaalutud paari rühma meetod aritmeetilise keskmisega). Kahe klastri üksikud punktid aitavad kaasa väiksema ja suurema klastri koondkaugusele.
  • Tsentroidühendus: nimetatud ka kui UPGMC (Kaalumata paarirühma meetod tsentroidide abil). Iga klastri jaoks arvutatakse kõigi punktide keskmisena määratletud punkt (tsentroid) ja klastrite vaheline kaugus on nende vastavate tsentroidide vaheline kaugus.

img

  • Jaoskonna ühendus: Tuntud ka kui MISSQ (Ruudude summa minimaalne suurenemine). See määrab kahe klastri vahelise kauguse, arvutab vea ruutude summa (ESS) ja valib järjestikku järgmised klastrid väiksema ESS alusel. Wardi meetodi eesmärk on minimeerida ESS-i suurenemist igal etapil. Seetõttu minimeerige viga.

img

Kauguse mõõdikud

Lisaks seostele saame määrata ka mõned enimkasutatavad kaugusmõõdikud:

  • eukleidiline: nimetatud ka kui Pythagorase ehk sirgjoon vahemaa. See arvutab kahe ruumipunkti vahelise kauguse, mõõtes nende vahelt läbiva joonelõigu pikkust. See kasutab Pythagorase teoreemi ja tulemuseks on kauguse väärtus (C) võrrandist:

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

  • Manhattan: nimetatud ka Linnakvartal, takso vahemaa. See on kahe punkti kõigi mõõtmete mõõtude absoluutsete erinevuste summa. Kui need mõõdud on kaks, on see analoogne ühe ploki kõndimisel paremale ja seejärel vasakule.

img

  • Minkowski: see on nii Eukleidilise kui Manhattani kauguste üldistus. See on viis kauguste arvutamiseks absoluutsete erinevuste põhjal Minkowski meetrika järjekorras p. Kuigi see on määratletud mis tahes p> 0, kasutatakse seda harva muude väärtuste puhul peale 1, 2 ja ∞ (lõpmatu). Minkowski kaugus on sama kui Manhattani kaugus p = 1, ja sama mis Eukleidiline kaugus, kui p = 2.

$$
Dleft(X,Yright) = vasak(summa_{i=1}^n |x_i-y_i|^pright)^{frac{1}{p}}
$$

img

  • Chebyshev: tuntud ka kui Malelaud vahemaa. See on Minkowski distantsi äärmuslik juhtum. Kui kasutame parameetri väärtusena lõpmatust p (p = ∞), saame tulemuseks mõõdiku, mis määratleb kauguse kui koordinaatide maksimaalse absoluutse erinevuse.
  • Kosineen: see on nurkkoosinuskaugus kahe punktijada või vektori vahel. Koosinussarnasus on vektorite punktkorrutis, mis on jagatud nende pikkuste korrutisega.
  • Jaccard: mõõdab sarnasust lõplike punktihulkade vahel. See on määratletud kui punktide koguarv (kardinaalsus) ühistes punktides igas komplektis (ristmik), mis on jagatud mõlema hulga punktide koguarvuga (kardinaalsus) mõlema hulga punktide koguarvuga (liit).
  • Jensen-Shannon: Kullback-Leibleri lahknevuse põhjal. See võtab arvesse punktide tõenäosusjaotust ja mõõdab nende jaotuste vahelist sarnasust. See on populaarne tõenäosusteooria ja statistika meetod.

Oleme valinud Eestkostetav ja eukleidiline dendrogrammi jaoks, sest need on kõige sagedamini kasutatav meetod ja mõõdik. Tavaliselt annavad need häid tulemusi, kuna Ward seob punkte vigade minimeerimise põhjal ja Euclidean töötab hästi ka väiksemate mõõtmetega.

Selles näites töötame kahe turundusandmete funktsiooni (veeru) ja 200 vaatluse või reaga. Kuna vaatluste arv on suurem kui tunnuste arv (200 > 2), töötame madalamõõtmelises ruumis.

Kui funktsioonide arv (F) on suurem kui vaatluste arv (N) – enamasti kirjutatud kui f >> N, see tähendab, et meil on a suuremõõtmeline ruum.

Kui lisaksime rohkem atribuute, nii et meil on üle 200 tunnuse, ei pruugi Eukleidiline kaugus väga hästi töötada, kuna sellel oleks raskusi kõigi väikeste vahemaade mõõtmisega väga suures ruumis, mis ainult suureneb. Teisisõnu, eukleidilise kauguse lähenemisviisil on andmetega töötamisel raskusi hõredus. See on probleem, mida nimetatakse mõõtmete needus. Kauguse väärtused muutuvad nii väikeseks, nagu muutuksid need suuremas ruumis "lahjenetuks", moonutuks, kuni need muutuvad nulliks.

Märge: Kui puutute kokku andmekogumiga f >> lk, kasutate tõenäoliselt muid kaugusmõõdikuid, näiteks Mahalanobis vahemaa. Teise võimalusena saate andmestiku mõõtmeid vähendada, kasutades Põhikomponentide analüüs (PCA). See probleem on sagedane, eriti bioloogiliste järjestuste andmete rühmitamisel.

Oleme juba arutanud mõõdikuid, seoseid ja seda, kuidas igaüks neist võib meie tulemusi mõjutada. Jätkame nüüd dendrogrammi analüüsi ja vaatame, kuidas see võib anda meile ülevaate meie andmekogumis olevate klastrite arvust.

Huvitava hulga klastrite leidmine dendrogrammis on sama, mis suurima horisontaalse ruumi leidmine, millel pole vertikaalseid jooni (pikimate vertikaalsete joontega ruum). See tähendab, et klastrite vahel on suurem eraldatus.

Saame tõmmata horisontaalse joone, mis läbib selle pikima vahemaa:

plt.figure(figsize=(10, 7))
plt.title("Customers Dendogram with line")
clusters = shc.linkage(selected_data, 
            method='ward', 
            metric="euclidean")
shc.dendrogram(clusters)
plt.axhline(y = 125, color = 'r', linestyle = '-')

img

Pärast horisontaalse joone asukoha määramist loendame, mitu korda meie vertikaaljooni see ületas – antud näites 5 korda. Nii et 5 näib olevat hea näitaja nende klastrite arvu kohta, mille vahel on kõige suurem vahemaa.

märkused: Dendrogrammi tuleks klastrite arvu valimisel kasutada ainult viitena. See võib selle numbri hõlpsalt kõrvale kalduda ja seda mõjutavad täielikult sideme tüüp ja kaugusmõõdikud. Põhjaliku klasteranalüüsi läbiviimisel on soovitatav vaadata erinevate seoste ja mõõdikutega dendrogramme ning vaadata tulemusi, mis on genereeritud esimese kolme reaga, kus klastrite vahel on kõige suurem vahemaa.

Aglomeratiivse hierarhilise klastri rakendamine

Algandmete kasutamine

Siiani oleme arvutanud oma andmestiku jaoks soovitatud arvu klastreid, mis kinnitavad meie esialgset analüüsi ja meie PCA analüüsi. Nüüd saame Scikit-Learni abil luua oma aglomeratiivse hierarhilise klastrimudeli AgglomerativeClustering ja uurige turunduspunktide silte labels_:

from sklearn.cluster import AgglomerativeClustering

clustering_model = AgglomerativeClustering(n_clusters=5, affinity='euclidean', linkage='ward')
clustering_model.fit(selected_data)
clustering_model.labels_

Selle tulemuseks on:

array([4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3,
       4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 1,
       4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 0, 2, 0, 2,
       1, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 2, 1, 2, 0, 2, 0, 2, 0, 2,
       0, 2, 0, 2, 0, 2, 1, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2,
       0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2,
       0, 2])

Oleme selle punktini jõudmiseks palju uurinud. Ja mida need sildid tähendavad? Siin on meie andmete iga punkt tähistatud rühmana vahemikus 0 kuni 4:

data_labels = clustering_model.labels_
sns.scatterplot(x='Annual Income (k$)', 
                y='Spending Score (1-100)', 
                data=selected_data, 
                hue=data_labels,
                pallete="rainbow").set_title('Labeled Customer Data')

img

Need on meie lõplikud rühmitatud andmed. Näete värvikoodiga andmepunkte viie klastri kujul.

Andmepunktid all paremal (silt: 0, lillad andmepunktid) kuuluvad kõrge palgaga, kuid madalate kulutustega klientidele. Need on kliendid, kes kulutavad oma raha hoolikalt.

Samamoodi paremas ülanurgas olevad kliendid (silt: 2, rohelised andmepunktid), on kõrge palga ja suurte kulutustega kliendid. Seda tüüpi kliente ettevõtted sihivad.

Kliendid keskel (silt: 1, sinised andmepunktid) on keskmise sissetuleku ja keskmise kulutusega. Sellesse kategooriasse kuulub kõige rohkem kliente. Ettevõtted saavad ka neid kliente sihtida, kuna neid on tohutult palju.

Kliendid all vasakul (silt: 4, punane) on madala palga ja madalate kulutustega kliendid, keda võidakse meelitada pakkumiste pakkumine.

Ja lõpuks, kliendid vasakus ülanurgas (silt: 3, oranžid andmepunktid) on need, millel on suur sissetulek ja väikesed kulutused, mis on ideaalis turunduse sihikule.

PCA tulemuste kasutamine

Kui oleksime teistsuguses stsenaariumis, mille puhul peaksime vähendama andmete mõõtmelisust. Samuti saaksime hõlpsalt joonistada rühmitatud PCA tulemusi. Seda saab teha, luues teise aglomeratiivse klastrite mudeli ja hankides iga põhikomponendi jaoks andmesildi:

clustering_model_pca = AgglomerativeClustering(n_clusters=5, affinity='euclidean', linkage='ward')
clustering_model_pca.fit(pcs)

data_labels_pca = clustering_model_pca.labels_

sns.scatterplot(x=pc1_values, 
                y=pc2_values,
                hue=data_labels_pca,
                palette="rainbow").set_title('Labeled Customer Data Reduced with PCA')

img

Pange tähele, et mõlemad tulemused on väga sarnased. Peamine erinevus seisneb selles, et esimest tulemust algandmetega on palju lihtsam seletada. Selgelt on näha, et aasta sissetulekute ja kulutuste skoori järgi saab kliendid jagada viide rühma. Kuigi PCA lähenemisviisi puhul võtame arvesse kõiki oma funktsioone, nii palju kui suudame vaadata nende erinevusi, on seda mõistet raskem mõista, eriti turundusosakonnale aru andes.

Mida vähem peame oma andmeid muutma, seda parem.

Kui teil on väga suur ja keeruline andmestik, milles peate enne rühmitamist mõõtmete vähendamise tegema, proovige analüüsida lineaarseid seoseid iga funktsiooni ja nende jääkide vahel, et varundada PCA kasutamist ja suurendada protsessi seletatavust. Luues lineaarse mudeli funktsioonide paari kohta, saate aru, kuidas funktsioonid omavahel suhtlevad.

Kui andmemaht on nii suur, on võimatu joonistada tunnuspaare, valida võimalikult tasakaalustatud ja normaaljaotuse lähedase andmete valim ning teha esmalt valimi analüüs, mõista seda, peenhäälestada. ja rakendage seda hiljem kogu andmekogumile.

Alati saab valida erinevaid klastrite visualiseerimise tehnikaid vastavalt andmete olemusele (lineaarne, mittelineaarne) ja neid kõiki vajadusel kombineerida või testida.

Järeldus

Klastrite moodustamise tehnika võib olla väga mugav, kui tegemist on märgistamata andmetega. Kuna suurem osa reaalses maailmas olevatest andmetest on märgistamata ja andmete märkimisega kaasnevad suuremad kulud, saab märgistamata andmete märgistamiseks kasutada klasterdamistehnikaid.

Selles juhendis oleme toonud tõelise andmeteaduse probleemi, kuna klastritehnikaid kasutatakse turundusanalüüsis (ja ka bioloogilises analüüsis) suures osas. Samuti oleme selgitanud paljusid uurimisetappe, et jõuda hea hierarhilise klastrimudelini ja kuidas lugeda dendrogramme, ning küsinud, kas PCA on vajalik samm. Meie peamine eesmärk on, et mõned lõksud ja erinevad stsenaariumid, mille puhul leiame hierarhilise rühmituse, oleksid kaetud.

Head rühmitamist!

Ajatempel:

Veel alates Stackabus