21. Klyngeanalyse
Klyngeanalyse eller klusteranalyse er en statistisk teknik brugt til at gruppere en samling af observationer i
undergrupper kaldet klynger, således at observationerne inden for hver klynge har lignende karakteristika eller
egenskaber, mens de er forskellige fra observationer i andre klynger.
I klyngeanalyse grupperer man observationerne, mens faktoranalyse grupperer variablene. Både klynge- og
faktoranalyse kaldes strukturanalyser. Disse minder en del om hinanden. I klyngeanalysen er der ikke regler for hvor
mange klynger man bør danne, her dannes klynger der giver mening, således at der er bestemte karakteristika for
klyngerne.
Klyngeanalyse bruges bredt inden for mange felter som marketing, biologi, medicin, psykologi, økonomi og mere, til
opgaver som markedssegmentering, genetisk forskning, mønstergenkendelse og datareduktion.
I modsætning til klassificeringsopgaver, hvor grupper er defineret på forhånd, opdager klyngeanalysen grupperinger i
data uden foruddefinerede etiketter.
Herunder er eksempler på i hvilke områder klyngeanalyse finder anvendelse i forskellige sektorer, bemærk der er angivet eksempler på 2 klynger, analysen kan sagtens indeholde flere klynger.
| Sektor | Eksempel |
|---|---|
| Retail |
En stor detailkæde kunne anvende klyngeanalyse til at identificere forskellige kundesegmenter baseret på
købsadfærd og demografiske data. Mulige klynger kunne være: Klynge 1: Værdibevidste kunder Karakteristika for klyngen: • Søger primært tilbud og rabatter • Køber store mængder under salg Klynge 2: Premium kunder Karakteristika for klyngen: • Foretrækker højkvalitetsprodukter • Mindre prissensitive |
| Bank |
Banker kan bruge klyngeanalyse baseret på kundedata til at segmentere kunder baseret på finansielle adfærd og
behov. Mulige klynger kunne være: Klynge 1: Aktive investorer Karakteristika for klyngen: • Høj aktivitet i investeringsporteføljer • Interesseret i forskellige investeringsmuligheder Klynge 2: Opsparingsorienterede kunder Karakteristika for klyngen: • Fokus på opsparingskonti og fastindtægtsprodukter • Risikoaverse i forhold til investeringer |
| Forsikring |
Forsikringsselskaber kan anvende klyngeanalyse baseret på kundedata til at segmentere kunder og forstå
risikoprofiler. Mulige klynger kunne være: Klynge 1: Højrisikokunder Karakteristika for klyngen: • Hyppige kravshistorikker • Engageret i risikofyldte aktiviteter Klynge 2: Lavrisikokunder Karakteristika for klyngen: • Sjældne forsikringskrav • Forsigtige og sikkerhedsorienterede adfærdsmønstre |
| Ejendomsadministration |
Ejendomsadministratorer kan bruge klyngeanalyse baseret på kundedata til at forstå forskellige lejertyper og
optimere
ledelsestjenester. Mulige klynger kunne være: Klynge 1: Langtidslejere Karakteristika for klyngen: • Søger stabilitet og langvarige lejemål • Foretrækker boliger med god adgang til offentlig transport og skoler Klynge 2: Korttidslejere Karakteristika for klyngen: • Ofte studerende eller midlertidige arbejdstagere • Leder efter fleksible lejevilkår og møblerede boliger |
| Telekommunikation |
Et telekommunikationsselskab kunne anvende klyngeanalyse til at segmentere kunder baseret på brugsmønstre og
præferencer. Mulige klynger kunne være: Klynge 1: Data-tunge brugere Karakteristika for klyngen: • Høj dataforbrug • Foretrækker ubegrænsede dataplaner Klynge 2: Grundlæggende brugere Karakteristika for klyngen: • Lavt dataforbrug • Foretrækker billigere planer med basale funktioner |
| Transport |
Et transportselskab kunne anvende klyngeanalyse til at forstå forskellige brugermønstre og forbedre
ruteplanlægning. Mulige klynger kunne være: Klynge 1: Pendlere Karakteristika for klyngen: • Daglige ture i spidsbelastningstider • Foretrækker direkte ruter til arbejdspladser Klynge 2: Lejlighedsrejsende Karakteristika for klyngen: • Uregelmæssige rejsetider • Tiltrækkes af fritidsrelaterede destinationer |
| Underholdning |
En streamingtjeneste kunne bruge klyngeanalyse til at identificere forskellige seerpræferencer for at
personalisere
anbefalinger. Mulige klynger kunne være: Klynge 1: Filmelskere Karakteristika for klyngen: • Høj præference for nyere filmudgivelser • Interesseret i filmfestivaler og priser Klynge 2: Serieentusiaster Karakteristika for klyngen: • Foretrækker lange TV-serier • Engagerer sig ofte i serie-maraton |
Tabel 21.1: Eksempler på, hvordan klyngeanalyse kan anvendes til kundesegmentering i syv forskellige sektorer — retail, bank, forsikring, ejendomsadministration, telekommunikation, transport og underholdning — med hver to illustrative klynger og deres karakteristika.
Kilde: Egen tilvirkning.
Klyngeanalyse er ofte et første, uovervåget skridt i en større ML-pipeline; fx kan man opdage
kundesegmenter forud for svindeldetektion eller gruppere porteføljer efter risikoprofil, inden mere
avancerede modeller, som Random ForestRandom Forest kombinerer mange beslutningstræer til én model. Hvert træ ser på et tilfældigt udsnit af data,
og flertallet af træernes svar bliver det endelige resultat — derfor "skov".
Leo Breiman introducerede metoden i 2001; den er i dag en af de mest populære inden for maskinlæring. Han startede som
fysiker og arbejdede med kernevåben, før han skiftede til statistik.
Klik her for at
læse mere om Random Forest i kapitel 1!, trænes på de fundne grupper.
Eksempel Bilmodeller
Vi har et datasæt bestående af 32 bilmodeller med følgende 11 variable:
| mtcars datasættet | |
|---|---|
| Variabel | Forklaring på de 11 variable |
| mpg |
Miles per gallon. Dette er en måling af brændstoføkonomi og angiver, hvor mange miles en bil kan
køre per gallon benzin.
1 mile er lig med ca. 1,6 kilometer. 1 US gallon er lig med ca. 3,8 liter. Man kan omregne mpg til km/l ved at gange med ca. 0,42. |
| cyl | Antal cylindre i bilens motor. Typiske værdier er 4, 6, eller 8 cylindre. |
| disp | Motorvolumen (displacement) i kubik tommer. Dette er et mål for motorstørrelsen. Kubik-tommer kan omregnes til kubik-centimeter ved at gange med ca. 16. |
| hp | Hestekræfter. Dette er en måling af bilens motorkraft. |
| drat | Bagakseludveksling (differential ratio). Dette tal angiver forholdet mellem antallet af tænder på ringgearet til antallet af tænder på drivgearet i bilens differential. |
| wt | Vægt (1000 lbs). Dette er bilens vægt målt i tusinder af pund. Vægt i 1000 pund kan omregnes til tons ved at gange med ca. 0,45. |
| qsec | 1/4 mile tid. Tiden det tager for bilen at køre en fjerdedels mile (cirka 0,4 kilometer) fra stillestående start, lavere værdi betyder hurtigere acceleration. qsec kan ikke direkte omsættes til 0-100 km/t tider. |
| vs | Motorform. Dummy-variabel med niveauerne 0 (V-formet motor) og 1 (lige motor). |
| am | Gearkassetype. Dummy-variabel med niveauerne 0 (automatisk gearkasse) og 1 (manuel gearkasse). |
| gear | Antal fremadgående gear i bilens gearkasse. |
| carb | Antal karburatorer. Dette tal angiver antallet af karburatorer i bilens motor. |
Tabel 21.2: Variabeloversigt for mtcars-datasættet — 11 tekniske og ydeevnerelaterede mål (brændstoføkonomi, cylindre, motorvolumen, hestekræfter m.m.) for 32 bilmodeller, som skal grupperes i klynger ud fra deres specifikationer.
Kilde: Motor Trend US (1974), indbygget R-datasæt "mtcars".
Vi vil gerne gruppere de forskellige bilmodeller i forskellige grupper eller klynger ud fra deres specifikationer. For at undersøge, om vi på baggrund af tekniske karakteristika, kan gruppere bilmodellerne, benytter vi klyngeanalyse. Bemærk i faktoranalysen grupperer vi variablene, i klyngeanalysen grupperer vi respondenterne eller observationerne, her altså bilerne.
Der findes overordnet 2 typer af klyngeudvælgelse:
Ikke-hierarkisk, k-means metoden benyttes ofte, hvis vi har store datasæt hvor der kræves mange beregninger, man vælger på forhånd hvor mange klynger man vil have.
Hierarkisk klyngedannelse, agglomerative metode
hvor man starter med at hver respondent har sin egen klynge og man derefter
sammenhober disse trin for trin kaldes den sammenhobede eller agglomerative
metode.
Vi benytter både den agglomerative metode og k-means på bildatasættet mtcars, for at se hvordan begge
metoder
fungerer.
Det kan være en fordel at få overblik vha. et klyngetræ vha. den agglomerative metode og derefter
benytte k-means med et specifikt antal klynger i den videre analyse.
#Vi gemmer datasættet mtcars i variablen data
data <- mtcars
#Vi kan se starten af datasættet med head kommandoen
head(data)
Vi kan se at når vi sammenligner forskellige variable ser det ud til at der er forskellige grupper. Nedenfor ser vi fx de 32 biler plottet i et diagram efter hestekræfter og miles per gallon. Bilerne er farvekodet med antal cylindre.
#Her angiver vi modelnavne for hver bil
#med label rownames vi bruger geom_text i stedet for point her.
pacman::p_load("ggplot2")
ggplot(data, aes(hp, mpg, color = cyl)) +
geom_point() #Plot med kun punkter
ggplot(data, aes(hp, mpg, color = cyl,label=rownames(data)))+
geom_text(size=3,check_overlap = TRUE)
Vi kan benytte t til at transponere data matricen, så kan vi tegne et
corrplot, det er meget mørkt da alle bilerne er positivt korrelerede, men
man kan ane nogle sammenhænge. t(data) betyder vi transponerer (vender)
matricen, så ser vi i stedet på grupper af respondenter, som vi netop
analyserer i klyngeanalysen. Hvis ikke vi vender matricen ser vi på
korrelationsmatricenKorrelationen angiver hvor meget 2 variable samvarierer, vi kan måle
korrelationen vha. korrelationskoefficienten der er et tal mellem -1 og
1.
Korrelationskoefficienten er klart positiv hvis høje og lave værdier for
den ene variabel følges med høje og lave værdier for den anden
variabel.
Korrelationskoefficienten er klart negativ hvis høje og lave værdier for
den ene variabel følges med lave og høje værdier for den anden
variabel.
Er der ingen samvariation mellem 2 variable er korrelationskoefficienten
tæt på 0.
Korrelationskoefficienten i en kiosk mellem afsætning af is og
temperaturen vil være positiv, jo koldere/varmere det er jo
mindre/større afsætning af is.
Korrelationskoefficienten i en kiosk mellem afsætning af varm kakao og
temperaturen vil være negativ, jo koldere/varmere det er jo
større/mindre afsætning af kakao.
For to variable som ikke er korrelerede (de samvarierer ikke) som fx.
Apple aktie kursen og nedbørsmængden i Dragør, vil vi få en
korrelationskoefficient tæt på 0.
Klik her for at lære
mere om korrelationsanalyse! mellem de 11 variable i stedet, ligesom vi tidligere
har gjort med faktoranalysen.
#korrelationsmatricen for transponeret data, hclust betyder vi
#ordner efter variable der passer sammen
pacman::p_load(corrplot)
corrplot(cor(t(data)), order = "hclust", tl.col='black', tl.cex=.5)
#Her er korrelationsmatricen ikke transponeret, hvilket svarer til en
#matrice baseret på variable som ved faktoranalysen vi tidligere så på.
corrplot(cor(data), order = "hclust", tl.col='black', tl.cex=.5)
Hierarkisk klyngeanalyse hclust-kommandoen
Vi får nu R til at danne klynger vha. hclust-kommandoen (hierarchical cluster). Denne benytter som standard en metode der hedder complete til at finde ens klynger, der findes mange andre metoder. For at benytte hclust skal R først beregne afstandene mellem bilerne, dette gøres med dist-kommandoen. Algoritmen beregner afstandene mellem de forskellige bilmodeller vha. den euklidiske metrik. Biler med kort afstand kommer i klynger sammen, biler med lang afstand kommer i forskellige klynger.
Nedenfor ses et udsnit af afstandene mellem hver af de 32 biler, det er en meget stor 32 × 32 matrice, derfor har vi benyttet head for kun at vise noget af matricen. Fx er afstanden mellem to forskellige biler som en Mazda RX4 og en Lincoln Continental 318,05 hvilket er en stor afstand i forhold til fx. Mazda RX4 og Mazda RX4 Wag på kun 0,62. Bemærk hvordan supersportsvognen Maserati Bora har store afstande til de fleste af de øvrige biler, Maseratien var en komfortabel, rummeligere og kraftigere og tungere sportsvogn end fx. Ferrari Dino.
head(as.matrix(dist(data)))
Vi gemmer hclust data i clusters variablen, vi så kan benytte til at tegne en oversigt over klyngerne. Vi kan nu plotte en grafisk oversigt over bilerne. I nederste linje er den fineste inddeling, hvor samtlige biler er i deres egen klynge. Den blå linje med 3 skæringer i dendogrammet indikerer der er 3 klynger, den røde 4 klynger.
clusters <- hclust(dist(data))
plot(clusters,cex=0.5,main = "Dendogram af mtcars",xlab = "Klyngetræ",sub="Bilmodeller")
abline(h = 190, col="red") #Tegn rød vandret linje h betyder horisontal
abline(h = 230, col="blue")
Hvis vi ønsker at undersøge en inddeling med et bestemt antal klynger, kan vi bruge cutree i R, til at undersøge klyngerne i en skæring med fx. 4 klynger nærmere. Her ser vi som nævnt, Maserati Bora skiller sig ud ved at have sin egen klynge. Nummeret ved hver af de 32 biler angiver hvilken klynge bilen tilhører.
clusterCut <- cutree(clusters, 4) #Opdeling i 4 klynger.
clusterCut
Vi kan benytte subset-kommandoen til at se på hvilke variable der er i hver klynge, herunder ser vi på klynge 3.
subset(clusterCut,clusterCut==3)
Vi kan ligeledes sammenligne klyngeinddelingen med de enkelte variable, og undersøge om der synes at være nogle mønstre.
table(clusterCut, data$cyl)

table(clusterCut, data$mpg)
Bemærk herunder mpg i klynge 1 har alle de bilerne med god benzinøkonomi der kører langt på literen, dvs.
der
er høje tal for mpg.
Klynge 3 og 4 har alle bilerne med dårlig benzinøkonomi, der har et lavt tal for mpg.
Bemærk herunder hp i klynge 1 har alle de bilerne med få hestekræfter.
Klynge 3 og 4 har alle bilerne med mange hestekræfter.
table(clusterCut, data$hp)
Herunder ses carb antal karburatorer i denne tabel er mønsteret ikke så entydigt tydeligt.
table(clusterCut, data$carb)
Bemærk herunder wt i klynge 1 har alle de bilerne med lav vægt. I klynge 3 og 4 er bilerne tungere.
table(clusterCut, data$wt)
Hvis dendogrammet virker lidt uoverskueligt, kan man vælge ape-pakken for at lave mere fancy plots, her er rigtig mange muligheder. Herunder er klyngerne også farvekodede, lyserød er fx klynge 4 med kun 1 Maserati, rød er klyngen med de benzinøkonomiske biler.
#install.packages("ape")
library("ape")
colors = c("red", "blue", "green", "pink")
clus4 = cutree(clusters, 4)
plot(as.phylo(clusters), type = "fan", tip.color = colors[clus4], label.offset = 0, cex = 0.5)
Herunder er et plot, hvor farvekoden er baseret på klyngerne. Rød er klynge 1 og blå er klynge 4 med kun Maserati.
ggplot(data, aes(hp, mpg)) +
geom_point(alpha = 0.4, size = 3.5)
+ geom_point(col = clusterCut)
Ikke-hierarkisk klyngeanalyse kmeans-kommandoen
Vi kunne også have brugt kmeans-metoden, her skal vi så angive hvor mange klynger, vi ønsker i analysen. Her benytter vi K-means og får 4 klynger med 7, 6, 9, 10 biler.
Herunder ses det kommenterede output af kmeans-kommandoen i R.
mtcarsCluster4 <- kmeans(data, 4)
mtcarsCluster4
Cluster means: For hver klynge vises den gennemsnitlige værdi af hver variabel. I søjle 2 der hedder
cyl er
der i
klynge 3 et gennemsnitligt antal cylindre på 4. Dette skyldes at alle de 10 biler i denne klynge har 4
cylindre.
Bemærk antallet
i klyngerne og nummeret på klyngerne, er ikke nødvendigvis det samme som ved hclust-metoden, der er tale om
2
forskellige algoritmer. I K-means klyngeanalysen har de økonomiske biler klynge nummer 3 og indeholder 10
biler, i
hclust vi så
tidligere var de økonomiske biler i klynge 1 og her var 16 biler (heraf 11 med 4 cylindre).
Kører du analyserne vil du opleve mindre
afvigelser, hver gang du
kører analysen på ny, det skyldes algoritmen udvikler sig forskelligt hver gang, men essensen er den samme.
Clustering vector: En vektor af klyngetildelinger for hver observation. Dette viser, hvilken klynge
hver
observation er blevet tildelt.
Within cluster sum of squares by cluster: Måler den samlede varians inden for hver klynge; lavere
værdier
indikerer, at observationerne ligger tættere på klyngens centrumspunkt, hvilket generelt anses for
bedre.
between_SS Dette er den samlede varians mellem klyngerne. Dette mål hjælper med at forstå, hvor
adskilte de forskellige klynger er.
total_SS Den samlede varians i datasættet.
between_SS / total_SS Angiver hvor meget af den samlede variation klyngerne forklarer, dette er et
tal mellem
0% og 100%
Available components: Man kan særskilt hente enkeltelementer fra analysen fx elementer som "totss",
"withinss", "tot.withinss",...
Man angiver variablen med klyngeanalysen og $ efterfulgt af elementet. Fx giver kommandoen:
mtcarsCluster4$iter
Her ses hvor mange iterationer algoritmen har gennemført (her 2 iterationer) for at nå til netop denne
klyngedeling.Bemærk hclust- og kmeans-kommandoerne gennemfører en algoritme og kommer ofte med forskellige opdelinger af klyngerne, derfor får du sandsynligvis ikke præcis samme tal, når du kører analysen i R.
Nedenfor ser vi på en tabel inddeling med 4 klynger med de 32 biler, sorteret efter antallet af cylindre. Rækker er klynger og søjler er cylindre. Bemærk klynge 3 der indeholder 10 biler, har kun biler med 4 cylindre, det var netop klyngen med bedst benzinøkonomi. Læg mærke til at klyngegennemsnittet for klynge 3 for variablen cylindre er netop 4 (se figuren med klyngeoutput og kommentarer herover), dette skyldes jo at samtlige biler i klyngen har 4 cylindre.
table(mtcarsCluster4$cluster, data$cyl)
Nedenfor ser vi på en tabel inddeling med kun 3 klynger med de 32 biler, sorteret efter antallet af cylindre. Her er klynge 1 nu klyngen med økonomiske biler. gennemfører vi kmeans analysen igen, falder bilerne ikke nødvendigvis i samme klynger som tidligere, det skyldes algoritmen kan give forskellig optimale inddelinger.
mtcarsCluster3 <- kmeans(data, 3)
table(mtcarsCluster3$cluster, data$cyl)
Vi kan lave et klyngeplot der viser forskellene på de 32 biler, herunder ses
plottet med 3 klynger. Bemærk vi skal hente pakken factoextra, der indeholder plotfunktionen
fviz_cluster(). Vi har benyttet
funktionen
scale(), det er en rigtig god idé at benytte, hvis der er stor forskel på
måleenhederne i en data.frame. Funktionen
scale() bringer variablene i samme skala.
Klyngeplottet giver et godt grafisk overblik over klyngerne, skalaerne på x- og y-aksen skal man
ikke hæfte sig nærmere ved. Disse er en dimensionsreduceret repræsentation af de oprindelige variable.
km3.res <- kmeans(scale(data), 3, nstart = 25)
pacman::p_load(factoextra)
fviz_cluster(km3.res, data = data, main = "Klyngeplot biler opdelt i 3 klynger",repel = TRUE)
Herunder beder vi kun om middelværdierne for hver af de 3 klyngerne for hver af de 11 variable, vi
har
fundet ovenfor ved
kommandoen km3.res <- kmeans(scale(data), 3, nstart = 25).
Husk man behøver ikke hente alt output med km3, men kan hente delelementer ved at benytte $.
Læg mærke til, at middelværdierne er standardiserede, i forhold til før hvor vi ikke standardiserede, da vi
brugte
kommandoen kmeans(data, 4). Standardisering sikrer en uniform vægtning af de enkelte variable.
km3.res$centers
Bemærk høje værdier markeret med grønne rammer, og lave værdier markeret med røde rammer, for de standardiserede middelværdier, stemmer med karakteristika for de 3 klynger af biler, i klyngeplottet.
Klyngeplot der viser forskellene på de 32 biler, herunder ses plottet med 5 klynger.
km5.res <- kmeans(scale(data), 5, nstart = 25)
fviz_cluster(km5.res, data = data, main = "Klyngeplot biler opdelt i 5 klynger",repel = TRUE)
Bemærk hvis skriften fylder meget, så mange labels ikke kommer med, kan man ændre skriftstørrelsen med argumentet labelsize = 6 i fviz_cluster-kommandoen som fx. herunder:
km5.res <- kmeans(scale(data), 5, nstart = 25)
fviz_cluster(km5.res, labelsize = 6, data = data, main = "Klyngeplot biler opdelt i 5 klynger",repel = TRUE)
Validering med ANOVA
Skal man undersøge om grupperne/klyngerne er forskellige med hensyn til de
forskellige variable, kan man benytte ANOVA
ANOVA testet benyttes til test af gennemsnit for flere end 2 kvantitative
variable, populationerne skal have samme varians.
Eksempler på stikprøver, hvor middelværdierne kan testes vha. ANOVA
testet kunne være:
For 4 stikprøver med højder for CBS, KU, CPH Business og SDU studerende,
kan man teste om middelhøjden er ens med ANOVA testet.
For 6 stikprøver med med salgspriser for ejendomme i 6 byer, kan man
teste om middelværdierne er ens med ANOVA testet.
ANOVA testet er en udvidelse af pooled t-test, hypoteserne kan generisk
skrives som:
H0: Alle middelværdier er ens
H1: Ikke alle middelværdier er ens
Klik her for at
lære mere om ANOVA!
, hvor klyngerne er den
uafhængige variabel. Man skal da gerne nå frem til at klyngegennemsnittene
er signifikant forskellige mht. flere af variablene, der indgår i analysen.
Quiz
Spørgsmål
Vi vil her gennemføre en klyngeanalyse af datasættet om Verdensøkonomien.
Bemærk Rusland og Ukraine er desværre ikke medtaget i datasættet, da det er svært at indhente
pålidelige
data pga.
krigen. En del andre interessante lande som f.eks. Argentina og Nord Korea er ligeledes ikke med i
analysen,
dette skyldes
igen manglende eller ubekræftede data.
Plots er ikke lagt direkte i besvarelsen da disse er meget grafiktunge for at få alle detaljer med,
men klik
på links for at se disse.
Datasættet består af 139 lande, målt på 6 variable:
Variable
- Land
- BNP USD
- BNP pr indbygger USD
- Befolkning
- BNP Vækst fra året før %
- Inflation %
- Arbejdsløshed %
Dette kan vi ordne med koden herunder:
# Klyngeanalyse med Verdensøkonomien
# Vi sætter nu alt output til normale tal, dvs. ikke-scientific notation
options(scipen = 999)
# Vi importerer Excel datasættet Verdensøkonomien_2023.xlsx, man kan også importere ved peg og klik metoden
library(readxl)
Verdensøkonomien_2023 <- read_excel("...ANGIV STI TIL FILEN HER.../Verdensøkonomien_2023.xlsx")
View(Verdensøkonomien_2023)
# Vi gemmer Verdensøkonomien_2023.xlsx i variablen data
data <- Verdensøkonomien_2023
# Vi vil gerne gemme landenavnene i første søjle som rækkenavne, før vi kan sætte row.names sættes data som en data.frame
data <- as.data.frame(data)
row_names <- data[,1]
row.names(data) <- row_names
# Vi fjerner nu 1. søjle da denne er gemt som rækkenavne
data <- data[,-1]
Vi startede med koden fra spørgsmålet for at klargøre data:
# Klyngeanalyse med Verdensøkonomien
# Vi sætter nu alt output til normale tal, dvs. ikke-scientific notation
options(scipen = 999)
# Vi importerer Excel datasættet Verdensøkonomien_2023.xlsx, man kan også importere ved peg og klik metoden
library(readxl)
Verdensøkonomien_2023 <- read_excel("...ANGIV STI TIL FILEN HER.../Verdensøkonomien_2023.xlsx")
View(Verdensøkonomien_2023)
# Vi gemmer Verdensøkonomien_2023.xlsx i variablen data
data <- Verdensøkonomien_2023
# Vi vil gerne gemme landenavnene i første søjle som rækkenavne, før vi kan sætte row.names sættes data som en data.frame
data <- as.data.frame(data)
row_names <- data[,1]
row.names(data) <- row_names
# Vi fjerner nu 1. søjle da denne er gemt som rækkenavne
data <- data[,-1]
Her har vi startet med at plotte data inden selve klyngeanalysen, for at danne os et overblik, til dette bruges pakken ggplot2 i R:
# For at tegne figurer skal vi først loade pakken ggplot2
library(ggplot2)
#Herunder er plot af BNP pr indbygger mod arbejdsløshed farvekodet med Befolkning, for at få et overblik over data
ggplot(data, aes(`BNP pr indbygger USD`, `Arbejdsløshed %`, color = Befolkning,label=rownames(data)))+
geom_text(size=3,check_overlap = TRUE)
#Herunder er plot af BNP mod Befolkning farvekodet med BNP Vækst fra året før %, for at få et overblik over data
ggplot(data, aes(`BNP USD`, Befolkning, color = `BNP Vækst fra året før %`,label=rownames(data)))+
geom_text(size=2,check_overlap = TRUE)
BNP pr indbygger mod arbejdsløshed farvekodet med Befolkning
BNP mod Befolkning farvekodet med BNP Vækst fra året før %
I det første plot ovenfor ses at Sydafrika har meget høj arbejdsløshed, Luxemborg har grundet lav
beskatning
et meget højt BNP pr.
indbygger.
I det andet plot ovenfor kan vi se at USA, Kina og Indien skiller sig ud fra de øvrige
observationer, pga.
deres store befolkninger
og høje BNP.
I det andet plot kan ikke vises særligt mange lande, da vi har valgt at navnene på landene skal
vises,
derfor kunne man f.eks. udelade outliers USA, Kina og
Indien.
datalille i koden herunder er data uden disse 3 lande. Herefter genereres de samme 2 plots:
# For at kunne se alle de små lande fjerner vi Kina, USA og Indien og gemmer datasættet som datalille
datalille <- subset(data, !(rownames(data) %in% c("China", "India","United States")))
#Herunder er plot af BNP pr indbygger mod arbejdsløshed farvekodet med Befolkning, for at få et overblik over data
ggplot(datalille, aes(`BNP pr indbygger USD`, `Arbejdsløshed %`, color = Befolkning,label=rownames(datalille)))+
geom_text(size=3,check_overlap = TRUE)
#Herunder er plot af BNP mod Befolkning farvekodet med BNP Vækst fra året før %, for at få et overblik over data
ggplot(datalille, aes(`BNP USD`, Befolkning, color = `BNP Vækst fra året før %`,label=rownames(datalille)))+
geom_text(size=2,check_overlap = TRUE)
BNP pr indbygger mod arbejdsløshed farvekodet med Befolkning
BNP mod Befolkning farvekodet med BNP Vækst fra året før %
Nu kan vi f.eks. se Danmark i plot af BNP mod Befolkning, vi ligger relativt godt set fra et økonomisk perspektiv med højt BNP i forhold til vores lille befolkning. Men ikke så godt som f.eks. Norge og Schweiz. Herunder er et udsnit af plottet, vi kan se at mørkeblå lande som Belarus og Sri Lanka har negativ vækst (recession). Mens lyseblå lande som Niger, har meget høj vækst.
Herunder er koden til at plotte et hclust klyngetræ
clusters <- hclust(dist(data))
plot(clusters,cex=0.5,main = "Dendogram af Lande",xlab = "Klyngetræ",sub="Verdensøkonomien")
Herunder ses klyngetræet der er genereret i R, vi kan se at Kina og USA skiller sig meget ud, ligesom andre store økonomier som Japan, Tyskland, Indien, Frankrig og UK synes at afvige fra de øvrige lande.
Klyngetræ for VerdensøkonomienVi kan se af klyngetræet at vi mindst bør have 2-3 klynger. Benytter vi kmeans med
Vi kan nu danne klyngeplots for at få et bedre overblik.
Husk at loade pakken factoextra, hvis du skal tegne klyngeplots.
Herunder er R-koden til klyngeanalysen for 5 klynger med scale, et kald for at vise klyngernes
standardiserede
middelværdier, klyngestørrelser samt klyngeplottet.
library(factoextra)
# Klyngeanalysen gemmes i k5 herunder
k5 <- kmeans(scale(data), 5, nstart = 25)
# centers og size hentes fra k5
k5$centers
k5$size
# Klyngeplot dannes baseret på k5
fviz_cluster(k5, data = data, main = "Klyngeplot lande opdelt i 5 klynger",repel = TRUE,labelsize = 4)
Vi kan af ovenstående værdier se, at klyngerne er opdelt ud fra følgende kriterier:
- Klynge 1: Klynge 1 er den store røde mellemgruppe i klyngeplottet herunder med 81 lande, klyngen har ingen særlige karakteristika.
- Klynge 2: Klynge 2 er den gule klynge i klyngeplottet herunder, bestående af lande med høj arbejdsløshed.
- Klynge 3: Klynge 3 er den grønne klynge bestående af lande med højt BNP pr. indbygger, i denne klynge findes f.eks. Danmark, Norge og lande med gunstige skatteregler.
- Klynge 4: Klynge 4 er den blå klynge med meget høj inflation og lav vækst.
- Klynge 5: Klynge 5 er lille i plottet herunder og består af 3 lande (Indien, Kina og USA) med store befolkninger og højt absolut BNP.
Vi udelader nu Kina, Indien og USA, ved at benyttet datalille datasættet vi dannede tidligere.
Herunder er koden til klyngeplot med 4 klynger, for det reducerede datasæt.
fviz_cluster(kmeans(scale(datalille), 4, nstart = 25), data = datalille, main = "Klyngeplot lande opdelt i 4 klynger\nUden Indien, USA og Kina",repel = TRUE,labelsize = 4)
Herunder ses klyngeplottet der er genereret med kun 4 klynger i R for det datalille.
Klynge 1: Danmark ligger i klynge 1, lande med mindre befolkninger, højt BNP pr. indbygger og
relativt solide mindre
økonomier.
Havde vi fx. haft areal med som en variabel var vi nok ikke i klynge med Canada og Australien.
Klynge 2: Klynge 2 domineres af lande med større befolkninger med relativt stort BNP, hvor
Nigeria og
Pakistan ligger
meget yderligt i klyngen.
Klynge 3: Klynge 3 består af lande med ringe økonomier, meget høj inflation, lav vækst.
Tyrkiet er lidt overraskende i klynge 3, hvilket nok primært skyldes den meget høje inflation.
Klynge 4: Klynge 4 spænder noget bredere end de øvrige klynger, noget mindre og helt små
lande mht.
befolkninger og
BNP, bedre økonomier end klynge 3, men ikke som klynge 1.
Der er ingen regler for hvor mange klynger man har med i sin klyngeanalyse, dette afhænger af
hvor fintmasket analysen ønskes.
Herunder er koden til klyngeplot med hele 20 klynger, for det reducerede datasæt. Disse 20 klynger
er ikke
kommenteret, Danmark er nu ikke længere i det supergode selskab med f.eks. Norge og Schweiz.
fviz_cluster(kmeans(scale(datalille), 20, nstart = 25), data = datalille, main = "Klyngeplot lande opdelt i 20 klynger\nUden Indien, USA og Kina",repel = TRUE,labelsize = 4)
Herunder ses klyngeplottet der er genereret med hele 20 klynger i R for det datalille.
| Forklaring af datasættet | |
|---|---|
| Variabel | Forklaring |
| Firmanavn | Revisionsselskabets navn |
| Postnr. | Postnummeret hvor selskabet er hjemmehørende |
| Antal ansatte | Hvor mange ansatte er registreret i virksomheden |
| Etableringsår | Hvilket år er revisionsselskabet registreret |
| Bruttofortjeneste (1.000 kr) | Indtægter fra revisionsydelser minus direkte omkostninger (f.eks. lønninger til revisorer, omkostninger til revisionsteknologi etc.). |
| Primært Resultat (1.000 kr) | Indtjening fra kerneaktiviteter (revision og rådgivning) før renter, skatter og andre finansielle poster. |
| Årets nettoresultat (1.000 kr) | Total indtjening efter fradrag af alle omkostninger, skatter og renteudgifter. |
| Overført resultat (1.000 kr) | Den del af årets resultat, der ikke udbetales som udbytte, men overføres til næste regnskabsår. |
| Egenkapital (1.000 kr) | Ejernes investering i firmaet plus akkumuleret overskud, efter fradrag af eventuelle tab. |
| Balance (1.000 kr) | Finansiel opgørelse, der viser firmaets aktiver, forpligtelser og egenkapital på et givet tidspunkt. |
| Kapacitetsgrad (%) | Mål for, hvor meget af firmaets totale kapacitet (f.eks. revisorers arbejdstimer) der faktisk anvendes. |
| Afkastningsgrad (%) | Hvor effektivt firmaet anvender sine aktiver til at generere indtjening. |
| Likviditetsgrad (%) | Firmaets evne til hurtigt at omdanne aktiver til likvide midler for at dække kortfristede forpligtelser. |
| Soliditetsgrad (%) | Andel af firmaets aktiver, der er finansieret med egenkapital, et mål for finansiel stabilitet. |
| Egenkapitalforrentning (%) | Afkast på ejernes investering, beregnet som nettoresultatet divideret med egenkapitalen. |
| Sikkerhedsmargin (%) | Hvor meget omsætningen kan falde, før virksomheden ikke længere er rentabel. |
| Indre værdi (%) | En estimeret værdi af firmaets aktie, baseret på dets aktiver og fremtidige indtjeningspotentiale. |
Tabel 21.3: Variabeloversigt for datasættet med 53 revisionsselskaber — 17 regnskabs- og nøgletalsvariable (bruttofortjeneste, egenkapital, afkastningsgrad, soliditetsgrad m.fl.), der bruges til at klynge selskaberne.
Kilde: Egen tilvirkning baseret på datasættet "Revisionsselskaber 2023".
Herunder kan du se koden for at bibeholde, revisionsselskabernes navne i R, så disse er med i output.
# Vi omdøber til data efter importen af Excelfilen i R
data <- data.frame(Revisionsselskaber_2023)
# Rækkenavne gemmes i variablen row_names
row_names <- Revisionsselskaber_2023[,1]
# data får rækkenavne
rownames(data) <- t(row_names)
# 1. søjle med rækkenavne fjernes fra datasættet, disse er nu gemt som rækkenavne.
data <- data[,-1]
R-kode til at tegne, dendogrammet/klyngetræet for revisionsselskaberne ses herunder.
clusters <- hclust(dist(data))
plot(clusters,cex=0.25,main = "Dendogram",xlab = "Klyngetræ",sub="revisorer")
Dendogrammet/klyngetræet for revisionsselskaberne kan ses herunder.
I løsningsforslaget er valgt en klyngeanalyse med 5 klynger. Herunder er R-kode og output.
library(factoextra)
k5 <- kmeans(scale(data), 5, nstart = 25)
k5$size
k5$centers
fviz_cluster(k5, data = data, main = "Klyngeplot revisorer opdelt i 5 klynger",repel = TRUE,labelsize = 4)
Herunder ses R-output for k5$size og k5$centers. Vi har 3 mindre klynger og 2 større. Store og små værdier for de skalerede klyngegennemsnit er markeret med hhv. grønne og røde rammer.
Vi kan af centers bestemme følgende karakteristika for de 5 klynger:
Klynge 1: Lille klynge af 2 store revisionsselskaber (KPMG og Beierholm) målt på Antal
ansatte
Bruttofortjeneste,
Egenkapital og Balance. Dog har selskaberne en lavere Afkastningsgrad, Soliditetsgrad og
Egenkapitalforrentning.
Klynge 2: Klynge af 5 lidt ældre revisionsselskaber i Københavnsområdet (lav værdi af
Postnr.) med
flotte resultater og Egenkapitalforrentning.
Klynge 3: Stor klynge af revisionsselskaber kendetegnet ved høje Soliditetsgrader, disse
selskaber
har altså primært finansieret sig ved egenkapital.
Klynge 4: Denne klynge har relativt ringere resultater end de øvrige klynger.
Klynge 5: Lille klynge af forholdsmæssigt veldrevne revisionsselskaber med høj
Egenkapitalforrentning
og Afkastningsgrad.
| US_Rich datasættet | |
|---|---|
| Variabel | Forklaring på de 9 variable |
| Name/Company | Navn på personen, samt hvilket selskab vedkommende primært er kendt for. |
| age | Hvor gammel er personen. |
| finalWorth mio. USD | Formue i mio USD, er værdien her f.eks. 1.000 betyder det at personen har en formue på 1 mia. USD. |
| selfmade_dummy | Har personen selv skabt formuen er værdien 1, ellers 0. |
| female_dummy | 1 hvis kvinde, 0 hvis mand. |
| philanthropyScore | En rang der angiver hvor meget vedkommende giver til godgørende formål. Hvor 1 er lavest, 5 er højest. |
| tech_dummy | Er formuen primært skabt i teknologi sektoren. |
| finance_dummy | Er formuen primært skabt i den finansielle sektor. |
| food_dummy | Er formuen primært skabt i sektoren indenfor føde- og drikkevarer. |
Tabel 21.4: Variabeloversigt for US_Rich-datasættet — 9 variable (alder, formue, selfmade-status, køn, filantropi-score og branchedummies) for 357 ultrarige amerikanere, der skal grupperes i klynger.
Kilde: Egen tilvirkning baseret på datasættet "US_Rich".
# Vi omdøber
data <- data.frame(US_Rich)
# Rækkenavne gemmes i variablen row_names
row_names <- US_Rich[,1]
# data får rækkenavne
rownames(data) <- t(row_names)
# 1. søjle med rækkenavne fjernes fra datasættet, disse er nu gemt som rækkenavne.
data <- data[,-1]
Dendogrammet klyngetræet er lidt svært at se navnene ordentligt, da der er 357 personer med i datasættet, dette er ses herunder, hvis man zoomer ind kan man læse navnene.
I løsningsforslaget er valgt en klyngeanalyse med 5 klynger.
library(factoextra)
k5 <- kmeans(scale(data), 5, nstart = 25)
k5$size
k5$centers
fviz_cluster(k5, data = data, main = "Klyngeplot superrige opdelt i 5 klynger",repel = TRUE,labelsize = 4)
Herunder ses R-output for k5$size og k5$centers. Vi har 2 store klynger, 1 og med 137 superrige og 2 med 91 superrige.
Vi kan af centers bestemme følgende karakteristika for de 5 klynger:
Klynge 1: Stor klynge af lidt ældre superrige, der er ellers ingen særlige kendetegn udover
at de
ikke har
tjent formuen indenfor
tech, finans eller food.
Klynge 2: Større klynge der primært har tjent formuen indenfor finans.
Klynge 3: De mindst velhavende af de superrige, de giver ikke noget særligt til velgørenhed
og har
tjent
formuen i fødevareindustrien.
Klynge 4: Primært kvinder i denne klynge, respondenterne i klyngen har typisk arvet
formuen.
Klynge 5: Yngre ultra superrige med selvskabte formuer primært tjent i tech-industrien
Bemærk hvor tydeligt karakteristika kan aflæses i de 5 klynger herover. Gul klynge 2 med finansfolk, Blå klynge 4, med mange kvinder, Lilla klynge 5 med unge tech ultrarige tech folk.
Bemærk når du henter data fra Excel er rækkenavne som regel bare numre 1,2,3... i stedet for fx. Alabama, Arizona,...
For at angive rækkenavne fra første søjle i Excel regnearket kan man benytte rownames-kommandoen i R, som nedenfor.
# Tjek hvilke rækkenavne dit datasæt har, når du har importeret fra Excel
rownames(usarrest)
# Fjern første kolonne med navnene på staterne i det importerede datasæt, kald usarrest for data
data <- usarrest[,-1]
# Lav data til en dataframe
data <- as.data.frame(data)
# Angiv at data's rækkenavne skal være staterne i USA, så der ikke blot står et rækkenummer
rownames(data) <- t(usarrest[,1])
# Tjek at navnene i dit datasæt nu er staterne
rownames(data)
Excelfilen om USArrests
Datasættet består af følgende 4 variable:
1. Mord, antal arrestationer (pr 100,000)
2. Overfald, antal arrestationer (pr 100,000)
3. Urbaniseringsgrad andel af bybefolkning.
4. Voldtægt, antal arrestationer (pr 100,000)
pacman::p_load(datasets)
arrest <- USArrests
head(arrest)
Undersøg om der kan dannes klynger og hvorledes disse kan
karakteriseres. Illustrer grafisk og kommenter på karakteristika for
klyngerne.