В работе участвует набор данных Auto. В этом наборе:
-mpg - расход топлива (галлонов на милю)
-cylinders - количество цилиндров (между 4 и 8)
-displacement - объем двигателя в квадратных дюймах
-horsepower - лошадиная сила
-weight - масса автомобиля в кг
-acceleration - время разгона от 0 до 60 миль/час
-year - год выпуска
-origin - страна-производитель
Посчитаем основные характеристики.
data("Auto")
str(Auto)
## 'data.frame': 392 obs. of 9 variables:
## $ mpg : num 18 15 18 16 17 15 14 14 14 15 ...
## $ cylinders : num 8 8 8 8 8 8 8 8 8 8 ...
## $ displacement: num 307 350 318 304 302 429 454 440 455 390 ...
## $ horsepower : num 130 165 150 150 140 198 220 215 225 190 ...
## $ weight : num 3504 3693 3436 3433 3449 ...
## $ acceleration: num 12 11.5 11 12 10.5 10 9 8.5 10 8.5 ...
## $ year : num 70 70 70 70 70 70 70 70 70 70 ...
## $ origin : num 1 1 1 1 1 1 1 1 1 1 ...
## $ name : Factor w/ 304 levels "amc ambassador brougham",..: 49 36 231 14 161 141 54 223 241 2 ...
Auto1 <- Auto[,-9]
summary(Auto1)
## mpg cylinders displacement horsepower
## Min. : 9.00 Min. :3.000 Min. : 68.0 Min. : 46.0
## 1st Qu.:17.00 1st Qu.:4.000 1st Qu.:105.0 1st Qu.: 75.0
## Median :22.75 Median :4.000 Median :151.0 Median : 93.5
## Mean :23.45 Mean :5.472 Mean :194.4 Mean :104.5
## 3rd Qu.:29.00 3rd Qu.:8.000 3rd Qu.:275.8 3rd Qu.:126.0
## Max. :46.60 Max. :8.000 Max. :455.0 Max. :230.0
## weight acceleration year origin
## Min. :1613 Min. : 8.00 Min. :70.00 Min. :1.000
## 1st Qu.:2225 1st Qu.:13.78 1st Qu.:73.00 1st Qu.:1.000
## Median :2804 Median :15.50 Median :76.00 Median :1.000
## Mean :2978 Mean :15.54 Mean :75.98 Mean :1.577
## 3rd Qu.:3615 3rd Qu.:17.02 3rd Qu.:79.00 3rd Qu.:2.000
## Max. :5140 Max. :24.80 Max. :82.00 Max. :3.000
Проведем стандартизацию данных и создадим новый массив данных для дальнейшего исследования.
#стандартизация переменных
mpg1 <- (Auto1$mpg-mean(Auto1$mpg))/sd(Auto1$mpg)
cylinders1 <- (Auto1$cylinders-mean(Auto1$cylinders))/sd(Auto1$cylinders)
displacement1 <- (Auto1$displacement-mean(Auto1$displacement))/sd(Auto1$displacement)
horsepower1 <- (Auto1$horsepower-mean(Auto1$horsepower))/sd(Auto1$horsepower)
weight1 <- (Auto1$weight-mean(Auto1$weight))/sd(Auto1$weight)
acceleration1 <- (Auto1$acceleration-mean(Auto1$acceleration))/sd(Auto1$acceleration)
year1 <- (Auto1$year-mean(Auto1$year))/sd(Auto1$year)
origin1 <- (Auto1$origin-mean(Auto1$origin))/sd(Auto1$origin)
#собираем данные в новую матрицу
auto <- data.table(mpg1, cylinders1, displacement1, horsepower1, weight1, acceleration1, year1, origin1)
После стандартизации выполним анализ методом главных компонент.
#метод главных компонент
apply(auto, 2, mean)
## mpg1 cylinders1 displacement1 horsepower1 weight1
## 1.569283e-16 -9.915610e-17 -5.786680e-17 -1.767977e-16 -8.020330e-18
## acceleration1 year1 origin1
## -2.319512e-16 -1.271467e-15 1.321042e-16
apply(auto, 2, var)
## mpg1 cylinders1 displacement1 horsepower1 weight1
## 1 1 1 1 1
## acceleration1 year1 origin1
## 1 1 1
pr.out=prcomp(auto, scale=TRUE)
names(pr.out)
## [1] "sdev" "rotation" "center" "scale" "x"
pr.out$center
## mpg1 cylinders1 displacement1 horsepower1 weight1
## 1.554702e-16 -9.969350e-17 -5.836105e-17 -1.764373e-16 -8.903734e-18
## acceleration1 year1 origin1
## -2.321299e-16 -1.272013e-15 1.319806e-16
pr.out$scale
## mpg1 cylinders1 displacement1 horsepower1 weight1
## 1 1 1 1 1
## acceleration1 year1 origin1
## 1 1 1
pr.out$rotation
## PC1 PC2 PC3 PC4 PC5
## mpg1 0.3858624 0.07663269 -0.2922857863 0.09998251 -0.74036644
## cylinders1 -0.4023885 0.13842878 -0.0722393515 -0.21603551 -0.48261485
## displacement1 -0.4164443 0.12632499 -0.0742362247 -0.13581398 -0.30331627
## horsepower1 -0.4018359 -0.11148007 -0.2360557124 -0.11971643 0.08426839
## weight1 -0.4015758 0.21102000 0.0008939861 -0.32246785 0.13127292
## acceleration1 0.2647309 0.41690206 0.6394351361 -0.49280794 -0.09773197
## year1 0.2138678 0.69046320 -0.5871891991 -0.10601968 0.30134385
## origin1 0.2778682 -0.50150064 -0.3073238207 -0.74328281 0.04739508
## PC6 PC7 PC8
## mpg1 0.387351653 -0.19588516 -0.11513210
## cylinders1 -0.530925481 0.27878265 -0.41774679
## displacement1 -0.006997047 -0.08422855 0.82916553
## horsepower1 0.666709602 0.53504996 -0.13477548
## weight1 0.235859612 -0.72202073 -0.30991105
## acceleration1 0.202933431 0.22891382 0.03518826
## year1 -0.110025917 0.12501506 0.05428840
## origin1 -0.120866629 -0.03452660 0.07951102
dim(pr.out$x)
## [1] 392 8
biplot(pr.out, scale=0)
pr.out$rotation=-pr.out$rotation
pr.out$x=-pr.out$x
biplot(pr.out, scale=0)
pr.out$sdev
## [1] 2.3185927 0.9714233 0.9009127 0.6972488 0.4275822 0.3381153 0.2314019
## [8] 0.1788003
pr.var=pr.out$sdev^2
pr.var
## [1] 5.37587230 0.94366326 0.81164365 0.48615594 0.18282657 0.11432193
## [7] 0.05354682 0.03196954
pve=pr.var/sum(pr.var)
pve
## [1] 0.671984038 0.117957908 0.101455456 0.060769492 0.022853321 0.014290241
## [7] 0.006693352 0.003996192
plot(pve, xlab="Principal Component", ylab="Proportion of Variance Explained", ylim=c(0,1),type='b')
plot(cumsum(pve), xlab="Principal Component", ylab="Cumulative Proportion of Variance Explained", ylim=c(0,1),type='b')
После анализа получаем, что нам лучше оставить 2 первых главных компоненты, так как суммарно они объясняют около 80% всей дисперсии.
Выполним кластерный анализ методом k-средних.
km.out=kmeans(auto,2,nstart=20)
km.out$cluster
## [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 2 2 2 2 2 1 1 1 1 1 2 2 2 1 1 1
## [36] 1 1 1 1 1 1 1 1 1 1 2 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1
## [71] 2 1 1 1 1 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1
## [106] 1 1 2 2 2 2 2 1 2 1 1 2 2 2 2 1 2 2 1 1 1 1 2 2 2 2 1 1 1 1 1 1 1 1 2
## [141] 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 2 2 2 2 1 2 1
## [176] 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 1 2 2 2 2 1 1 1 1 2 2 2 2 2 1 2 2 1
## [211] 1 1 1 1 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [246] 2 2 1 1 1 1 2 2 2 1 1 1 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 1 2 1 2 2 1 2
## [281] 2 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 1 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1
## [316] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [351] 2 2 2 2 2 2 2 2 1 1 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2
## [386] 2 2 2 2 2 2 2
plot(auto, col=(km.out$cluster+1), main="K-Means Clustering Results with K=2", pch=20, cex=2)
km.out=kmeans(auto,3,nstart=20)
km.out$cluster
## [1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 3 3 3 1 1 1 1 1 1 3 2 2 2 2 1 3 1 3 3 3
## [36] 3 3 2 2 2 2 2 2 2 3 3 3 3 3 1 1 1 1 1 1 3 1 3 1 3 3 2 2 2 2 2 2 2 2 2
## [71] 1 2 2 2 2 3 1 3 1 3 1 1 3 1 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 1 2 2 2
## [106] 2 3 1 3 1 1 3 3 1 2 2 1 1 1 3 2 1 1 2 3 3 3 1 3 1 3 3 3 3 2 2 2 2 2 1
## [141] 1 1 1 1 1 1 1 1 1 1 3 3 3 3 2 2 2 2 3 3 3 3 3 2 2 1 3 3 3 1 1 1 3 1 3
## [176] 1 1 3 1 1 1 1 3 3 1 2 2 2 2 3 3 3 3 1 3 1 1 3 3 3 3 1 1 1 3 3 2 3 1 3
## [211] 2 2 2 2 1 1 1 3 1 2 3 2 2 3 3 3 3 2 2 2 2 1 3 1 3 1 1 1 1 1 1 1 1 1 1
## [246] 1 1 3 2 2 3 3 3 3 3 3 3 3 3 3 2 2 2 2 1 1 1 1 1 3 3 1 3 3 3 3 1 1 3 3
## [281] 3 3 3 2 2 2 2 2 2 2 2 1 1 1 3 3 2 1 3 1 1 1 1 3 3 3 1 1 1 1 1 3 3 3 3
## [316] 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1
## [351] 1 1 1 1 1 1 1 1 3 3 3 3 3 3 1 1 3 3 3 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 1
## [386] 1 3 3 1 1 3 3
plot(auto, col=(km.out$cluster+1), main="K-Means Clustering Results with K=3", pch=20, cex=2)
km.out=kmeans(auto,2,nstart=20)
km.out$tot.withinss
## [1] 1553.797
km.out=kmeans(auto,3,nstart=20)
km.out$tot.withinss
## [1] 1167.322
Проанализировав внутриклассовые дисперсии, приходим к выводу, что наиболее оптимальным является разбиение на 3 кластера с ядром равным 20.
Выполним иерархическую кластеризацию.
hc.complete=hclust(dist(auto), method="complete")
hc.average=hclust(dist(auto), method="average")
hc.single=hclust(dist(auto), method="single")
par(mfrow=c(1,3))
plot(hc.complete,main="Complete Linkage", xlab="", sub="", cex=.9)
plot(hc.average, main="Average Linkage", xlab="", sub="", cex=.9)
plot(hc.single, main="Single Linkage", xlab="", sub="", cex=.9)
par(mfrow=c(1,1))
cutree(hc.complete, 2)
## [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2
## [36] 2 2 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1
## [71] 2 1 1 1 1 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1
## [106] 1 2 2 2 2 2 2 2 2 1 1 2 2 2 2 1 2 2 1 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 2
## [141] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 1 1 2 2 2 2 2 2 2 2 2 2
## [176] 2 2 2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2
## [211] 1 1 1 1 2 2 2 2 2 1 2 1 1 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [246] 2 2 2 1 1 2 2 2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [281] 2 2 2 2 1 1 2 1 1 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [316] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [351] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [386] 2 2 2 2 2 2 2
cutree(hc.average, 2)
## [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 2 2 2 2 2 1 1 1 1 1 2 2 2 1 1 1
## [36] 1 1 1 1 1 1 1 1 1 1 2 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1
## [71] 2 1 1 1 1 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1
## [106] 1 1 2 2 2 2 2 1 2 1 1 2 2 2 2 1 2 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 1 1 2
## [141] 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 2 2 2 2 1 2 1
## [176] 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 2 2 2 2 1 1 1 1 2 2 2 2 2 1 2 1 1
## [211] 1 1 1 1 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 1 2 2 2 2 2
## [246] 2 2 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 1 2 1 2 2 1 1
## [281] 2 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 1 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1
## [316] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [351] 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [386] 2 2 2 2 2 2 2
cutree(hc.single, 2)
## [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
## [36] 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
## [71] 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
## [106] 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
## [141] 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
## [176] 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
## [211] 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
## [246] 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
## [281] 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
## [316] 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
## [351] 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 1 1
## [386] 1 1 1 1 1 1 1
cutree(hc.single, 4)
## [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [36] 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
## [71] 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
## [106] 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
## [141] 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
## [176] 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
## [211] 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
## [246] 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
## [281] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [316] 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
## [351] 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 4 1 1 1
## [386] 1 1 1 1 1 1 1
xsc=scale(auto)
plot(hclust(dist(xsc), method="complete"), main="Hierarchical Clustering with Scaled Features")
Из всех вариантов остановимся на 2 кластерах, полученных методами дальнего соседа и средней связи.