Sei sulla pagina 1di 28

Metodi statistici per il

Data Mining

Cluster Analysis con R

Stefania Mignani
Dati

Il data set si riferisce alle 20 regioni italiane per le quali si sono


rilevate 6 variabili quantitative

Regione: →stringa
1. Indicepov: indicatore della povertà →% di famiglie con reddito al
di sotto della soglia di povertà
2. Crimini: tasso di criminalità→ crimini ogni 100 abitanti → quant
3. Scolarizza: livello di scolarizzazione→% di popolazione nella
fascia 20-24 con almeno il diploma di scuola secondaria superiore
4. Dis_giov: tasso di disoccupazione giovanile (15-24 anni)
5. Pil: Prodoto Interno Lordo
6. Internet: percentuale di famiglie con Internet

OBIETTIVO: CLASSIFICARE LE REGIONI PER EVIDENZIARE


PARTICOLARI COMPORTAMENTI TERRITORIALI
Caricamento dei dati e
prime analisi esplorative

regioni<-read.table("regioni.txt",header=T)
dim(regioni)
str(regioni)

data.frame': 20 obs. of 7 variables:


$ Regione : Factor w/ 20 levels "Abruzzo","Basilicata",..: 1 2 3 4 5 6 7 8 9
10 ...
$ Indicepov : num 9.2 26.5 29.6 28.5 4.6 9.1 7.8 6.1 5.1 8.8 ...
$ Crimini : num 2.8 4 2.6 3.2 3.2 4.6 3.1 3.5 3.2 2.5 ...
$ Scolarizza: num 80.4 84.6 78.3 72.1 81.4 80.2 83 84.7 74.1 80.7 ...
$ Dis_giov : num 24 38.3 31.8 38.1 18.3 18.9 30.6 18.8 18.5 22.6 ...
$ Pil : num 27703 10973 33988 95087 133035 ...
$ Internet : num 48.1 39.9 38.6 45.3 50.8 49.6 51.5 42.3 50.6 53 ...
Calcolo delle Distanze

#calcolo della distanza euclidea sulle variabili originarie


dist.or<-dist(regioni[,(-1)],method="euclidean")
1 1 2 3 4 5 6
2 16730.0176
3 6285.0455 23015.0021
4 67384.0048 84114.0011 61099.0010
5 105332.0003 122062.0041 99047.0049 37948.0142
6 7153.0022 23883.0166 868.4119 60231.0069 98179.0001

#standardizzazione delle variabili


datist<-scale(regioni[,(-1)])
#calcolo della distanza euclidea sulle variabili standardizzate
dist.z<-dist(datist,method="euclidean")
1 1 2 3 4 5 6
2 3.2238151
3 3.1155337 1.8543874
4 3.1685161 2.8883358 2.1741828
5 1.7552459 4.3383171 4.2743351 3.9243306
6 1.6247297 3.5991736 3.8784533 3.6662296 1.8537053
Cluster gerarchica

# cluster gerarchica col metodo di Ward


h<-hclust(dist.z, method="ward") #presente nel pacchetto stats
#produce in output una serie di oggetti
h$merge
# matrice di dimensioni (n-1)x 2 che indica per ogni aggregazione i
cluster aggregati
[,1] [,2] [,1] [,2]
unità-cluster che vengono aggregati nei
[1,] -5 -20 [10,] -11 6 vari step dell’algoritmo (gli elementi con
[2,] -12 -16 [11,] -8 10 il meno davanti sono le unità mentre
[3,] -1 -10 [12,] -19 5 quelli senza meno indicano lo step nel
[4,] -13 -15 [13,] 4 7 quale è stato formato il cluster!!!).
[5,] -6 2 [14,] -9 9
[6,] -18 3 [15,] 8 13
[7,] -4 -14 [16,] -17 12
[8,] -2 -3 [17,] 11 14
[9,] -7 1 [18,] 16 17
[19,] 15 18
Dendrogramma

plot(h,labels=regioni$Regione)
Scelta della partizione

h.cl<-h$height # le distanze a cui avvengono le fusioni ad ogni passo:


sequenza di n-1 numeri reali non decrescenti che indicano la distanza tra i
cluster

[1] 0.7537496 1.0174118 1.1038073 1.3091118 1.6331679 1.6896399


[7] 1.7306679 1.8543874 2.0469822 2.2140720 2.4150713 2.5131908
[13] 2.8080683 3.3330469 4.1009397 4.1418303 5.9711043 6.3490776
[19] 15.1771986

h.cl2<-c(0,h.cl[-length(h.cl)]) #vettore con le distanze-dissomiglianze al passo


precedente che devo sottrarre (aggiungo uno zero davanti)

[1] 0.0000000 0.7537496 1.0174118 1.1038073 1.3091118 1.6331679


[7] 1.6896399 1.7306679 1.8543874 2.0469822 2.2140720 2.4150713
[13] 2.5131908 2.8080683 3.3330469 4.1009397 4.1418303 5.9711043
[19] 6.3490776
Scelta della partizione

round(h.cl-h.cl2,3) # differenza assoluta arrotondata al terzo decimale (non faccio


l’incremento relative perché ho degli zeri!)

[1] 0.754 0.264 0.086 0.205 0.324 0.056 0.041 0.124 0.193 0.167 0.201
[12] 0.098 0.295 0.525 0.768 0.041 1.829 0.378 8.828

max(round(h.cl-h.cl2,3)) #il Massimo arrotondato


[1] 8,828

numgr<-which.max(round(h.cl-h.cl2,3))
[19]
#Sulla base delle differenze delle distanze tra partizioni il numero più
appropriato è 2 perchè all’ultimo step che si ha il più alto incremento,
Dedrogramma con gruppi

#dendrogramma colorato
numgruppi <- cutree(h, k = 2) #definire i gruppi
rect.hclust(h, k=2, border=c("red","blue","green","goldenrod"))
Descrizione dei cluster

1 1 Abruzzo
library(dplyr) #pacchetto aggiuntivo 2 2 Basilicata
regioni <- cbind(regioni, member = 3 2 Calabria
4 2 Campania
numgruppi) #appartenenza ai gruppi 5 1 Emilia-Romagna
6 1 Friuli-Venezia Giulia
7 1 Lazio
8 1 Liguria
9 1 Lombardia
10 1 Marche
11 1 Molise
12 1 Piemonte
13 2 Puglia
14 2 Sardegna
15 2 Sicilia
16 1 Toscana
17 1 Trentino
18 1 Umbria
19 1 Valle d'Aosta/Vallée d'Aos
20 1 Veneto
Descrizione dei gruppi

table(regioni$member) #numero di unità per gruppo


1 2
14 6

by(data = regioni[, -(1)], INDICES = regioni$member, FUN = summary) #sintesi


delle variabili nei due gruppi

regioni$member: 1
Indicepov Crimini Scolarizza Dis_giov
Min. : 4.600 Min. :1.900 Min. :70.40 Min. :10.20
1st Qu.: 6.225 1st Qu.:2.800 1st Qu.:75.35 1st Qu.:17.93
Median : 7.700 Median :3.200 Median :79.45 Median :18.85
Mean : 8.146 Mean :3.571 Mean :78.96 Mean :20.17
3rd Qu.: 9.025 3rd Qu.:4.175 3rd Qu.:81.22 3rd Qu.:23.65
Max. :18.300 Max. :7.500 Max. :87.60 Max. :30.60

Pil Internet
Min. : 4183 Min. :42.30
1st Qu.: 22785 1st Qu.:48.12
Median : 41918 Median :49.20
Mean : 83920 Mean :48.92
3rd Qu.:130167 3rd Qu.:50.75
Max. :310952 Max. :53.00
Descrizione dei gruppi

regioni$member: 2
Indicepov Crimini Scolarizza Dis_giov
Min. :21.90 Min. :2.600 Min. :68.60 Min. :31.80
1st Qu.:26.12 1st Qu.:3.125 1st Qu.:70.45 1st Qu.:33.98
Median :27.50 Median :3.500 Median :71.50 Median :38.20
Mean :26.97 Mean :3.500 Mean :74.13 Mean :37.33
3rd Qu.:29.10 3rd Qu.:3.950 3rd Qu.:76.75 3rd Qu.:38.45
Max. :29.60 Max. :4.300 Max. :84.60 Max. :44.70
Pil Internet
Min. :10973 Min. :38.10
1st Qu.:33585 1st Qu.:38.90
Median :51140 Median :39.85
Mean :54634 Mean :41.87
3rd Qu.:81584 3rd Qu.:43.95
Max. :95087 Max. :49.50
Verifica bontà classificazione
# due nuovi pacchetti
library(clusterSim)
library(ggplot2)
# Calcola i valori di silhouette per valutare i cluster
sil <- silhouette(numgruppi, dist.z)
# disegna il silhouette
plot(sil)
# l’unità 11 (Molise) ha valore
dell’indice negativo
quindi non è ben
classificata
Data set vinho verde

1559 vini e 6 variabili


• Acidità fissa: è la quota costituita dalle sostanze acide presenti in un vino,
che non sono portate a volatilizzare, ma al contrario restano all’interno del
vino per tutta la sua vita. Essendo uno dei parametri fondamentali del vino,
determina, il periodo di vendemmia
• Anidride Solforosa Totale: E’ la quota di Anidride solforosa (SO2 biossido
di Zolfo) libera più quella dovuta altri agenti chimici come aldeidi, pigmenti,
o zuccheri. Principale additivo utilizzato in campo enologico per la
prevenzione delle alterazioni del vino
• Ph: Costituisce un indice di acidità reale. E' un parametro che subisce
variazioni durante le varie fasi di vinificazione e conservazione;
• Solfiti: vengono aggiunti per favorire la conservazione. Possiedono delle
proprietà antiossidanti, quindi, e antimicrobiche che preservano il vino dai
danni dei batteri
• Gradazione alcolica: indica la percentuale di alcol in volume
• Giudizio di gradimento: 1=insoddisfatto, 2=soddisfatto
Metodo partitivo

#installare il pacchetto
install.packages("fpc")

# caricare il pacchetto
library(fpc)

#caricare I dati
vino<-read.table("vino.txt",header=T)
str(vino)

#per trasformare in categorica


vino$Grad<-as.factor(vino$Grad)
Analisi esplorative
#esplorative
summary(vino)
Acfissa AnidsolfT PH
Min. : 4.60 Min. : 6.00 Min. :2.740
1st Qu.: 7.10 1st Qu.: 22.00 1st Qu.:3.210
Median : 7.90 Median : 38.00 Median :3.310
Mean : 8.32 Mean : 46.47 Mean :3.311
3rd Qu.: 9.20 3rd Qu.: 62.00 3rd Qu.:3.400
Max. :15.90 Max. :289.00 Max. :4.010
Solfiti Alcohol Grad
Min. :0.3300 Min. : 8.40 Min. :1.000
1st Qu.:0.5500 1st Qu.: 9.50 1st Qu.:1.000
Median :0.6200 Median :10.20 Median :2.000
Mean :0.6581 Mean :10.42 Mean :1.535
3rd Qu.:0.7300 3rd Qu.:11.10 3rd Qu.:2.000
Max. :2.0000 Max. :14.90 Max. :2.000
Standardizzazione e calcolo distanze

#nuova matrice con solo variabile quantitative


vinoq<-as.matrix(vino[,1:5])
#standardizzare le variabili
vinost<-scale(vinoq)
#calcolare distanza euclidea
d<-dist(vinost)
#creare la matrice di distanza
d<-as.matrix(d)
1 2 3 4 5
1 0.000000 0.000000 4.609867 2.710647 2.710647
2 0.000000 0.000000 4.609867 2.710647 2.710647
3 4.609867 4.609867 0.000000 3.045182 3.045182
4 2.710647 2.710647 3.045182 0.000000 0.000000
5 2.710647 2.710647 3.045182 0.000000 0.000000
K-means

#clustering con k-medie due gruppi


ci vuole il data set e centers indica
cl2=kmeans(vinost,centers=2,nstart=20)
il numero di gruppi
#alcuni output della procedura
cl2$size #dimensione gruppi
[1] 539 1060
cl2$centers #baricentri dei due gruppi
Acfissa AnidsolfT PH Solfiti Alcohol
1 1.0285200 -0.2497459 -0.8527382 0.6107177 0.17349313
2 -0.5229927 0.1269934 0.4336093 -0.3105442 -0.08821962
cl2$cluster #appartenenza ai due gruppi
[1] 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2
[25] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

vino$Cluster<-as.factor(cl2$cluster) # aggiungo colonna con appartenenza


gruppo
Esplorative gruppi
#esplorative per gruppo
by(data = vino, INDICES = vino$Cluster, FUN = summary)
Cluster 1
Acfissa AnidsolfT PH
Min. : 6.90 Min. : 6.00 Min. :2.740
1st Qu.: 8.90 1st Qu.: 19.00 1st Qu.:3.120
Median :10.00 Median : 29.00 Median :3.180
Mean :10.11 Mean : 38.25 Mean :3.179
3rd Qu.:11.05 3rd Qu.: 49.00 3rd Qu.:3.260
Max. :15.90 Max. :151.00 Max. :3.480
Solfiti Alcohol Grad
Min. :0.4200 Min. : 8.40 Min. :1.000
1st Qu.:0.6200 1st Qu.: 9.60 1st Qu.:1.000
Median :0.7300 Median :10.50 Median :2.000
Mean :0.7617 Mean :10.61 Mean :1.668
3rd Qu.:0.8400 3rd Qu.:11.40 3rd Qu.:2.000
Esplorative gruppi

Cluster: 2
Acfissa AnidsolfT PH
Min. : 4.600 Min. : 7.00 Min. :3.010
1st Qu.: 6.800 1st Qu.: 25.00 1st Qu.:3.290
Median : 7.400 Median : 41.00 Median :3.370
Mean : 7.409 Mean : 50.65 Mean :3.378
3rd Qu.: 8.000 3rd Qu.: 68.00 3rd Qu.:3.450
Max. :10.100 Max. :289.00 Max. :4.010
Solfiti Alcohol Grad
Min. :0.3300 Min. : 8.70 Min. :1.000
1st Qu.:0.5400 1st Qu.: 9.50 1st Qu.:1.000
Median :0.5900 Median :10.00 Median :1.000
Mean :0.6055 Mean :10.33 Mean :1.467
3rd Qu.:0.6600 3rd Qu.:11.00 3rd Qu.:2.000
Max. :1.1600 Max. :14.00 Max. :2.000
Due gruppi

Gruppo Acfissa AnidsolfT PH Solfiti Alcohol Gradimento

1 (539) 1.0285 -0.8527 0.2497 0.6108 0.1735 1=179 2=360


67% pos
2 (1060) -0.5230 0.1270 0.4336 -0.3105 -0.0882 565 495
46% pos

GRUPPO 1: Vini con acidità fissa, solfiti e tasso alcolico più alto
GRUPPO 2 Vini con più alta concentrazione di anidride solforosa e ph
Validità partizione

#analisi validità dei gruppi


out.cl2<-cluster.stats(d,cl2$cluster) #outoput per i
confronti
out.cl2$avg.silwidth #indicatore più si avvicina a uno
meglio è
[1] 0.2538071
out.cl2$pearsongamma #indicatore più si avvicina a uno
meglio è
[1] 0.3655827
Varie soluzioni
#per provare varie soluzioni
install.packages("factoextra")
library(factoextra)
Ricordiamo che vogliamo gruppi
# funzione per calcolare la varianza entro omogeni al loro interno quindi
cercare di minimizzare WSS
wss <- function(k) {
kmeans(vinost, k, nstart = 20 )$tot.withinss
}
#grafici per scegliere numero di gruppi
#metodo di Elbon
fviz_nbclust(vinost, kmeans, method = "wss",k.max = 10)
#metodo della silhouette
fviz_nbclust(vinost, kmeans, method = "silhouette")
Varie soluzioni

Metodo di Elbon
WSS scende sempre. Scegliamo Metodo della silhouette.
dove si presenta il gomito, cioè dopo Indica la qualità del gruppo. Un valore
quel numero di gruppi scende ma di elevato elevata indica un buon
poco raggruppamento. Si calcola la silhouette
media per diversi valori di k.
Confronto tra soluzioni
#ripetiamo per diversi numeri di gruppi
cl3=kmeans(vinost,centers=3,nstart=20)
cl4=kmeans(vinost,centers=4,nstart=20)
cl5=kmeans(vinost,centers=5,nstart=20)
cl6=kmeans(vinost,centers=6,nstart=20)
out.cl3<-cluster.stats(d,cl3$cluster)
out.cl3$avg.silwidth
out.cl3$pearsongamma
out.cl4<-cluster.stats(d,cl4$cluster)
out.cl4$avg.silwidth
out.cl4$pearsongamma
out.cl5<-cluster.stats(d,cl5$cluster)
out.cl5$avg.silwidth
out.cl5$pearsongamma
out.cl6<-cluster.stats(d,cl6$cluster)
out.cl6$avg.silwidth
out.cl6$pearsongamma
Confronto tra soluzioni

out.cl3$avg.silwidth
[1] 0.2178705
> out.cl3$pearsongamma
[1] 0.3667339
>out.cl4$avg.silwidth
[1] 0.2215525
out.cl4$pearsongamma
[1] 0.4126725
out.cl5$avg.silwidth
[1] 0.2419866
out.cl5$pearsongamma
[1] 0.4549679
>out.cl6$avg.silwidth
[1] 0.233619
>out.cl6$pearsongamma
[1] 0.4407883
Soluzione a cinque gruppi

#scelto 5 gruppi: esplorative


vino$Cluster<-as.factor(cl5$cluster)# aggiungo colonna con
appartenenza gruppo
#esplorative per gruppo
by(data = vino, INDICES = vino$Cluster, FUN = summary)
Cinque gruppi
Gruppo Acfissa AnidsolfT PH Solfiti Alcohol Gradimento

1 (58) -0.4126 -0.3393 0.3659 -0.3247 -0.5284 1= 39 2=19


33% pos
2 (338) -0.1477 1.6206 0.2846 -0.4182 -0.6368 1=69 2=269
79% pos
3 (356) -0.6908 -0.3189 0.8239 0.0668 1.2573 1=97 2=259
73% pos
4 (269) 0.1967 0.6069 -1.2836 3.2963 -0.6896 1=207 2=62
23% pos
5 (578) 1.4054 -0.4696 -0.9522 0.2427 0.2578 1=332 2=246
42% pos

Gruppo 1: sotto media per tutto tranne che per ph (secondo valore più alto)
Gruppo 2: più alta concentrazione anidride solforosa in contrasto con tasso alcolico
Gruppo 3: tasso alcolico decisamente più alto e più alto ph
Gruppo 4: alta presenza di solfiti in contrasto col ph
Gruppo 5: più alta acidità fissa