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,結果沒有很好。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM