R語言聚類之—kmeans聚類
k(均值)聚類屬於扁平聚類演算法,即進行一層劃分得到k個簇,與層次聚類演算法開始不需要決定簇數不同,k均值聚類需要使用者事先確定好簇個數,因為構建一顆聚類樹是非常耗時的事情,所以k均值聚類演算法的效率要優於層次聚類。
一、資料準備
> data(nutrient,package = “flexclust”)
> str(nutrient)
‘data。frame’: 27 obs。 of 5 variables:
$ energy : int 340 245 420 375 180 115 170 160 265 300 。。。
$ protein: int 20 21 15 19 22 20 25 26 20 18 。。。
$ fat : int 28 17 39 32 10 3 7 5 20 25 。。。
$ calcium: int 9 9 7 9 17 8 12 14 9 9 。。。
$ iron : num 2。6 2。7 2 2。6 3。7 1。4 1。5 5。9 2。6 2。3 。。。
> nutrient1<-scale(nutrient[,-1])
二、(1)使用kmeans方法聚類nutrient1資料集;
> fit<-kmeans(nutrient1,5)
> fit
K-means clustering with 5 clusters of sizes 10, 2, 3, 6, 6
Cluster means:
protein fat calcium iron
1 -0。02352002 1。1298286 -0。4531723 0。06057497
2 -2。35200232 -1。1087718 0。4361807 2。27092763
3 -0。15680015 -0。5165495 2。3541419 -0。48916187
4 1。17600116 -0。6201884 -0。2280575 0。37764310
5 -0。27440027 -0。6349940 -0。3391198 -0。99099632
Clustering vector:
BEEF BRAISED HAMBURGER BEEF ROAST BEEF STEAK
1 1 1 1
BEEF CANNED CHICKEN BROILED CHICKEN CANNED BEEF HEART
4 5 4 4
LAMB LEG ROAST LAMB SHOULDER ROAST SMOKED HAM PORK ROAST
1 1 1 1
PORK SIMMERED BEEF TONGUE VEAL CUTLET BLUEFISH BAKED
1 1 4 5
CLAMS RAW CLAMS CANNED CRABMEAT CANNED HADDOCK FRIED
2 2 5 5
MACKEREL BROILED MACKEREL CANNED PERCH FRIED SALMON CANNED
5 3 5 3
SARDINES CANNED TUNA CANNED SHRIMP CANNED
3 4 4
Within cluster sum of squares by cluster:
[1] 5。4900775 0。5321011 6。7811219 8。9407403 3。7326705
(between_SS / total_SS = 75。5 %)
Available components:
[1] “cluster” “centers” “totss” “withinss” “tot。withinss”
[6] “betweenss” “size” “iter” “ifault”
(2)呼叫barplot函式繪製每個簇中心的條形圖:
> barplot(t(fit$centers),beside = T,xlab = “cluster”,ylab=“value”)
(3)還可以繪製簇的散點圖,對於屬於不同的觀測點使用不同的顏色
> plot(nutrient1,col=fit$cluster)
(4)使用ggfortify包進行聚類結果的視覺化展示
> library(ggfortify)
> library(ggplot2)
> autoplot(kmeans(nutrient1, 5),data=nutrient1,label=TRUE, label。size=3, frame=TRUE)
三、原理
k均值聚類屬於分裂聚類,演算法目標透過將n個物件劃分到k個簇中,使得同一個簇中的物件之間的距離最近,演算法的目的是使組內平方和(Within—Cluster Sum of Squares,WCSS)最小。假設x是一組給定觀測點,s={s1,s2,‘’‘,sk}代表k個劃分,ui是si的中心,wcss公式定義
k均值聚類過程分如下五步
(1)指定聚類個數
(2)隨機產生k個劃分
(3)計算每個劃分的中心
(4)將觀測點分配到距離簇中心最近的一個簇中
(5)重複(2)(3)(4)知道wcss基本不發生變化(或最小化)
讀者還可以在k均值聚類演算法中規定具體的聚類方法,如Hartigan—Wong,Lloyd,Forgy,MacQueen
四、擴充套件—獲得最佳化的k
1、準備
為了找到最優的簇個數,讀者需要準備好前述提及的nutrient1資料集
2、操作
執行以下操作為k均值演算法找到最合適的聚類個數。
(1)首先,計算每個簇的距離平方和(withinss)
> nk=2:10
> set。seed(22)
> Wss<-sapply(nk,function(k){
+ kmeans(nutrient1,centers = k)$tot。withinss
+ })
> Wss
[1] 80。107407 56。593182 40。543422 24。155897 22。989831 14。480686 9。669921 10。105902
[9] 7。498038
(2)呼叫plot繪製不同k值下距離平方和的線圖
> plot(nk,Wss,type = “l”,xlab=“number of k”,ylab=“within sum of squares”)
(3)計算不同聚類結果的平均輪廓值(avg。silwidth)
> library(fpc)
> sw=sapply(nk,function(k){
+ cluster。stats(dist(nutrient1),kmeans(nutrient1,centers = k)$cluster)$avg。silwidth
+ })
> sw
[1] 0。4755391 0。3022866 0。3736633 0。4061053 0。3962927 0。3534240 0。3284742 0。4001432
[9] 0。4039906
(4)使用線圖繪製不同k值的平均輪廓值
> plot(nk,sw,type = “l”,xlab=“number of clusters”,ylab = “average silhouette width”)
(5)得到最大的簇個數
> nk[which。max(sw)]
[1] 2
所以聚類簇個數為2時最好。