聚類效果評估——輪廓係數(Silhouette Coefficient)附Python代碼

前言

在機器學習中,無監督學習算法中聚類算法算作相對重要的一部分算法。也常在低資源和無標註的情況下使用。
其中KMeans作爲聚類算法中的一種,充當着重要的角色。由於其思想較爲簡單,易於理解和方便實現。所以經常被用來做數據的處理,在NLP領域常被用於文本聚類以及文本類別挖掘等方向。

但是KMeans算法有一個致命的缺點就是,如何選擇K值。K值的選擇至關重要,選擇的好可以有較好的聚類效果。

通常情況下,K值的選擇人們會根據先驗的知識給定一個估計的值,或者是利用Canopy算法計算出一個大致的K值。更多的情況下,還是利用後驗的方式進行K值的選擇。也就是在給定K的範圍[a,b]下,對不同的K值分別進行聚類操作,最終利用聚類效果的評價指標,來給出相應的最優聚類結果。這種評價聚類結果效果的指標有:誤差平方和(Sum of the Squared Errors, SSE),輪廓係數(Silhouette Coefficient)和CH指標(Calinski-Harabaz)。

是什麼?

輪廓係數,是用於評價聚類效果好壞的一種指標。可以理解爲描述聚類後各個類別的輪廓清晰度的指標。其包含有兩種因素——內聚度和分離度。

內聚度可以理解爲反映一個樣本點與類內元素的緊密程度。
分離度可以理解爲反映一個樣本點與類外元素的緊密程度。

爲什麼?

爲什麼輪廓係數可以評價聚類效果的好壞?怎樣評價效果好壞?

輪廓係數的公式如下:
S(i)=b(i)a(i)max{a(i),b(i)}S(i) = \frac{b(i)-a(i)}{max\{a(i), b(i)\}}

其中,a(i)a(i)代表樣本點的內聚度,計算方式如下:
a(i)=1n1jindistance(i,j)a(i) = \frac{1}{n-1}\sum_{j\ne i}^{n}distance(i,j)
其中jj代表與樣本ii在同一個類內的其他樣本點,distancedistance代表了求iijj的距離。所以a(i)a(i)越小說明該類越緊密。

b(i)b(i)的計算方式與a(i)a(i)類似。只不過需要遍歷其他類簇得到多個值{b1(i),b2(i),b3(i),...,bm(i)}\{b_1(i),b_2(i),b_3(i),...,b_m(i)\}從中選擇最小的值作爲最終的結果。

所以原S(i)S(i)
S(i)={1a(i)b(i)a(i)<b(i)0a(i)=b(i)b(i)a(i)1a(i)>b(i)S(i)=\left\{\begin{matrix} 1-\frac{a(i)}{b(i)} & a(i)<b(i)\\ 0& a(i)=b(i)\\ \frac{b(i)}{a(i)}-1 & a(i)>b(i) \end{matrix}\right.

由上式可以發現:
當a(i)>b(i)時,即類內的距離小於類間距離,則聚類結果更緊湊。S的值會趨近於1。越趨近於1代表輪廓越明顯。

相反,當a(i)<b(i)時,類內的距離大於類內距離,說明聚類的結果很鬆散。S的值會趨近於-1,越趨近於-1則聚類的效果越差。

由此可得:

輪廓係數S的取值範圍爲[-1, 1],輪廓係數越大聚類效果越好。

怎麼用?

如何計算輪廓係數,已經說明了。但是輪廓係數如何確定K值呢?

我們需要將K值設定爲具體的多個數值,範圍可以人爲規定,如2到10。每個K值下進行聚類,最終計算聚類結果的輪廓係數。最終將輪廓係數繪製關於K的折線圖(繪圖更直觀)。然後將輪廓係數最大的K值作爲最終的K值。

不適用

對於簇結構爲凸的數據輪廓係數較高,對於簇結構非凸的輪廓係數較低。
因此,輪廓係數不能在不同的算法之間比較優劣,如統一數據下,可能KMeans的結果就比DBSCAN要好。

示例

如下代碼是計算KMeans的輪廓係數的code

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

# 定義KMeans,以及K值
kmeans = KMeans(n_clusters=n_clusters)	
# 根據數據data進行聚類,結果存放於result_list中
result_list = kmeans.fit_predict(data)
# 將原始的數據data和聚類結果result_list
# 傳入對應的函數計算出該結果下的輪廓係數
score = silhouette_score(data, result_list)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章