Kmeans分群演算法 與 Silhouette 輪廓分析

Jimmy Huang
5 min readAug 24, 2019

--

在機器學習 - 非監督學習中,KMeans可以說是簡單、效果又不錯的分群演算法,基本思想為

基本思想:對於給定的樣本集,按照樣本之間的距離大小,將樣本集劃分為K個Cluster,讓Cluster內的點盡量緊密的連在一起,而讓Cluster間的距離盡量的大。

簡單來說就是物以類聚,

  1. 根據設定的K,隨機地選擇K個聚類中心(Cluster Centroid)

2. 評估各個樣本到聚類中心的距離,如果樣本距離第i個聚類中心更近,則認為其屬於第i簇

3. 計算每個簇中樣本的平均(均值)位置,將聚類中心移動至該位置

4. 重複以上步驟直至各個聚類中心的位置不再發生改變。

圖片來源: Coursera - Andrew Ng 的機器學習課程

至於在更進一步的詳細的影片解說:StatQuest這篇 講解得很好

看起來很簡單,但這演算法有最大的缺點,就是第一點,要選定K

這時候有兩種方法: 一種是手肘法,另一種就是今天要介紹的,利用輪廓係數法Silhouette analysis

輪廓係數法的概念是「找出同群資料點內最近/不同群越分散」的值,也就是滿足 Cluster 的定義,b為不同群之間的點平均距離,a為同群之間的距離
S則越大越好,代表分得越清楚

import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
X, y = make_blobs(n_samples=1000,n_features=2,centers=6,cluster_std=0.3,center_box=(-10.0, 10.0))
plt.scatter(*zip(*X))
利用make_blobs製造6個群組

為了解釋說明,先用make_blobs(聚類數據生成器)來產生數據
scikit中的make_blobs方法常被用來生成聚類算法的測試數據,直觀地說,make_blobs會根據用戶指定的特徵數量、中心點數量、範圍等來生成幾類數據,這些數據可用於測試聚類算法的效果。

產生完後,就用for迴圈產生不同的n_clusters去看看何者輪廓係數較高呢

silhouette_avg = []
for i in range(2,11):
kmeans_fit = KMeans(n_clusters = i).fit(X)
silhouette_avg.append(silhouette_score(X, kmeans_fit.labels_))
plt.plot(range(2,11), silhouette_avg)

透過上圖可以發現 在n_clusters = 6的時候,分的效果最好,所以可以選定6當作K

這是嘗試更複雜的分類問題,現實生活中,資料常常是非常混亂的

X, y = make_blobs(n_samples=1000,n_features=2,centers=13,cluster_std=1,center_box=(-10.0, 10.0)) 
plt.scatter(*zip(*X),c=y)
silhouette_avg = []
for i in range(2,30):
kmeans_fit = KMeans(n_clusters = i).fit(X)
silhouette_avg.append(silhouette_score(X, kmeans_fit.labels_))
plt.plot(range(2,30), silhouette_avg)
假設產生n=13的資料,輪廓法是否能找出最佳分類數量呢?
由上圖可知,最佳的K大概就在13附近,顯示輪廓分析效果不錯

更多的探討可以參照Scikit-Learn的官方文檔https://blog.csdn.net/weixin_44344462/article/details/89337770

--

--

Jimmy Huang
Jimmy Huang

No responses yet