k-means聚類算法及案例分析(如何確定聚類數:輪廓系數、中心划分法(PAM))


k-means聚類算法的R語言實現

 

K-means算法假設要把樣本集分為c個類別,算法描述如下:(1)隨機選擇c個類的初始中心;

 

(2)在第n次迭代中,對任意一個樣本,求其到每一個中心的距離,將該樣本歸到距離最近的中心所在的類;

 

3)更新該類的中心值,一般利用均值、中位點等方法;

 

(4)對於所有的c個聚類中心,利用(2)( 3 )的迭代法更新后,如果中心點的值不再變化,則迭代結束,否則繼續迭代,當達到最大迭代次數時,中心點仍未收斂的,取最后的中心點為中心。

 

     kmeans 函數幾個參數的具體作用:centers 設置聚類數;iter.max 設置最大迭代次數;nstart 隨機設置初始中心點的次數,也可以理解為重復做kmeans的次數,眾所周知,kmeans對初始中心非常敏感,nstart10表示做10kmeans,每次初始中心點隨機生成一次,也可以理解為確定初始中心點時重復 kmeans的次數,每次迭代完成后返回最優解,當nstart 等於1時,等於只做了一次 kmeans,由於初始中心點不同,所以每次結果都不一樣(可以設置隨機種子克服)nstart一般設置在20~25之間,基本保證能返回最優解,每次的聚類結果也大體相同,除非你的數據量很大。

 

 

#步驟1 數據集准備及描述

n=100

g=6

set.seed(g)

d<-data.frame(x=unlist(lapply(1:g,function(i) rnorm(n/g,runif(1)*i^2))),

              y=unlist(lapply(1:g,function(i) rnorm(n/g,runif(1)*i^2)))) #生成數據集

解釋:#unlist 給定一個列表結構 x,unlist 將其簡化為生成一個包含 x 中出現的所有原子分量的向量。

            # lapply返回一個與 X 長度相同的列表,其中每個元素都是將 FUN 應用於 X 的相應元素的結果。

            #runif()函數用於生成從0到1區間范圍內的服從正態分布的隨機數,每次生成的值都不一樣。runif(20) 表示生成20個0到1之間的隨機數

            #rnorm(n/g,runif(1)*i^2) 表示總共生成n/g個隨機數,且每個隨機數的大小為runif(1)*i^2

           #lapply(1:g,function(i) rnorm(n/g,runif(1)*i^2)) 表示總共生成與(1:g)*(n/g)長度相同的列表,且列表中的數字為runif(1)*i^2,其中i的取值為1:g。

           #x=unlist(lapply(1:g,function(i) rnorm(n/g,runif(1)*i^2))) 標識把列表簡化為向量

dim(d)

 

class(d)

 

#步驟2 計算簇類數k

library(cluster)

library(fpc)

pamk.best<-pamk(d)  #判斷是否存在多個聚類

 

par(mfrow=c(1,2))  #設置畫布展示,1行2張圖

cat("number of clusters estimated by optimum average silhouette width:",pamk.best$nc,"\n") #cat表示連接

plot(pam(d,pamk.best$nc),main="")  #pam(x,k)將數據x划分為k個聚類

#這兩個組成部分解釋了100%的點變異性

 

#此圖表示最佳平均輪廓寬度簇類數估計,從簇類數估計看,簇類設置為4類為最佳

 

#步驟3 聚類結果展示及其可視化

par(mfrow=c(1,1))

c1<-kmeans(d,pamk.best$nc)

c1

 

plot(d,col=c1$cluster)+points(c1$centers,col=3:6,pch=12,cex=1)

#plot(d,col=c1$cluster) 畫出聚類結果

#points(c1$centers,col=3:6,pch=12,cex=1) 畫出每個聚類的中心,且設置顏色col,設置參數控制符號(圖中的四方格)pch,設置控制符號和文字的大小cex

 

案例1:k-means聚類算法在NCI60數據集上的應用

#NCI60數據集由64個細胞系的6830個基因表達數據構成,每個細胞系都有一個標簽變量記錄了其癌細胞的類型

library(ISLR)

nci.labs<-NCI60$labs

nci.data<-NCI60$data

#在進行 PCA 和聚類分析時,由於是無指導約學習,不使用癌細胞的類型特征,在 PCA和聚類分析之后,可以用這些特征檢驗無指導學習的結果與癌細胞類型的匹配度。

dim(nci.data)

 

nci.labs[1:4] #查看癌細胞系的類型

 

table(nci.labs) #列出癌細胞的類型

 

set.seed(2)

km.out<-kmeans(sd.data, 4, nstart=20) #k均值聚類法

km.clusters<-km.out$cluster

table(km.clusters,hc.clusters)

 

案例2:k-means聚類算法在iris數據集上的應用

#鳶尾花數據集

require("stats")

model<-kmeans(x=subset(iris,select = -Species),centers = 3)

table(iris$Species,model$cluster,dnn=c("Actual","predicted"))

  

#如何確定聚類數

  聚類就像切西瓜,切幾瓣真的很隨意,但是我們也可以使用一些方法評估一下應該聚幾類,比如輪廓系數,它結合了內聚度和分離度兩種因素,即同時考察了組內相似性和組間差異性,可見輪廓系數的值介於[-1,1],越趨近於1代表內聚度和分離度都相對較優

#(1)輪廓系數

library(cluster)

asw<-numeric(20) #生成一個序列

for(k in 2:20){  #測試聚類2-20的可能性

  asw[[k]]<-pam(subset(iris,select = -Species),k)$silinfo$avg.width

}

k.best<-which.max(asw) #找出最大的聚類數

cat("通過輪廓系數(silhouette)估計的最佳聚類數:",k.best,"\n") #輸出最佳聚類數

 

#2)中心划分法(PAM)

library(fpc)

library(cluster)

pamk.best<-pamk(subset(iris,select = -Species))

cat("通過中心化分法估計的最佳聚類數:",pamk.best$nc,"\n") #輸出最佳聚類數


免責聲明!

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



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