首頁 > 軟體

R語言實現KMeans聚類演演算法範例教學

2022-07-01 22:03:07

本文和你一起學習無監督機器學習演演算法 ———— kmeans演演算法,並在R中給詳細的實現範例和步驟。

什麼是k-means聚類演演算法

聚類是從資料集中對觀測值進行聚類的機器學習方法。它的目標是聚類相似觀測值,不同類別之間差異較大。聚類是一種無監督學習方法,因為它僅嘗試從資料集中發現結構,而不是預測應變數的值。

下面是一個市場行銷中對客戶分類的場景,通過下面客戶資訊:

  • 家庭收入
  • 住房面積
  • 戶主職業
  • 據城區距離

我們利用這些資訊進行聚類,可識別相似家庭,從而能夠識別某型別家庭可能購買某種產品或對某種型別的廣告反應更好。

最常用的聚類演演算法就是k-means聚類演演算法,下面我們介紹k-means演演算法並通過範例進行說明。

k-means聚類演演算法把資料集中每個觀測值分為K個類別。每個分類中的觀測值相當類似,K類之間彼此差異較大。實際應用中執行下列幾步實現k-means聚類演演算法:

1.確定K值

首先確定把資料集分為幾類。通常我們簡單測試幾個不同值K,然後分析結果,確定那個值更有現實意義。

2.將每個觀察結果隨機分配到一個初始簇中,從1到K。

3.執行以下步驟,直到叢集分配停止變化。

對於K個叢集中的每一個,計算叢集的質心。這僅僅是第k個簇中觀測的p特徵的向量。

將每個觀測值分配到質心最近的簇中。在這裡最接近的是用歐氏距離來定義的。

下面通過範例展示R的實現過程。

R 實現kmeans聚類演演算法

載入包

首先載入兩個包,包括kmeans演演算法的一些輔助函數。

library(factoextra)
library(cluster)

載入範例資料

對於本例我們將使用R中內建的usarrest資料集,該資料集包含1973年美國每個州每10萬居民因謀殺、襲擊和強姦而被捕的人數,以及每個州居住在城市地區的人口百分比(UrbanPop)。

#load data
df <- USArrests

#remove rows with missing values
df <- na.omit(df)

#scale each variable to have a mean of 0 and sd of 1
df <- scale(df)

#view first six rows of dataset
head(df)

#                Murder   Assault   UrbanPop         Rape
# Alabama    1.24256408 0.7828393 -0.5209066 -0.003416473
# Alaska     0.50786248 1.1068225 -1.2117642  2.484202941
# Arizona    0.07163341 1.4788032  0.9989801  1.042878388
# Arkansas   0.23234938 0.2308680 -1.0735927 -0.184916602
# California 0.27826823 1.2628144  1.7589234  2.067820292
# Colorado   0.02571456 0.3988593  0.8608085  1.864967207

上面程式碼首先載入USArrests資料集,刪除缺失值,對資料值進行標準化。

尋找最佳聚類數量

執行kmeans聚類演演算法,我們可以使用內建包stat中的kmeans()函數,語法如下:

kmeans(data, centers, nstart)

  • data : 資料集名稱
  • centers: 聚類數量,即選擇k的值
  • nstart: 初始設定個數。因為不同的初始啟動集合可能會導致不同的結果,所以建議使用幾種不同的初始設定。k-means演演算法將找到導致簇內變異最小的初始設定。

既然在使用kmeans函數之前並不確定最優聚類數量,下面通過兩個圖來輔助我們決定:

1.聚類數量 vs. 總體平方和

首先使用 fviz_nbclust 函數建立一個圖,展示聚類數量及總體平方和之間的關係:

fviz_nbclust(df, kmeans, method = "wss")

通常我們建立這類圖形尋找某個K類對應的平方和值開始彎曲或趨於平緩的肘形。這通常是最理想的聚類數量。上圖中顯然在k = 4個時出現肘形。

2.聚類數量 vs. 差距統計

另一個決定最佳聚類數量的是使用指標:差距統計。它用於比較不同k值聚類差距變化情況。使用cluster包中的clusGap()以及fviz_gap_stat()函數畫圖:

#calculate gap statistic based on number of clusters
gap_stat <- clusGap(df,
                    FUN = kmeans,
                    nstart = 25,
                    K.max = 10,
                    B = 50)

#plot number of clusters vs. gap statistic
fviz_gap_stat(gap_stat)

從上圖可以看到k=4時,差距統計最大,這與前面圖的結果一致。

使用最優k執行kmeans聚類

最後,我們執行kmeans函數,使用k=4作為最優值:

# 設定隨機種子,讓結果可以重現
set.seed(1)

# 呼叫kmeans聚類演演算法 k = 4
km <- kmeans(df, centers = 4, nstart = 25)

# 檢視結果
km

# Show in New Window
# Clustering k = 1,2,..., K.max (= 10): .. done
# Bootstrapping, b = 1,2,..., B (= 50)  [one "." per sample]:
# .................................................. 50 
# R Console
# 
# 
# Show in New Window
# K-means clustering with 4 clusters of sizes 13, 13, 16, 8
# 
# Cluster means:
#       Murder    Assault   UrbanPop        Rape
# 1 -0.9615407 -1.1066010 -0.9301069 -0.96676331
# 2  0.6950701  1.0394414  0.7226370  1.27693964
# 3 -0.4894375 -0.3826001  0.5758298 -0.26165379
# 4  1.4118898  0.8743346 -0.8145211  0.01927104
# 
# Clustering vector:
#        Alabama         Alaska        Arizona       Arkansas     California       Colorado 
#              4              2              2              4              2              2 
#    Connecticut       Delaware        Florida        Georgia         Hawaii          Idaho 
#              3              3              2              4              3              1 
#       Illinois        Indiana           Iowa         Kansas       Kentucky      Louisiana 
#              2              3              1              3              1              4 
#          Maine       Maryland  Massachusetts       Michigan      Minnesota    Mississippi 
#              1              2              3              2              1              4 
#       Missouri        Montana       Nebraska         Nevada  New Hampshire     New Jersey 
#              2              1              1              2              1              3 
#     New Mexico       New York North Carolina   North Dakota           Ohio       Oklahoma 
#              2              2              4              1              3              3 
#         Oregon   Pennsylvania   Rhode Island South Carolina   South Dakota      Tennessee 
#              3              3              3              4              1              4 
#          Texas           Utah        Vermont       Virginia     Washington  West Virginia 
#              2              3              1              3              3              1 
#      Wisconsin        Wyoming 
#              1              3 
# 
# Within cluster sum of squares by cluster:
# [1] 11.952463 19.922437 16.212213  8.316061
#  (between_SS / total_SS =  71.2 %)
# 
# Available components:
# 
# [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
# [6] "betweenss"    "size"         "iter"         "ifault"     

從結果可見:

  • 16 州分在第一個類
  • 13 州分在第二個類
  • 13 州分在第三個類
  • 8 州分在第四個類

我們可以通過fviz_cluster()函數在二維空間中以散點圖方式展示結果:

#plot results of final k-means model
fviz_cluster(km, data = df)

也可以使用aggregate()函數檢視每個類中變數的均值:

#find means of each cluster
aggregate(USArrests, by=list(cluster=km$cluster), mean)

# cluster	  Murder   Assault	UrbanPop	    Rape
# 				
# 1	3.60000	  78.53846	52.07692	12.17692
# 2	10.81538 257.38462	76.00000	33.19231
# 3	5.65625	 138.87500	73.87500	18.78125
# 4	13.93750 243.62500	53.75000	21.41250

輸出結果解釋如下:

  • 在第一類中的州中平均每100,000人謀殺數為 3.6
  • 在第一類中的州中平均每100,000人襲擊數為 78.5
  • 在第一類中的州中平均每100,000人城區居民率為 52.1%
  • 在第一類中的州中平均每100,000人強姦數為 3.6 12.2

最後我們把聚類結果附加到原始資料集中:

#add cluster assigment to original data
final_data <- cbind(USArrests, cluster = km$cluster)

#view final data
head(final_data)

# 	    Murder	Assault	UrbanPop  Rape	 cluster
# 				
# Alabama	    13.2	236	58	  21.2	 4
# Alaska	    10.0	263	48	  44.5	 2
# Arizona	     8.1	294	80	  31.0	 2
# Arkansas     8.8	190	50	  19.5	 4
# California   9.0	276	91	  40.6	 2
# Colorado     7.9	204	78	  38.7	 2

kmeans 演演算法的優缺點

優點:

很快的演演算法能夠處理巨量資料集

缺點:

在執行演演算法之前需要指定聚類數量對異常值敏感 總結

本文我們討論了kmeans演演算法的概念,並在R中給詳細實現範例和步驟。

總結

到此這篇關於R語言實現KMeans聚類演演算法教學的文章就介紹到這了,更多相關R語言KMeans聚類演演算法內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com