1. 程式人生 > 其它 >16--劃分聚類分析(K 均值聚類、圍繞中心點的劃分(PAM))

16--劃分聚類分析(K 均值聚類、圍繞中心點的劃分(PAM))

1 劃分聚類分析

1.1 K 均值聚類

最常見的劃分方法是K均值聚類分析。從概念上講,K均值演算法如下:

(1) 選擇K箇中心點(隨機選擇K行);

(2) 把每個資料點分配到離它最近的中心點;

(3) 重新計算每類中的點到該類中心點距離的平均值(也就說,得到長度為p的均值向量這裡的p是變數的個數);

(4) 分配每個資料到它最近的中心點;

(5) 重複步驟(3)和步驟(4)直到所有的觀測值不再被分配或是達到最大的迭代次數(R10次作為預設迭代次數)。

R軟體使用Hartigan & Wong1979)提出的有效演算法,這種演算法是把觀測值分成k組並使得觀測值到其指定的聚類中心的平方的總和為最小。

K均值聚類能處理比層次聚類更大的資料集。在RK均值的函式格式是kmeans(x,centers),這裡x表示數值資料集(矩陣或資料框),centers是要提取的聚類數目。函式返回類的成員、類中心、平方和(類內平方和、類間平方和、總平方和)和類大小。

由於K均值聚類在開始要隨機選擇k箇中心點,在每次呼叫函式時可能獲得不同的方案。使用set.seed()函式可以保證結果是可複製的。此外,聚類方法對初始中心值的選擇也很敏感。

kmeans()函式有一個nstart選項嘗試多種初始配置並輸出最好的一個。例如,加上nstart=25會生成25個初始配置。通常推薦使用這種方法。

不像層次聚類方法,K均值聚類要求你事先確定要提取的聚類個數。同樣,

NbClust包可以用來作為參考。另外,在K均值聚類中,類中總的平方值對聚類數量的曲線可能是有幫助的。可根據圖中的彎曲選擇適當的類的數量。

影象可以用下面的程式碼產生:

wssplot<-function(data,nc=15,seed=123){

wss<-(nrow(data)-1)*sum(apply(data, 2, var))

for (i in 2:nc){

set.seed(seed)

wss[i]<-sum(kmeans(data,centers = i)$withiness)}

plot(1:nc,wss,type="b",xlab="Number of Clusters",

ylab="within groups sum of squares")}

data引數是用來分析的數值資料,nc是要考慮的最大聚類個數,而seed是一個隨機數種子。

K均值聚類來處理包含178種義大利葡萄酒中13種化學成分的資料集。該資料最初來自於UCI機器學習庫(http://www.ics.uci.edu/~mlearn/MLRepository.html),但是可以通過rattle

包獲得。在這個資料集裡,觀測值代表三種葡萄酒的品種,由第一個變數(型別)表示。

1)葡萄酒資料的K均值聚類:

data(wine, package="rattle")

head(wine)

df <- scale(wine[-1]) #標準化資料,均值未0,方差為1

wssplot(df)

結果分析:畫出組內的平方和和提取的聚類個數的對比。從一類到三類下降得很快(之後下降得很慢),建議選用聚類個數為二、三的解決方案。

library(NbClust)

set.seed(1234)

devAskNewPage(ask=TRUE)

nc <- NbClust(df, min.nc=2, max.nc=15, method="kmeans")

結果分析:左圖表示從一類到三類變化時,組內的平方總和有一個明顯的下降趨勢。三類之後,下降的速度減弱,暗示著聚成三類可能對資料來說是一個很好的擬合。

table(nc$Best.n[1,])#檢視分組支援數

結果分析:這裡,19個評判準則贊同聚類個數為32個判定準則贊同聚類個數為2,等等。

barplot(table(nc$Best.n[1,]), #分組支援數視覺化

xlab="Number of Clusters", ylab="Number of Criteria",

main="Number of Clusters Chosen by 26 Criteria")

結果分析:使用NbClust包中的26個指標推薦的聚類個數,可以看到聚為3類擁有最多的支援數。

set.seed(1234)

fit.km <- kmeans(df, 3, nstart=25) #進行K均值聚類分析

fit.km$size#檢視聚成三類後,每類有多少變數

檢視標準化之後資料據的維度,有178行,13列

fit.km$centers#檢視聚類的中心

aggregate(wine[-1], by=list(cluster=fit.km$cluster), mean) #使用aggregate()函式和類的成員來得到原始矩陣中每一類的變數均值

交叉列表型別(葡萄酒品種)和類成員由下面的程式碼表示:

ct.km <- table(wine$Type, fit.km$cluster)

ct.km

可以用flexclust包中的蘭德指數(Rand index)來量化型別變數和類之間的協議:

library(flexclust)

randIndex(ct.km)

結果分析:調整的蘭德指數為兩種劃分提供了一種衡量兩個分割槽之間的協定,即調整後機會的量度。它的變化範圍是從1(不同意)到1 (完全同意)。葡萄酒品種型別和類的解決方案之間的協定約等於0.9,結果不壞。

1.2 圍繞中心點的劃分

因為K均值聚類方法是基於均值的,所以它對異常值是敏感的。一個更穩健的方法是圍繞中

心點的劃分(PAMK均值聚類一般使用歐幾里得距離,而PAM可以使用任意的距離來計算。

PAM演算法如下:

(1) 隨機選擇K個觀測值(每個都稱為中心點);

(2) 計算觀測值到各個中心的距離/相異性;

(3) 把每個觀測值分配到最近的中心點;

(4) 計算每個中心點到每個觀測值的距離的總和(總成本);

(5) 選擇一個該類中不是中心的點,並和中心點互換;

(6) 重新把每個點分配到距它最近的中心點;

(7) 再次計算總成本;

(8) 如果總成本比步驟(4)計算的總成本少,把新的點作為中心點;

(9) 重複步驟(5)(8)直到中心點不再改變。

可以使用cluster包中的pam()函式使用基於中心點的劃分方法。格式如下:

pam(x, k, metric="euclidean", stand=FALSE)

x表示資料矩陣或資料框,k表示聚類的個數,metric表示使用的相似性/相異性的度量,而stand是一個邏輯值,表示是否有變數應該在計算該指標之前被標準化。

1對葡萄酒資料使用基於質心的劃分方法

library(cluster)

set.seed(1234)

fit.pam <- pam(wine[-1], k=3, stand=TRUE) #聚類資料的標準化

fit.pam$medoids #輸出中心點

結果分析:這裡得到的中心點是葡萄酒資料集中實際的觀測值。

clusplot(fit.pam, main="Bivariate Cluster Plot")#畫出聚類方案

PAM在如下例子中的表現不如K均值:

ct.pam <- table(wine$Type, fit.pam$clustering)

ct.pam

randIndex(ct.pam)

結果分析:flexclust包中的蘭德指數(Rand index)來量化型別變數和類之間的協議,調整的蘭德指數為兩種劃分提供了一種衡量兩個分割槽之間的協定,即調整後機會的量度。它的變化範圍是從–1(不同意)到1 (完全同意)。葡萄酒品種型別和類的解決方案之間的協定約等於0.7,結果沒有很好。

本文來自部落格園,作者:zhang-X,轉載請註明原文連結:https://www.cnblogs.com/YY-zhang/p/15138191.html