聚類距離
聚類分析的距離就是將相似(相異)的數據看成是對象之間距離遠近的一種度量,其目的就是讓類群內觀測的距離最近,而不同群體之間的距離最遠。
絕對值距離
也叫做“城市街區”或“棋盤距離”
歐幾里得距離(Euclid)
通常意義下的距離,默認使用
閔可夫斯基距離(Minkowski)
絕對值距離和歐氏距離是閔式距離的特例情況
切比雪夫距離(Chebyshew)
是閔式距離中 q 趨近于無窮大的情況
系統聚類法
系統聚類,也叫層次聚類,它的核心就是每一個觀測值首先自成一類,然后將距離最近的類兩兩合并成為一個新類,重復多次合并,直到所有的類被聚成一類。
最短距離法,兩個類之間樣本的最短距離
最長距離法,兩個類之間樣本的最遠距離
類平均法,一個類中的點和另一個類中的點的平均距離
重心法,類之間的重心(變量均值)之間的距離
Ward方法,兩個類之間所有變量的方差分析的平方和
劃分聚類法
劃分聚類又稱為逐步聚類法,基本的思想就是,首先粗略的分一下類,然后按照某種最優原則修改分類,直到最終分類合理。這種方法的計算量較小,占用內存較少,計算效率高且方法簡單。 最常見的劃分聚類的方法是 k-means 均值聚類分析。這里我們列出它的基本算法如下: (1)隨機選擇 K 個中心點 (2)將每個數據值點分配給相應最近的中心點 (3)重新計算每一類中的各個點到中心點的距離的平均值 (4)再次分配每個數據點給最近的中心點 (5)重復步驟 (3)和(4),直到所有的點達到最大迭代次數 由于 K 均值是基于均值的,所以它對異常值比較敏感,而基于中心的劃分聚類法(k-medoids 法)顯示出更加穩健,相較于 K 均值法一般使用歐氏距離來說,k-medoids 法中的 PAM 函數則可以調用任意的距離公式來計算。所以 PAM 方法可以容納混合的數據類型,而不僅限于連續變量。
模型對比
系統聚類,能夠展現數據層次結構,易于理解,可以基于層次再選擇類的個數(根據數據選擇類,但是數據量大,速度慢),計算量比較大,不適合樣本量大的情形,較多用于宏觀綜合評價
劃分聚類,屬于快速聚類,計算效率高,需要實現指定類的個數(需要指定類),有時會不穩定,陷入局部收斂
數據獲取
從實驗平臺上讀取實驗數據,數據來源是國家統計局,數據是 2010 年 31 個省份城鎮居民家庭人均消費支出的統計值。
options(stringsAsFactors=F)
coms <- readLines("http://labfile.oss.aliyuncs.com/courses/908/comsume.csv")
coms <- unlist(strsplit(coms, split=","))
coms <- as.data.frame(matrix(coms, ncol=10, byrow=T))
colnames(coms) <- coms[1,]
coms <- coms[-1,]
row_names <- coms[,1]
coms <- coms[,-1]
coms <- as.data.frame(sapply(coms, as.numeric))
rownames(coms) <- row_names
數據整理
使用 scale函數對數據矩陣做中心化和標準化變換。
> coms.scale <- scale(coms)
使用 dist來計算距離。其中 x 是樣本矩陣或者數據框。method 表示計算哪種距離。在本實驗中采用的均是歐幾里得距離,簡稱歐氏距離。
> d <- dist(coms.scale, method="euclidean")
系統聚類法
系統聚類(或叫層次聚類)的方法主要是由 hclust函數實現,method 的方法包括 “single”、“complete”、“average”、“centroid” 和 “ward”。
最短距離法(single)
> data.single <- hclust(d, method="single")
> plot(data.single, hang=-1, cex=.8, main="Single Linkage Clustering")
最長距離法(complete)
> data.complete <- hclust(d, method="complete")
> plot(data.complete, hang=-1, cex=.8, main="Complete Linkage Clustering")
類平均法(average)
> data.average <- hclust(d, method="average")
> plot(data.average, hang=-1, cex=.8, main="Average Linkage Clustering")
重心法(centroid)
> data.centroid <- hclust(d, method="centroid")
> plot(data.centroid, hang=-1, cex=.8, main="Centroid Linkage Clustering")
離差平方和法(ward 法)
> data.ward <- hclust(d, method="ward.D")
> plot(data.ward, hang=-1, cex=.8, main="Ward Linkage Clustering")
選擇聚類個數
NbClust 這個包提供了眾多指數來確定在一個聚類分析里的最佳數目,雖然不能保證所有指標的結果相同,但是這也不失為一種參考。
> library(NbClust)
> devAskNewPage(ask=T)
> nc <- NbClust(coms.scale, distance="euclidean", min.nc=2, max.nc=15, method="average")
Hit <Return> to see next plot:
> table(nc$Best.n[1,])
0 2 3 4 5 7 9 10 11 15
2 7 5 3 3 1 1 1 2 1
類似于“投票”個數,NbClust 包中的26 個評判準則贊同數最多的聚類個數是 2,其次是 3 ,接著是 4 和 5 。
> barplot(table(nc$Best.n[1,]), xlab="Number of Clustering", ylab="Number of Criteria", main="Number of Clusters Chosen by 26 Criteria")
獲取最終聚類方法
用 cutree 函數將樹狀圖分為 2 類(先選用評判準則推薦數)
> clusters <- cutree(data.average, k=2)
> table(clusters)
clusters
1 2
5 26
通過 aggregate 函數獲取每一類的中位數,采用的是標準度量 (coms.scale) 的形式。
> aggregate(as.data.frame(coms.scale), by=list(cluster=clusters), median)
cluster 城鎮居民家庭人均現金消費支出(元)
1 1 1.7310408
2 2 -0.4160258
城鎮居民家庭人均食品消費支出(元) 城鎮居民家庭人均衣著消費支出(元)
1 1.6341314 1.1998430
2 -0.3451563 -0.3956246
城鎮居民家庭人均居住消費支出(元)
1 1.2023829
2 -0.2386753
城鎮居民家庭人均家庭設備及用品消費支出(元)
1 1.3138472
2 -0.4543204
城鎮居民家庭人均醫療保健消費支出(元)
1 0.8466638
2 -0.2979085
城鎮居民家庭人均交通和通信消費支出(元)
1 2.0493731
2 -0.5555593
城鎮居民家庭人均文教娛樂服務消費支出(元)
1 1.775012
2 -0.392895
城鎮居民家庭人均其它消費支出(元)
1 1.0778945
2 -0.3627564
通過 rect.hclust() 函數將樹狀圖重新繪制,得出最終的聚類解決方法。
> plot(data.average, hang=-1, cex=.8, main="Average Linkage Clustering\n5 Cluster Solution")
> rect.hclust(data.average, k=2)
從圖中可能并沒有得到一個滿意的聚類方法,因為評判準則推薦的聚類數2過于粗略,因此可根據自己的判斷進行重新聚類。
劃分聚類法
K-Means 均值法
為了消除量級的影響,采用的數據是進過標準化處理過后的數據,通過調用 kmeans 函數進行劃分聚類,類的個數選擇的是 5 個,算法默認選擇 Hartigan-Wong。
> km <- kmeans(coms.scale, 5, nstart=20)
> km
K-means clustering with 5 clusters of sizes 4, 13, 7, 1, 6
Cluster means:
城鎮居民家庭人均現金消費支出(元)
1 1.6467834
2 -0.5242398
3 -0.6875210
4 3.1562770
5 0.3140589
城鎮居民家庭人均食品消費支出(元)
1 1.5472740
2 -0.6677726
3 -0.2339480
4 2.9226560
5 0.2011548
城鎮居民家庭人均衣著消費支出(元)
1 0.8217448
2 -0.1055786
3 -1.1258935
4 1.1998430
5 0.7944923
城鎮居民家庭人均居住消費支出(元)
1 1.2626311
2 -0.3091093
3 -0.9212548
4 3.0003585
5 0.4027202
城鎮居民家庭人均家庭設備及用品消費支出(元)
1 1.1235531
2 -0.4051740
3 -0.7193372
4 3.4593421
5 0.3915114
城鎮居民家庭人均醫療保健消費支出(元)
1 1.32527086
2 0.01625638
3 -1.19385371
4 0.72146236
5 0.35384954
城鎮居民家庭人均交通和通信消費支出(元)
1 1.74585670
2 -0.59338532
3 -0.36428352
4 2.88597319
5 0.06576562
城鎮居民家庭人均文教娛樂服務消費支出(元)
1 1.5404023
2 -0.4105722
3 -0.7680925
4 3.0305706
5 0.2536510
城鎮居民家庭人均其它消費支出(元)
1 1.0548462
2 -0.3150703
3 -0.7814860
4 3.8807792
5 0.2443586
Clustering vector:
北京市 天津市 河北省
1 1 2
山西省 內蒙古自治區 遼寧省
2 5 5
吉林省 黑龍江省 上海市
2 2 4
江蘇省 浙江省 安徽省
5 1 2
福建省 江西省 山東省
5 3 5
河南省 湖北省 湖南省
2 2 2
廣東省 廣西壯族自治區 海南省
1 3 3
重慶市 四川省 貴州省
5 2 3
云南省 西藏自治區 陜西省
3 3 2
甘肅省 青海省 寧夏回族自治區
2 3 2
新疆維吾爾自治區
2
Within cluster sum of squares by cluster:
[1] 13.55936 16.90677 12.31074 0.00000 15.07624
(between_SS / total_SS = 78.6 %)
Available components:
[1] "cluster" "centers" "totss"
[4] "withinss" "tot.withinss" "betweenss"
[7] "size" "iter" "ifault"
為了便于查看聚類后的情況,可以通過 sort 函數進行排序。
> sort(km$cluster)
北京市 天津市 浙江省
1 1 1
廣東省 河北省 山西省
1 2 2
吉林省 黑龍江省 安徽省
2 2 2
河南省 湖北省 湖南省
2 2 2
四川省 陜西省 甘肅省
2 2 2
寧夏回族自治區 新疆維吾爾自治區 江西省
2 2 3
廣西壯族自治區 海南省 貴州省
3 3 3
云南省 西藏自治區 青海省
3 3 3
上海市 內蒙古自治區 遼寧省
4 5 5
江蘇省 福建省 山東省
5 5 5
重慶市
5
畫出聚類后的圖像
> plot(coms.scale, col=km$cluster)
> points(km$centers, col=1:5, pch=8, cex=2)
k-medoids 聚類
> library(cluster)
> coms.result <- pam(coms, 5, stand=T)
> coms.result
Medoids:
ID 城鎮居民家庭人均現金消費支出(元)
天津市 2 16561.8
湖南省 18 11825.3
青海省 29 9613.8
遼寧省 6 13280.0
上海市 9 23200.4
城鎮居民家庭人均食品消費支出(元)
天津市 5940.4
湖南省 4322.1
青海省 3784.8
遼寧省 4658.0
上海市 7777.0
城鎮居民家庭人均衣著消費支出(元)
天津市 1567.6
湖南省 1277.5
青海省 1185.6
遼寧省 1586.8
上海市 1794.1
城鎮居民家庭人均居住消費支出(元)
天津市 1615.6
湖南省 1182.3
青海省 923.5
遼寧省 1314.8
上海市 2166.2
城鎮居民家庭人均家庭設備及用品消費支出(元)
天津市 1119.9
湖南省 903.8
青海省 644.0
遼寧省 785.7
上海市 1800.2
城鎮居民家庭人均醫療保健消費支出(元)
天津市 1275.6
湖南省 776.9
青海省 718.8
遼寧省 1079.8
上海市 1005.5
城鎮居民家庭人均交通和通信消費支出(元)
天津市 2454.4
湖南省 1541.4
青海省 1116.6
遼寧省 1773.3
上海市 4076.5
城鎮居民家庭人均文教娛樂服務消費支出(元)
天津市 1899.5
湖南省 1418.9
青海省 908.1
遼寧省 1495.9
上海市 3363.3
城鎮居民家庭人均其它消費支出(元)
天津市 688.7
湖南省 402.5
青海省 332.5
遼寧省 585.8
上海市 1217.7
Clustering vector:
北京市 天津市 河北省
1 1 2
山西省 內蒙古自治區 遼寧省
3 4 4
吉林省 黑龍江省 上海市
4 3 5
江蘇省 浙江省 安徽省
2 1 2
福建省 江西省 山東省
2 2 4
河南省 湖北省 湖南省
2 2 2
廣東省 廣西壯族自治區 海南省
1 2 3
重慶市 四川省 貴州省
4 2 3
云南省 西藏自治區 陜西省
3 3 2
甘肅省 青海省 寧夏回族自治區
3 3 2
新疆維吾爾自治區
3
Objective function:
build swap
1.867907 1.867907
Available components:
[1] "medoids" "id.med" "clustering" "objective"
[5] "isolation" "clusinfo" "silinfo" "diss"
[9] "call" "data"
> summary(coms.result)
Medoids:
ID 城鎮居民家庭人均現金消費支出(元)
天津市 2 16561.8
湖南省 18 11825.3
青海省 29 9613.8
遼寧省 6 13280.0
上海市 9 23200.4
城鎮居民家庭人均食品消費支出(元)
天津市 5940.4
湖南省 4322.1
青海省 3784.8
遼寧省 4658.0
上海市 7777.0
城鎮居民家庭人均衣著消費支出(元)
天津市 1567.6
湖南省 1277.5
青海省 1185.6
遼寧省 1586.8
上海市 1794.1
城鎮居民家庭人均居住消費支出(元)
天津市 1615.6
湖南省 1182.3
青海省 923.5
遼寧省 1314.8
上海市 2166.2
城鎮居民家庭人均家庭設備及用品消費支出(元)
天津市 1119.9
湖南省 903.8
青海省 644.0
遼寧省 785.7
上海市 1800.2
城鎮居民家庭人均醫療保健消費支出(元)
天津市 1275.6
湖南省 776.9
青海省 718.8
遼寧省 1079.8
上海市 1005.5
城鎮居民家庭人均交通和通信消費支出(元)
天津市 2454.4
湖南省 1541.4
青海省 1116.6
遼寧省 1773.3
上海市 4076.5
城鎮居民家庭人均文教娛樂服務消費支出(元)
天津市 1899.5
湖南省 1418.9
青海省 908.1
遼寧省 1495.9
上海市 3363.3
城鎮居民家庭人均其它消費支出(元)
天津市 688.7
湖南省 402.5
青海省 332.5
遼寧省 585.8
上海市 1217.7
Clustering vector:
北京市 天津市 河北省
1 1 2
山西省 內蒙古自治區 遼寧省
3 4 4
吉林省 黑龍江省 上海市
4 3 5
江蘇省 浙江省 安徽省
2 1 2
福建省 江西省 山東省
2 2 4
河南省 湖北省 湖南省
2 2 2
廣東省 廣西壯族自治區 海南省
1 2 3
重慶市 四川省 貴州省
4 2 3
云南省 西藏自治區 陜西省
3 3 2
甘肅省 青海省 寧夏回族自治區
3 3 2
新疆維吾爾自治區
3
Objective function:
build swap
1.867907 1.867907
Numerical information per cluster:
size max_diss av_diss diameter separation
[1,] 4 4.228761 2.808394 4.921966 3.609082
[2,] 12 3.438325 1.734727 4.931835 1.319385
[3,] 9 3.168900 1.881147 4.833101 1.319385
[4,] 5 2.921007 1.784901 3.631708 1.852737
[5,] 1 0.000000 0.000000 0.000000 5.642691
Isolated clusters:
L-clusters: character(0)
L*-clusters: character(0)
Silhouette plot information:
cluster neighbor sil_width
廣東省 1 4 0.384426204
浙江省 1 4 0.273987209
北京市 1 5 0.216066065
天津市 1 4 0.111089995
湖南省 2 3 0.363302374
四川省 2 3 0.286014541
湖北省 2 3 0.260832464
安徽省 2 3 0.226162095
寧夏回族自治區 2 4 0.166634900
陜西省 2 4 0.162060575
河南省 2 3 0.132284283
福建省 2 4 0.090919045
廣西壯族自治區 2 3 0.081965348
河北省 2 3 0.042007432
江西省 2 3 -0.006777434
江蘇省 2 4 -0.032022384
青海省 3 2 0.292361741
西藏自治區 3 2 0.244563997
云南省 3 2 0.222421437
甘肅省 3 2 0.219584082
貴州省 3 2 0.217680263
新疆維吾爾自治區 3 2 0.126063641
海南省 3 2 0.070171522
山西省 3 2 0.011027726
黑龍江省 3 2 -0.075325647
內蒙古自治區 4 2 0.369302778
遼寧省 4 2 0.288186152
重慶市 4 2 0.212660109
吉林省 4 2 0.167825669
山東省 4 2 0.152252464
上海市 5 1 0.000000000
Average silhouette width per cluster:
[1] 0.2463924 0.1477819 0.1476165 0.2380454 0.0000000
Average silhouette width of total data set:
[1] 0.1702493
465 dissimilarities, summarized :
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.9889 2.6669 3.9286 4.8799 6.2731 16.0050
Metric : euclidean
Number of objects : 31
Available components:
[1] "medoids" "id.med" "clustering" "objective"
[5] "isolation" "clusinfo" "silinfo" "diss"
[9] "call" "data"
> plot(coms.result$data, col=coms.result$clustering)