Il file cars.csv presenta 10 variabili (numero di cilindri, dimensioni dei veicolo, indicatori di performance) di 53 modelli diversi di automobile. I dati possono essere importati con il seguente comando:

D <- read.csv("cars.csv", header = TRUE, row.names=1)

Otteniamo la dimensione del dataset, la media e la varianza di ciascuna variabile

dim(D)
## [1] 53 10
apply(D , 2, mean)
##         cyl        disp          pw        leng         wid        heig 
##    5.037736 2383.132075  143.356604 4306.943396 1799.169811 1499.377358 
##          wg       speed         acc        cons 
## 1443.603774  202.950943   10.109434    8.783019
apply(D , 2, var)
##          cyl         disp           pw         leng          wid         heig 
## 4.575472e+00 2.003218e+06 1.292237e+04 2.346743e+05 1.617791e+04 2.513520e+04 
##           wg        speed          acc         cons 
## 1.577197e+05 2.807535e+03 1.239741e+01 1.487259e+01

Si può utilizzare anche la funzione

summary(D)
##       cyl              disp            pw             leng           wid      
##  Min.   : 3.000   Min.   : 796   Min.   : 38.0   Min.   :3337   Min.   :1495  
##  1st Qu.: 4.000   1st Qu.:1497   1st Qu.: 74.0   1st Qu.:4050   1st Qu.:1721  
##  Median : 4.000   Median :1970   Median :110.0   Median :4336   Median :1792  
##  Mean   : 5.038   Mean   :2383   Mean   :143.4   Mean   :4307   Mean   :1799  
##  3rd Qu.: 6.000   3rd Qu.:2996   3rd Qu.:170.0   3rd Qu.:4603   3rd Qu.:1892  
##  Max.   :12.000   Max.   :6749   Max.   :640.0   Max.   :5830   Max.   :2170  
##       heig            wg           speed            acc             cons       
##  Min.   :1135   Min.   : 735   Min.   : 19.4   Min.   : 3.40   Min.   : 4.200  
##  1st Qu.:1420   1st Qu.:1277   1st Qu.:175.0   1st Qu.: 8.10   1st Qu.: 6.300  
##  Median :1488   Median :1370   Median :197.0   Median :10.20   Median : 7.700  
##  Mean   :1499   Mean   :1444   Mean   :203.0   Mean   :10.11   Mean   : 8.783  
##  3rd Qu.:1568   3rd Qu.:1605   3rd Qu.:228.0   3rd Qu.:12.50   3rd Qu.: 9.500  
##  Max.   :1890   Max.   :2495   Max.   :340.0   Max.   :21.90   Max.   :21.300

Standardizziamo le variabili attraverso la funzione

D.sd<-scale(D)
#head(D.sd)

Utilizziamo la funzione del pacchetto cluster per effettuare una analisi di clustering gerarchico basata sulla distanza Euclidea e diversi linkages

library(cluster)
eu.dist<-dist(D.sd)

hc.sing<-agnes(eu.dist, method="single")
pltree(hc.sing, cex=0.8, hang = -1, main="SL")

hc.ave<-agnes(eu.dist, method="average")
pltree(hc.ave, cex=0.8, hang = -1, main="AL")

hc.com<-agnes(eu.dist, method="complete")
pltree(hc.com, cex=0.8, hang = -1, main="CL")

Utilizziamo anche il metodo di Ward

hc.ward<-agnes(D.sd, method="ward")
pltree(hc.ward, cex=0.8, hang = -1, main="Ward")

Dall’ultimo dendrogramma ottenuto si potrebbero ricavare due partizioni, con 3 e 5 gruppi, rispettivamente:

pltree(hc.ward, cex=0.8, hang = -1, main="Ward")
rect.hclust(hc.ward, 3)

cl3<-cutree(hc.ward, 3)
pltree(hc.ward, cex=0.8, hang = -1, main="Ward")
rect.hclust(hc.ward, 5)

cl5<-cutree(hc.ward, 5)

Otteniamo la composizione del raggruppamento con K=3

table(cl3)
## cl3
##  1  2  3 
## 28 18  7
labels<-row.names(D)
labels[cl3==1]
##  [1] "Fiat_500_1.2"           "Fiat_500_1.3"           "Fiat_500_1.4"          
##  [4] "Fiat_Multipla_1.616v"   "Fiat_Multipla_NatPower" "Fiat_600_"             
##  [7] "Mercedes_A_1.6"         "Chevrolet_Matiz_"       "Toyota_Yaris_"         
## [10] "Ford_Focus_1.6"         "Seat_Altea_1.6"         "Seat_Altea_2.0"        
## [13] "Fiat_Doblo_1.2"         "Fiat_Doblo_1.9"         "BMW_Z3_1.9"            
## [16] "VW_Fox_1.2"             "Fiat_Bravo_1.4"         "Fiat_Bravo_1.9"        
## [19] "Fiat_Bravo_1.6v150"     "Lancia_Y_1.2"           "Lancia_Y_1.4"          
## [22] "VW_Golf_1.4"            "VW_Golf_GTI"            "VW_Newbeetle_1.6"      
## [25] "Opel_Meriva_1.6-16v"    "Volvo_V50_"             "Volvo_C30_"            
## [28] "Toyota_Aygo_1.0"
labels[cl3==2]
##  [1] "Mercedes_C_3.0"           "AlfaRomeo_Spider_2.4"    
##  [3] "AlfaRomeo_GT_2.0"         "AlfaRomeo_Brera_2.2"     
##  [5] "AlfaRomeo_Brera_3.2"      "LandRover_Freelander_3.2"
##  [7] "BMW_Z3_2.2"               "BMW_Z3_3.0"              
##  [9] "BMW_320i_"                "BMW_630i_"               
## [11] "Porsche_Cayenne_"         "Audi_A6_"                
## [13] "Hyunday_Sonica_2.4-16v"   "Toyota_Corolla_1.8VVT"   
## [15] "Toyota_Rav4_2.0vvti"      "Volvo_S60_2.4"           
## [17] "Volvo_S60_3.2awd"         "Hummer_H3_"
labels[cl3==3]
## [1] "Ferrari_430_scuderia"         "Maserati_Sport_GTS"          
## [3] "Lamborghini_Murcielago_L8640" "Jaguar_XK_4.2v8"             
## [5] "Bentley_Continental_Flying"   "AstonMartin_Vanquish_"       
## [7] "RollsRoyce_Phantom_"

I cluster sono caratterizzati come segue:

Affinando la partizione e considerando 5 gruppi, si osserva che i due gruppi più eterogenei vengono ulteriormente suddivisi.

Infine, utilizziamo la funzione per eseguire l’algoritmo PAM con K=3 e K=5:

# PAM con K=3 gruppi
pam.out3<-pam(D.sd,3) 
pam.out3$silinfo$avg.width
## [1] 0.2940391
pam.out3$medoids  
##                          cyl       disp         pw       leng        wid
## Fiat_500_1.2       -0.485142 -0.8062539 -0.8124504 -1.5707953 -1.3536169
## Volvo_C30_         -0.485142 -0.2714042 -0.3198249 -0.1134182 -0.1349908
## Maserati_Sport_GTS  1.384860  1.3147751  1.3339895  1.5380006  0.7534269
##                           heig         wg      speed        acc       cons
## Fiat_500_1.2       -0.07176295 -1.4569285 -0.8106065  0.7925503 -0.9550160
## Volvo_C30_         -0.33037137 -0.2936091  0.1330358 -0.2014868 -0.3845505
## Maserati_Sport_GTS -0.46913687  1.0988488  1.2654065 -1.2807270  1.5342879
#D[pam.out3$id.med, ]
# PAM con K=5 gruppi
pam.out5<-pam(D.sd,5) 
pam.out5$silinfo$avg.width
## [1] 0.2970917
pam.out5$medoids  
##                             cyl       disp         pw        leng        wid
## Fiat_500_1.2          -0.485142 -0.8062539 -0.8124504 -1.57079533 -1.3536169
## Seat_Altea_1.6        -0.485142 -0.5568458 -0.6013252 -0.05561854 -0.2450603
## AlfaRomeo_Brera_2.2   -0.485142 -0.1308030 -0.0647152  0.21892984  0.2423901
## AstonMartin_Vanquish_  3.254862  2.5095320  2.1520998  0.74944814  0.9499794
## Volvo_S60_3.2awd       0.449859  0.5714965  0.2783633  1.03225362  0.7770132
##                              heig          wg      speed        acc       cons
## Fiat_500_1.2          -0.07176295 -1.45692847 -0.8106065  0.7925503 -0.9550160
## Seat_Altea_1.6         0.43283887 -0.18533483 -0.4142768  0.7641492 -0.3067597
## AlfaRomeo_Brera_2.2   -0.80343557  0.06646589  0.3595099 -0.4286952  0.1599847
## AstonMartin_Vanquish_ -1.13142675  1.08625881  2.2279216 -1.5079355  2.6233584
## Volvo_S60_3.2awd       1.79526376  1.55209014  0.1330358 -0.1730857  0.8601015
#D[pam.out5$id.med, ]

Otteniamo il grafico della silhouette media:

par(mfrow=c(1,2))
plot(pam.out3, which=2, main=" ")
plot(pam.out5, which=2, main=" ")

Per la partizione in 3 gruppi, aggiungiamo ai dati il vettore del clustering

D$Group <- as.factor(pam.out3$clustering)

Possiamo utilizzare dei box plots per descrivere la distribuzione di alcune variabili condizionando ai gruppi ottenuti

par(mfrow=c(2,2), mar=c(2,2,2,2))
plot(D$Group, D$pw, col=2:4, main="Power", xlab="cluster")
plot(D$Group, D$speed, col=2:4, main="Max. Speed", xlab="cluster")
plot(D$Group, D$acc, col=2:4, main="Acceleration", xlab="cluster")
plot(D$Group, D$cons, col=2:4, main="Fuel Consumption", xlab="cluster")