R數據挖掘 第三篇:聚類的評估(簇數確定和輪廓系數)和可視化


在實際的聚類應用中,通常使用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)

 

參考文檔:

確定最佳聚類數目的10種方法


免責聲明!

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



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