聚類分析(Cluster analysis)是一種數(shù)據(jù)歸約技術(shù)驻龟,旨在揭露一個數(shù)據(jù)集中觀測值的子集亿笤;關(guān)于“類”的概念是指由若干個觀測值組成的群組萝玷。所謂聚類分析就是把大量的觀測值歸約為若干個類,群組內(nèi)的觀測值間的相似度比群間的觀測相似度高卫漫。常用的聚類方法有層次聚類帅刀、劃分聚類让腹,下面一起來學習吧~
層次聚類 hierarchical agglomerative clustering
1远剩、基本概念
- 特征: 起初定義每一個觀測值屬于一類;聚類就是每一次把兩類聚成新的一類骇窍,直到所有的類聚成單個類為止瓜晤。
- 適用范圍:對于小樣本來說很實用(150個觀測以下)
- 聚類算法:常見的算法有 單聯(lián)動(single)、全聯(lián)動(complete)腹纳、平均聯(lián)動(average)痢掠、質(zhì)心(centroid),Ward法嘲恍。常用的是平均聯(lián)動
2足画、算法步驟
(1)定義每一個觀測值為一類;
(2)計算每一類和其它各類的距離佃牛;
- 不同算法都需要首先計算被聚類的實體之間的距離淹辞;
- 每個觀測值之間常用的距離量度是歐幾里得距離(針對連續(xù)型變量),例見p345俘侠;
- 由于觀測的變量性質(zhì)不同象缀,對距離的貢獻可能差異很大,因此兼贡,需要對各變量做歸一化處理(均值為0攻冷,標準差為1)
(3)把“距離”最短的兩類合并成一類娃胆,這樣類的個數(shù)就減少一個遍希;
- 這里的“距離”應(yīng)該不是指第二步直接的歐幾里得距離,而是涉及的算法距離里烦。
- 不同算法主要區(qū)別就是兩類之間的距離定義不同凿蒜。(詳見p346)
(4)重復(fù)步驟1和步驟2,直到包含所有觀測值的類合并成單個類為止胁黑。
3废封、實驗示例
基于5種營養(yǎng)標準含量(變量)的27種食物(觀測)進行層次聚類分析,探索不同食物的相同點與不同點丧蘸,并分成有意義的類漂洋。此處層次聚類算法以平均聯(lián)動(average)為例。
注意力喷!在選擇變量時刽漂,一定要慎重。要選擇可能對識別和理解數(shù)據(jù)中不同觀測值分組有重要影響的變量弟孟。~以免“爛泥扶不上墻”~
(1)數(shù)據(jù)預(yù)處理--歸一化
par(ask=TRUE)
opar <- par(no.readonly=FALSE)
data(nutrient, package="flexclust") #加載數(shù)據(jù)包
head(nutrient, 10)
#可以看出energy這一列的數(shù)值差異很大贝咙,十分影響后幾個變量的貢獻,因此需要歸一化拂募。
nutrient.scaled <- scale(nutrient)
head(nutrient.scaled, 10)
#這樣就舒服很多了
(2)計算歐幾里得距離
d <- dist(nutrient.scaled)
#好像dist還是專門的一種儲存格式
as.matrix(d)[1:4,1:4]
#局部查看一下
(3)平均聯(lián)動層次聚類分析
fit.average <- hclust(d, method="average")
plot(fit.average, hang=-1, cex=.8, main="Average Linkage Clustering")
#繪樹狀圖圖庭猩,聚類可視化窟她。
-
hang=-1
設(shè)定展示觀測值標簽的位置; - 樹狀圖高度刻度代表了該高度(距離)類之間合并判定值--
如圖注釋:(1)首先是beef braised與smoked ham的最先合并(它們最矮--距離最近)蔼水;
(2)然后是pork roast 和 pork simmered 的合并(重新計算距離后的最相近的點震糖,下同);
(3)其次為chicken canned 和 tuna canned的合并趴腋;
(4)再然后是beef braised/smoked ham的類與pork roast/pork simmered的類的兩小類的合并试伙;
.............
最后是sardines canned 與一個大類的合并。
上圖已經(jīng)足夠我們理解27種食物基于營養(yǎng)成分的相似性與差異性于样,也可進行深入的分析:將27種食物分為較少的疏叨、有意義的類〈┢剩基于此蚤蔓,做如下分析步驟:
(1)確定聚類個數(shù)
NbClust包提供了眾多的指數(shù)來確定在一個聚類分析里類的最佳數(shù)目。
library(NbClust)
nc <- NbClust(nutrient.scaled, distance="euclidean",
min.nc=2, max.nc=15, method="average")
#直接返回的結(jié)論推薦為2
- 提供的數(shù)據(jù)仍為歸一化后的數(shù)據(jù)糊余;
- distance="euclidean"交代距離量度為歐幾里得方法秀又;
- min.nc與max.nc設(shè)置可考慮的最小和最大聚類數(shù);
- method交代層次聚類算法。
par(opar)
table(nc$Best.n[1,])
#分別各有四個評判準則贊同聚類個數(shù)為2贬芥、3吐辙、5、15
barplot(table(nc$Best.n[1,]),
xlab="Numer of Clusters", ylab="Number of Criteria",
main="Number of Clusters Chosen by 26 Criteria")
#將上述結(jié)果繪制成柱狀圖蘸劈。
最終的決策聚類方案可以均試一試昏苏,選擇一個最具有解釋意義的聚類方案。下面以聚類數(shù)為5威沫,演示一下贤惯。(后來自己做了一下聚類數(shù)為2的結(jié)果,可能理解了教材為什么不用2的原因了棒掠;就是樹狀圖最左邊的那個食物單分成了一類...)
(2)獲取最終的聚類方案
- 利用cutree()函數(shù)把樹狀圖分成5類(砍樹.......)
clusters <- cutree(fit.average, k=5)
- 查看5種小類的觀測數(shù)目
table(clusters)
- 觀察5種類的變量平均水平孵构,分別為原水平、歸一化后的水平
aggregate(nutrient, by=list(cluster=clusters), median)
aggregate(as.data.frame(nutrient.scaled), by=list(cluster=clusters),
median)
- 可視化聚類方案
plot(fit.average, hang=-1, cex=.8,
main="Average Linkage Clustering\n5 Cluster Solution")
rect.hclust(fit.average, k=5)
由上圖烟很,嘗試解釋每類變量的含義:
- sardines canned 單獨生成一類颈墅,因為鈣的含量多;
- beef heart 單獨生成一類雾袱,因為富含蛋白質(zhì)和鐵恤筛;
- clams類是低蛋白和高鐵的;
- 另一較小類都是高能量和高脂肪的食物谜酒;
- 最大的一類均含有相對較低的鐵叹俏。
劃分聚類分析 partitioning clustering
1、基本概念
- 特征:首先指定類的個數(shù)K僻族,然后觀測值被隨機分成K類粘驰,再重新形成聚合的類屡谐。
- 適用范圍:大樣本觀測(成百上千)
- 算法:K均值、基于中心點的劃分(PAM)
實驗示例為178種意大利葡萄酒(觀測)的13種化學成分含量數(shù)據(jù)(變量)蝌数。其實是3類葡萄酒愕掏,但是我們假裝不知道,看能否分析出來顶伞,并且比較兩種算法(K均值與PAM)的結(jié)果差異饵撑。
2、K均值聚類
K均值聚類為最常見的劃分方法唆貌。
2.1滑潘、算法步驟
(1)選擇K個中心點(隨機選擇K個觀測),K數(shù)值就是我們預(yù)期的聚類數(shù)锨咙。
(2)把每個數(shù)據(jù)點分配給離它最近的中心點语卤;第一次中心點是隨機選擇的,但也可以設(shè)置參數(shù)酪刀,選擇最優(yōu)的初始值粹舵。
(3)重新計算每類中的點到該類中心點距離的平均值;此時的中心點應(yīng)該為每一類的均值中心點骂倘,對異常值敏感(之后都是如此)
(4)分配每個數(shù)據(jù)到它最近的中心點眼滤;
(5)重復(fù)步驟3、4历涝,直到所有的觀測值不在被分配或是達到最大的迭代次數(shù)(默認10次)
2.2诅需、實驗演算
(1)數(shù)據(jù)預(yù)處理:去除第一列干擾數(shù)據(jù),并歸一化數(shù)據(jù)睬关。
data(wine, package="rattle")
head(wine)
df <- scale(wine[-1])
(2)確定待提取的聚類個數(shù)诱担,同樣可用NbClust包判斷(順序與層次聚類分析不同,如前所述电爹,層次聚類分析在最后才確定聚類個數(shù))
library(NbClust)
set.seed(1234)
nc <- NbClust(df, min.nc=2, max.nc=15, method="kmeans")
par(opar)
table(nc$Best.n[1,])
barplot(table(nc$Best.n[1,]),
xlab="Numer of Clusters", ylab="Number of Criteria",
main="Number of Clusters Chosen by 26 Criteria")
因為K值分析在開始時,要隨機選擇K個中心點料睛,每次可能獲得稍有差異的方案丐箩。使用
set.seed()
可以保證結(jié)果可復(fù)制。
此外恤煞,在K均值聚類中屎勘,類中總的平方值對聚類數(shù)量的曲線可能對確定聚類數(shù)量是有幫助的,詳見p351
(3)K均值聚類分析
set.seed(1234)
fit.km <- kmeans(df, 3, nstart=25)
由于聚類方法對初始中心值的選擇很敏感居扒,
nstart=
參數(shù)允許嘗試多種初始配置并輸出最好的一個概漱。比如上例,會生成25個初始配置喜喂。
fit.km$size
#三類所包含的樣本數(shù)
fit.km$centers
#各類中心值(歸一化后的數(shù)據(jù))
aggregate(wine[-1], by=list(cluster=fit.km$cluster), mean)
#還原數(shù)據(jù)
(4)最后將聚類結(jié)果與原始數(shù)據(jù)標準結(jié)果(第一列數(shù)據(jù))進行比對瓤摧,看看分析質(zhì)量如何竿裂。
- 通過flexclust包的蘭德指數(shù)評價,變化范圍從-1(完全不同意)到1(完全同意)
ct.km <- table(wine$Type, fit.km$cluster)
ct.km
library(flexclust)
randIndex(ct.km)
蘭德指數(shù)接近0.9照弥,看來K均值聚類算法還不錯~
3腻异、基于中心點的劃分(PAM)
K均值法對均值異常敏感,相比來說这揣,PAM為更穩(wěn)健的方法悔常。
3.1、算法步驟
(1)隨機選擇K個觀測(每個都稱為中心點)给赞;
(2)計算觀測值到各個中心的距離机打;
(3)把每個觀測值分配到最近的中心點;
(4)計算每個中心點到每個觀測值的距離的總和(總成本)片迅;
(5)選擇一個該類中不是中心的點姐帚,并和中心點互換;
(6)重新把每個點分配到距它最近的中心點障涯;
(7)再次計算總成本罐旗;
(8)若新的總成本比步驟4計算的總成本少,就把新的點作為中心點唯蝶;
(9)重復(fù)步驟5-8九秀,直到中心點不變。
3.2粘我、實驗演算
- 基于上述2.2鼓蜒,判斷聚類數(shù)為3后的基礎(chǔ)上,進行分析
library(cluster)
set.seed(1234)
fit.pam <- pam(wine[-1], k=3, stand=TRUE)
# 進行PAM分析
fit.pam$medoids
# 查看各類中心值
fit.pam$id.med
# 查看各類觀測數(shù)
clusplot(fit.pam, main="Bivariate Cluster Plot")
# 聚類可視化
- 最后計算下蘭德指數(shù)征字,0.7左右都弹,看來不比K均值法~
ct.pam <- table(wine$Type, fit.pam$clustering)
ct.pam
randIndex(ct.pam)
由于聚類分析有時也能分析出原本肯定不存在的類,因此需要驗證(立方聚類規(guī)則匙姜,見p356)畅厢。此外,要想對自己的聚類結(jié)果更自信氮昧,可以嘗試不同的聚類方法框杜,若同一類持續(xù)復(fù)原,那么就增加了把握~~~
以上就是聚類分析的R語言學習袖肥,參考教材《R語言實戰(zhàn)(第2版)》