K-anordning Clustering i R med Eksempel
Hva er Cluster analyse?
Cluster analyse er en del av uovervåket læring. En klynge er en gruppe data som deler lignende funksjoner. Vi kan si at klyngeanalyse handler mer om oppdagelse enn en prediksjon. Maskinen søker etter likhet i dataene. Du kan for eksempel bruke klyngeanalyse for følgende applikasjon:
- Kundesegmentering: Ser etter likhet mellom grupper av kunder
- Aksjeklynger: Gruppeaksjer basert på resultater
- Reduser dimensjonaliteten til et datasett ved å gruppere observasjoner med lignende verdier
Clusteringanalyse er ikke for vanskelig å implementere og er både meningsfylt og handlingsdyktig for virksomheten.
Den mest slående forskjellen mellom veiledet og uovervåket læring ligger i resultatene. Uovervåket læring skaper en ny variabel, etiketten, mens veiledet læring forutsier et utfall. Maskinen hjelper utøveren i oppdraget med å merke dataene basert på nær slektskap. Det er opp til analytikeren å gjøre bruk av gruppene og gi dem et navn.
La oss lage et eksempel for å forstå begrepet klynging. For enkelhets skyld jobber vi i to dimensjoner. Du har data om det totale forbruket til kunder og deres alder. For å forbedre annonseringen ønsker markedsføringsteamet å sende mer målrettede e-poster til kundene sine.
I den følgende grafen plotter du det totale forbruket og alderen til kundene.
library(ggplot2) df <- data.frame(age = c(18, 21, 22, 24, 26, 26, 27, 30, 31, 35, 39, 40, 41, 42, 44, 46, 47, 48, 49, 54), spend = c(10, 11, 22, 15, 12, 13, 14, 33, 39, 37, 44, 27, 29, 20, 28, 21, 30, 31, 23, 24) ) ggplot(df, aes(x = age, y = spend)) + geom_point()
Et mønster er synlig på dette punktet
- Nederst til venstre ser du unge med lavere kjøpekraft
- Øvre midtre reflekterer folk med en jobb som de har råd til å bruke mer
- Til slutt eldre med lavere budsjett.
I figuren ovenfor grupperer du observasjonene for hånd og definerer hver av de tre gruppene. Dette eksemplet er noe enkelt og svært visuelt. Hvis nye observasjoner legges til datasettet, kan du merke dem i kretsene. Du definerer sirkelen basert på vår vurdering. I stedet kan du bruke Maskinlæring å gruppere dataene objektivt.
I denne opplæringen lærer du hvordan du bruker k-betyr algoritme.
K-betyr algoritme
K-mean er uten tvil den mest populære klyngemetoden. Forskere ga ut algoritmen for flere tiår siden, og mange forbedringer har blitt gjort på k-means.
Algoritmen prøver å finne grupper ved å minimere avstanden mellom observasjonene, kalt lokalt optimalt løsninger. Avstandene måles ut fra koordinatene til observasjonene. For eksempel, i et todimensjonalt rom, er koordinatene enkle og .
Algoritmen fungerer som følger:
- Trinn 1: Velg grupper i funksjonsplanen tilfeldig
- Trinn 2: Minimer avstanden mellom klyngesenteret og de forskjellige observasjonene (Tyngdepunktet). Det resulterer i grupper med observasjoner
- Trinn 3: Shift starttyngdepunktet til gjennomsnittet av koordinatene i en gruppe.
- Trinn 4: Minimer avstanden i henhold til de nye tyngdepunktene. Nye grenser skapes. Dermed vil observasjoner flytte fra en gruppe til en annen
- Gjenta til ingen observasjon endrer gruppe
K-means tar vanligvis den euklidiske avstanden mellom funksjonen og funksjonen:
Ulike mål er tilgjengelige som Manhattan-avstanden eller Minlowski-avstanden. Merk at K-mean returnerer forskjellige grupper hver gang du kjører algoritmen. Husk at de første innledende gjetningene er tilfeldige og beregne avstandene til algoritmen når en homogenitet i grupper. Det vil si at k-middel er veldig følsomt for førstevalget, og med mindre antall observasjoner og grupper er lite, er det nesten umulig å få samme klynging.
Velg antall klynger
En annen vanskelighet funnet med k-middel er valget av antall klynger. Du kan sette en høy verdi på, dvs. et stort antall grupper, for å forbedre stabiliteten, men du kan ende opp med overfitt av data. Overtilpasning betyr at ytelsen til modellen reduseres betydelig for nye kommende data. Maskinen lærte de små detaljene i datasettet og strever med å generalisere det generelle mønsteret.
Antall klynger avhenger av typen av datasett, industrien, virksomheten og så videre. Det er imidlertid en tommelfingerregel for å velge riktig antall klynger:
med lik antall observasjoner i datasettet.
Generelt sett er det interessant å bruke tid på å søke etter den beste verdien for å passe med forretningsbehovet.
Vi vil bruke datasettet Priser på personlige datamaskiner for å utføre klyngeanalysen vår. Dette datasettet inneholder 6259 observasjoner og 10 funksjoner. Datasettet observerer prisen fra 1993 til 1995 på 486 personlige datamaskiner i USA. Variablene er blant annet pris, hastighet, ram, skjerm, cd.
Du vil fortsette som følger:
- Import datoer
- Tren modellen
- Evaluer modellen
Import datoer
K betyr ikke er egnet for faktorvariabler fordi det er basert på avstanden og diskrete verdier ikke returnerer meningsfulle verdier. Du kan slette de tre kategoriske variablene i datasettet vårt. Dessuten mangler det ingen verdier i dette datasettet.
library(dplyr) PATH <-"https://raw.githubusercontent.com/guru99-edu/R-Programming/master/computers.csv" df <- read.csv(PATH) %>% select(-c(X, cd, multi, premium)) glimpse(df)
Produksjon
## Observations: 6, 259 ## Variables: 7 ## $ price < int > 1499, 1795, 1595, 1849, 3295, 3695, 1720, 1995, 2225, 2... ##$ speed < int > 25, 33, 25, 25, 33, 66, 25, 50, 50, 50, 33, 66, 50, 25, ... ##$ hd < int > 80, 85, 170, 170, 340, 340, 170, 85, 210, 210, 170, 210... ##$ ram < int > 4, 2, 4, 8, 16, 16, 4, 2, 8, 4, 8, 8, 4, 8, 8, 4, 2, 4, ... ##$ screen < int > 14, 14, 15, 14, 14, 14, 14, 14, 14, 15, 15, 14, 14, 14, ... ##$ ads < int > 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, ... ## $ trend <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1...
Fra oppsummeringsstatistikken kan du se at dataene har store verdier. En god praksis med k gjennomsnitt og avstandsberegning er å omskalere dataene slik at gjennomsnittet er lik én og standardavviket er lik null.
summary(df)
Utgang:
## price speed hd ram ## Min. : 949 Min. : 25.00 Min. : 80.0 Min. : 2.000 ## 1st Qu.:1794 1st Qu.: 33.00 1st Qu.: 214.0 1st Qu.: 4.000 ` ## Median :2144 Median : 50.00 Median : 340.0 Median : 8.000 ## Mean :2220 Mean : 52.01 Mean : 416.6 Mean : 8.287 ## 3rd Qu.:2595 3rd Qu.: 66.00 3rd Qu.: 528.0 3rd Qu.: 8.000 ## Max. :5399 Max. :100.00 Max. :2100.0 Max. :32.000 ## screen ads trend ## Min. :14.00 Min. : 39.0 Min. : 1.00 ## 1st Qu.:14.00 1st Qu.:162.5 1st Qu.:10.00 ## Median :14.00 Median :246.0 Median :16.00 ## Mean :14.61 Mean :221.3 Mean :15.93 ## 3rd Qu.:15.00 3rd Qu.:275.0 3rd Qu.:21.50 ## Max. :17.00 Max. :339.0 Max. :35.00
Du skalerer variablene på nytt med scale()-funksjonen til dplyr-biblioteket. Transformasjonen reduserer effekten av uteliggere og gjør det mulig å sammenligne en eneste observasjon med gjennomsnittet. Hvis en standardisert verdi (eller z-poengsum) er høy, kan du være sikker på at denne observasjonen faktisk er over gjennomsnittet (en stor z-score betyr at dette punktet er langt unna gjennomsnittet når det gjelder standardavvik. En z-score på to indikerer at verdien er 2 standard avvik fra gjennomsnittet. Merk at z-skåren følger en gaussisk fordeling og er symmetrisk rundt gjennomsnittet.
rescale_df <- df % > % mutate(price_scal = scale(price), hd_scal = scale(hd), ram_scal = scale(ram), screen_scal = scale(screen), ads_scal = scale(ads), trend_scal = scale(trend)) % > % select(-c(price, speed, hd, ram, screen, ads, trend))
R-basen har en funksjon for å kjøre k-middelalgoritmen. Den grunnleggende funksjonen til k gjennomsnitt er:
kmeans(df, k) arguments: -df: dataset used to run the algorithm -k: Number of clusters
Tren modellen
I figur tre beskrev du hvordan algoritmen fungerer. Du kan se hvert trinn grafisk med den flotte pakken bygget av Yi Hui (også skaperen av Knit for Rmarkdown). Pakkeanimasjonen er ikke tilgjengelig i conda-biblioteket. Du kan bruke den andre måten å installere pakken med install.packages(“animasjon”). Du kan sjekke om pakken er installert i vår Anaconda-mappe.
install.packages("animation")
Etter at du har lastet inn biblioteket, legger du til .ani etter kmeans og R vil plotte alle trinnene. For illustrasjonsformål kjører du bare algoritmen med de reskalerte variablene hd og ram med tre klynger.
set.seed(2345) library(animation) kmeans.ani(rescale_df[2:3], 3)
Kode Forklaring
- kmeans.ani(rescale_df[2:3], 3): Velg kolonne 2 og 3 i rescale_df datasett og kjør algoritmen med k sett til 3. Plott animasjonen.
Du kan tolke animasjonen som følger:
- Trinn 1: R velger tilfeldig tre poeng
- Trinn 2: Beregn den euklidiske avstanden og tegn klyngene. Du har en klynge i grønt nederst til venstre, en stor klynge farget i svart til høyre og en rød mellom dem.
- Trinn 3: Beregn tyngdepunktet, dvs. gjennomsnittet av klyngene
- Gjenta til ingen data endrer klynge
Algoritmen konvergerte etter syv iterasjoner. Du kan kjøre k-mean-algoritmen i datasettet vårt med fem klynger og kalle det pc_cluster.
pc_cluster <-kmeans(rescale_df, 5)
- Listen pc_cluster inneholder syv interessante elementer:
- pc_cluster$cluster: Indikerer klyngen for hver observasjon
- pc_cluster$centers: Klyngen sentre
- pc_cluster$totss: Den totale summen av kvadrater
- pc_cluster$withinss: Innenfor summen av kvadratet. Antallet komponenter returnerer er lik "k".
- pc_cluster$tot.withinss: Summen av insidess
- pc_clusterbetweenss: Total sum av kvadrat minus Innen sum av kvadrat
- pc_cluster$size: Antall observasjoner innenfor hver klynge
Du vil bruke summen av den indre summen av kvadratet (dvs. tot.withinss) for å beregne det optimale antallet klynger k. Å finne k er virkelig en betydelig oppgave.
Optimal k
En teknikk for å velge den beste k kalles albuemetoden. Denne metoden bruker homogenitet innen gruppe eller heterogenitet innen gruppe for å evaluere variabiliteten. Du er med andre ord interessert i prosentandelen av variansen som forklares av hver klynge. Du kan forvente at variabiliteten øker med antall klynger, alternativt avtar heterogeniteten. Utfordringen vår er å finne k-en som er hinsides den avtagende avkastningen. Å legge til en ny klynge forbedrer ikke variasjonen i dataene fordi det er svært lite informasjon igjen å forklare.
I denne opplæringen finner vi dette punktet ved å bruke heterogenitetsmålet. Summen av kvadrater innenfor klynger er tot.withinss i listen returnerer med kmean().
Du kan konstruere albuegrafen og finne den optimale k som følger:
- Trinn 1: Konstruer en funksjon for å beregne totalsummen av kvadrater innenfor klynger
- Trinn 2: Kjør algoritmetidene
- Trinn 3: Lag en dataramme med resultatene av algoritmen
- Trinn 4: Plott resultatene
Trinn 1) Konstruer en funksjon for å beregne totalsummen av kvadrater innenfor klynger
Du oppretter funksjonen som kjører k-middelalgoritmen og lagrer totalsummen innenfor klynger summen av kvadrater
kmean_withinss <- function(k) { cluster <- kmeans(rescale_df, k) return (cluster$tot.withinss) }
Kode Forklaring
- funksjon(k): Angi antall argumenter i funksjonen
- kmeans(rescale_df, k): Kjør algoritmen k ganger
- return(cluster$tot.withinss): Lagre totalsummen i klynger summen av kvadrater
Du kan teste funksjonen med lik 2.
Utgang:
## Try with 2 cluster
kmean_withinss(2)
Utgang:
## [1] 27087.07
Trinn 2) Kjør algoritmen n ganger
Du vil bruke sapply()-funksjonen til å kjøre algoritmen over et område på k. Denne teknikken er raskere enn å lage en løkke og lagre verdien.
# Set maximum cluster max_k <-20 # Run algorithm over a range of k wss <- sapply(2:max_k, kmean_withinss)
Kode Forklaring
- max_k <-20: Sett et maksimalt antall til 20
- sapply(2:max_k, kmean_withinss): Kjør funksjonen kmean_withinss() over et område 2:max_k, dvs. 2 til 20.
Trinn 3) Lag en dataramme med resultatene av algoritmen
Etter opprettelse og testing av funksjonen vår kan du kjøre k-middelalgoritmen over et område fra 2 til 20, lagre tot.withinss-verdiene.
# Create a data frame to plot the graph elbow <-data.frame(2:max_k, wss)
Kode Forklaring
- data.frame(2:max_k, wss): Lag en dataramme med utdata fra algoritmelageret i wss
Trinn 4) Plott resultatene
Du plotter grafen for å visualisere hvor albuepunktet er
# Plot the graph with gglop ggplot(elbow, aes(x = X2.max_k, y = wss)) + geom_point() + geom_line() + scale_x_continuous(breaks = seq(1, 20, by = 1))
Fra grafen kan du se den optimale k er syv, hvor kurven begynner å ha en avtagende avkastning.
Når du har vår optimale k, kjører du algoritmen på nytt med k er lik 7 og evaluerer klyngene.
Undersøker klyngen
pc_cluster_2 <-kmeans(rescale_df, 7)
Som nevnt før, kan du få tilgang til den gjenværende interessante informasjonen i listen returnert av kmean().
pc_cluster_2$cluster pc_cluster_2$centers pc_cluster_2$size
Evalueringsdelen er subjektiv og er avhengig av bruken av algoritmen. Målet vårt her er å samle datamaskiner med lignende funksjoner. En datamann kan gjøre jobben for hånd og gruppedatamaskin basert på sin ekspertise. Imidlertid vil prosessen ta mye tid og vil være utsatt for feil. K-mean-algoritmen kan forberede feltet for ham/henne ved å foreslå klynger.
Som en forhåndsevaluering kan du undersøke størrelsen på klyngene.
pc_cluster_2$size
Utgang:
## [1] 608 1596 1231 580 1003 699 542
Den første klyngen er sammensatt av 608 observasjoner, mens den minste klyngen, nummer 4, bare har 580 datamaskiner. Det kan være greit å ha homogenitet mellom klynger, hvis ikke, kan det være nødvendig med en tynnere dataforberedelse.
Du får en dypere titt på dataene med senterkomponenten. Radene refererer til nummereringen av klyngen og kolonnene variablene som brukes av algoritmen. Verdiene er den gjennomsnittlige poengsummen for hver klynge for den interesserte kolonnen. Standardisering gjør tolkningen enklere. Positive verdier indikerer at z-skåren for en gitt klynge er over det totale gjennomsnittet. For eksempel har klynge 2 det høyeste prisgjennomsnittet blant alle klyngene.
center <-pc_cluster_2$centers center
Utgang:
## price_scal hd_scal ram_scal screen_scal ads_scal trend_scal ## 1 -0.6372457 -0.7097995 -0.691520682 -0.4401632 0.6780366 -0.3379751 ## 2 -0.1323863 0.6299541 0.004786730 2.6419582 -0.8894946 1.2673184 ## 3 0.8745816 0.2574164 0.513105797 -0.2003237 0.6734261 -0.3300536 ## 4 1.0912296 -0.2401936 0.006526723 2.6419582 0.4704301 -0.4132057 ## 5 -0.8155183 0.2814882 -0.307621003 -0.3205176 -0.9052979 1.2177279 ## 6 0.8830191 2.1019454 2.168706085 0.4492922 -0.9035248 1.2069855 ## 7 0.2215678 -0.7132577 -0.318050275 -0.3878782 -1.3206229 -1.5490909
Du kan lage et varmekart med ggplot for å hjelpe oss med å fremheve forskjellen mellom kategorier.
Standardfargene til ggplot må endres med RColorBrewer-biblioteket. Du kan bruke conda bibliotek og koden som skal startes i terminalen:
conda installer -cr r-rcolorbrewer
For å lage et varmekart går du frem i tre trinn:
- Bygg en dataramme med verdiene til senteret og lag en variabel med nummeret til klyngen
- Omform dataene med gather()-funksjonen til tidyr-biblioteket. Du vil transformere data fra brede til lange.
- Lag fargepaletten med fargerRampPalett() funksjon
Trinn 1) Bygg en dataramme
La oss lage omformingsdatasettet
library(tidyr) # create dataset with the cluster number cluster <- c(1: 7) center_df <- data.frame(cluster, center) # Reshape the data center_reshape <- gather(center_df, features, values, price_scal: trend_scal) head(center_reshape)
Utgang:
## cluster features values ## 1 1 price_scal -0.6372457 ## 2 2 price_scal -0.1323863 ## 3 3 price_scal 0.8745816 ## 4 4 price_scal 1.0912296 ## 5 5 price_scal -0.8155183 ## 6 6 price_scal 0.8830191
Trinn 2) Omform dataene
Koden nedenfor lager paletten med farger du skal bruke til å plotte varmekartet.
library(RColorBrewer) # Create the palette hm.palette <-colorRampPalette(rev(brewer.pal(10, 'RdYlGn')),space='Lab')
Trinn 3) Visualiser
Du kan plotte grafen og se hvordan klyngene ser ut.
# Plot the heat map ggplot(data = center_reshape, aes(x = features, y = cluster, fill = values)) + scale_y_continuous(breaks = seq(1, 7, by = 1)) + geom_tile() + coord_equal() + scale_fill_gradientn(colours = hm.palette(90)) + theme_classic()
Oppsummering
Vi kan oppsummere k-middelalgoritmen i tabellen nedenfor
Pakke | Målet | Funksjon | Argument |
---|---|---|---|
basen | Tog k-middel | kmeans () | df, k |
Tilgangsklynge | kmeans()$cluster | ||
Cluster sentre | kmeans()$sentre | ||
Størrelse klynge | kmeans()$størrelse |