在實際的聚類應用中,通常使用k-均值和k-中心化算法來進行聚類分析,這兩種算法都需要輸入簇數,為了保證聚類的質量,應該首先確定最佳的簇數,並使用輪廓系數來評估聚類的結果。
一,k-均值法確定最佳的簇數
通常情況下,使用肘方法(elbow)以確定聚類的最佳的簇數,肘方法之所以是有效的,是基於以下觀察:增加簇數有助於降低每個簇的簇內方差之和,給定k>0,計算簇內方差和var(k),繪制var關於k的曲線,曲線的第一個(或最顯著的)拐點暗示正確的簇數。
1,使用sjc.elbow()函數計算肘值
sjPlot包中sjc.elbow()函數實現了肘方法,用於計算k-均值聚類分析的肘值,以確定最佳的簇數:
library(sjPlot) sjc.elbow(data, steps = 15, show.diff = FALSE)
參數注釋:
- steps:最大的肘值的數量
- show.diff:默認值是FALSE,額外繪制一個圖,連接每個肘值,用於顯示各個肘值之間的差異,改圖有助於識別“肘部”,暗示“正確的”簇數。
sjc.elbow()函數用於繪制k-均值聚類分析的肘值,該函數在指定的數據框計算k-均值聚類分析,產生兩個圖形:一個圖形具有不同的肘值,另一個圖形是連接y軸上的每個“步”,即在相鄰的肘值之間繪制連線,第二個圖中曲線的拐點可能暗示“正確的”簇數。
繪制k均值聚類分析的肘部值。 該函數計算所提供的數據幀上的k均值聚類分析,並產生兩個圖:一個具有不同的肘值,另一個圖繪制在y軸上的每個“步”(即在肘值之間)之間的差異。 第二個圖的增加可能表明肘部標准。
library(effects) library(sjPlot) library(ggplot2) sjc.elbow(data,show.diff = FALSE)
從下面的肘值圖中,可以看出曲線的拐點大致在5附近:
2,使用NbClust()函數來驗證肘值
從上面肘值圖中,可以看到曲線的拐點是3,還可以使用NbClust包種的NbClust()函數,默認情況下,該函數提供了26個不同的指標來幫助確定簇的最終數目。
NbClust(data = NULL, diss = NULL, distance = "euclidean", min.nc = 2, max.nc = 15, method = NULL, index = "all", alphaBeale = 0.1)
參數注釋:
- diss:相異性矩陣(dissimilarity matrix),默認值是NULL,如果diss參數不為NULL,那么忽略distance參數。
- distance:用於計算相異性矩陣的距離度量,有效值是: "euclidean", "maximum", "manhattan", "canberra", "binary", "minkowski" 和"NULL"。如果distance不是NULL,diss(相異性矩陣)參數必須為NULL。
- min.nc:最小的簇數
- max.nc:最大的簇數
- method:用於聚類分析的方法,有效值是:"ward.D", "ward.D2", "single", "complete", "average", "mcquitty", "median", "centroid", "kmeans"
- index:用於計算的指標,NbClust()函數提供了30個指數,默認值是"all",是指除GAP、Gamma、Gplus 和 Tau之外的26個指標。
- alphaBeale:Beale指數的顯著性值
利用NbClust()函數來確定k-均值聚類的最佳簇數:
library(NbClust) nc <- NbClust(data,min.nc = 2,max.nc = 15,method = "kmeans") barplot(table(nc$Best.nc[1,]),xlab="Number of Clusters",ylab="Number of Criteria",main="number of Clusters Chosen by 26 Criteria")
從條形圖種,可以看到支持簇數為3的指標(Criteria)的數量是最多的,因此,基本上可以確定,k-均值聚類的簇數目是3。
二,k-中心化確定最佳簇數
k-中心化聚類有兩種實現方法,PAM和CLARA,PAM適合在小型數據集上運行,CLARA算法基於抽樣,不考慮整個數據集,而是使用數據集的一個隨機樣本,然后使用PAM方法計算樣本的最佳中心點。
通過fpc包中的pamk()函數得到最佳簇數:
pamk(data,krange=2:10,criterion="asw", usepam=TRUE, scaling=FALSE, alpha=0.001, diss=inherits(data, "dist"), critout=FALSE, ns=10, seed=NULL, ...)
參數注釋:
- krange:整數向量,用於表示簇的數量
- criterion:有效值是:"asw"(默認值)、 "multiasw" 和 "ch"
- usepam:邏輯值,如果設置為TRUE,那么使用pam算法,如果為FALSE,那么使用clara算法。
- scaling:邏輯值,是否對數據進行縮放(標准化),如果設置為FALSE,那么不對data參數做任何縮放;如果設置為TRUE,那么對data參數通過把(中間)變量除以它們的均方根來完成縮放。
- diss:邏輯值,如果設置為TRUE,表示data參數是相異性矩陣;如果設置為FALSE,那么data參數是觀測矩陣。
使用pamk()函數獲得PAM或CLARA聚類的最佳簇數:
library(fpc) pamk.best <- pamk(dataset) pamk.best$nc
通過cluster包中的clusplot()函數來查看聚類的結果:
library(cluster)
clusplot(pam(dataset, pamk.best$nc))
三,評估聚類的質量(輪廓系數)
使用數據集中對象之間的相似性度量來評估聚類的質量,輪廓系數(silhouette coefficient)就是這種相似性度量,是簇的密集與分散程度的評價指標。輪廓系數的值在-1和1之間,該值越接近於1,簇越緊湊,聚類越好。當輪廓系數接近1時,簇內緊湊,並遠離其他簇。
如果輪廓系數sil 接近1,則說明樣本聚類合理;如果輪廓系數sil 接近-1,則說明樣本i更應該分類到另外的簇;如果輪廓系數sil 近似為0,則說明樣本i在兩個簇的邊界上。所有樣本的輪廓系數 sil的均值稱為聚類結果的輪廓系數,是該聚類是否合理、有效的度量。
1,fpc包
包fpc中實現了計算聚類后的一些評價指標,其中就包括了輪廓系數:avg.silwidth(平均的輪廓寬度)
library(fpc) result <- kmeans(data,k) stats <- cluster.stats(dist(data)^2, result$cluster) sli <- stats$avg.silwidth
2,silhouette()函數
包cluster中計算輪廓系數的函數silhouette(),返回聚類的平均輪廓寬度:
silhouette(x, dist, dmatrix, ...)
參數注釋:
- x:整數向量,是聚類算法的結果
- dist:相異性矩陣(是dist()函數計算的結果),如果dist參數不指定,那么dmatrix參數必須指定;
- dmatrix:對稱性的相異性矩陣,用於代替dist參數,比dist參數更有效率
使用silhouette()計算輪廓系數:
library (cluster) library (vegan) #pam dis <- vegdist(data) res <- pam(dis,3) sil <- silhouette (res$clustering,dis) #kmeans dis <- dist(data)^2 res <- kmeans(data,3) sil <- silhouette (res$cluster, dis)
四,聚類的可視化
聚類的結果,可以試用ggplot2來可視化,還可以使用的一些聚類包中特有的函數來實現:factoextra包,sjPlot包和cluster包
1,cluster包
clusplot()函數
2,sjPlot包
sjc.qclus()函數
3,factoextra包
該包中的兩個函數十分有用,一個用於確定最佳的簇數,一個用於可視化聚類的結果。
(1),確定最佳的簇數fviz_nbclust()
函數fviz_nbclust(),用於划分聚類分析中,使用輪廓系數,WSS(簇內平方誤差和)確定和可視化最佳的簇數
fviz_nbclust(x, FUNcluster = NULL, method = c("silhouette", "wss",), diss = NULL, k.max = 10, ...)
參數注釋:
- FUNcluster:用於聚類的函數,可用的值是: kmeans, cluster::pam, cluster::clara, cluster::fanny, hcut等
- method:用於評估最佳簇數的指標
- diss:相異性矩陣,由dist()函數產生的對象,如果設置為NULL,那么表示使用 dist(data, method="euclidean") 計算data參數,得到相異性矩陣;
- k.max:最大的簇數量,至少是2
例如,使用kmenas進行聚類分析,使用平均輪廓寬度來評估聚類的簇數:
library(factoextra) fviz_nbclust(dataset, kmeans, method = "silhouette")
(2),可視化聚類的結果
fviz_cluster()函數用於可是化聚類的結果:
fviz_cluster(object, data = NULL, choose.vars = NULL, stand = TRUE, axes = c(1, 2), geom = c("point", "text"), repel = FALSE, show.clust.cent = TRUE, ellipse = TRUE, ellipse.type = "convex", ellipse.level = 0.95, ellipse.alpha = 0.2, shape = NULL, pointsize = 1.5, labelsize = 12, main = "Cluster plot", xlab = NULL, ylab = NULL, outlier.color = "black", outlier.shape = 19, ggtheme = theme_grey(), ...)
參數注釋:
- object:是聚類函數計算的結果
- data:原始對象數據集
使用fviz_cluster()把聚類的結果顯示出來:
km.res <- kmeans(dataset,3) fviz_cluster(km.res, data = dataset)
參考文檔: