Kmeans分群演算法 與 Silhouette 輪廓分析
在機器學習 - 非監督學習中,KMeans可以說是簡單、效果又不錯的分群演算法,基本思想為
基本思想:對於給定的樣本集,按照樣本之間的距離大小,將樣本集劃分為K個Cluster,讓Cluster內的點盡量緊密的連在一起,而讓Cluster間的距離盡量的大。
簡單來說就是物以類聚,
- 根據設定的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(聚類數據生成器)來產生數據
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)
更多的探討可以參照Scikit-Learn的官方文檔, https://blog.csdn.net/weixin_44344462/article/details/89337770