天天看點

機器學習:聚類算法的模型評估名額:輪廓系數

不同于分類模型和回歸,聚類算法的模型評估不是一件簡單的事。

在分類中,有直接結果(标簽)的輸出,并且分類的結果有正誤之分,是以使用預測的準确度,混淆矩陣,ROC曲線等名額來進行評估。但無論如何評估,都是在”模型找到正确答案“的能力。而回歸中,由于要拟合資料,我們有MSE均方誤差,有損失函數來衡量模型的拟合程度。但這些衡量名額都不适用于聚類。

如何衡量聚類算法的效果

聚類模型的結果不是某種标簽輸出,并且聚類的結果是不确定的,其優劣由業務需求或者算法需求來決定,并且沒有永遠的正确答案。如何衡量聚類的效果呢?

K-Means的目标是確定“簇内差異小,簇外差異大”,可以通過衡量簇内差異來衡量聚類的效果。

SSE是用距離來衡量簇内差異的名額,是以,是否可以用SSE來作為聚類的衡量名額呢?SSE越小模型越好嘛。

可以,但是這個名額的缺點和局限太大。

首先,它不是有界的。我們隻知道,SSE越小越好,是0最好,但不知道,一個較小的SSE究竟有沒有達到模型的極限,能否繼續提高。

第二,它的計算太容易受到特征數目的影響,資料次元很大的時候,SSE的計算量會陷入次元詛咒之中,計算量會爆炸,不适合用來一次次評估模型。

第三,它會受到超參數K的影響,随着K越大,SSE注定會越來越小,但這并不代表模型的效果越來越好了。

第四,SSE對資料的分布有假設,它假設資料滿足凸分布(即資料在二維平面圖像上看起來是一個凸函數的樣子),并且它假設資料是各向同性的(isotropic),即是說資料的屬性在不同方向上代表着相同的含義。但是現實中的資料往往不是這樣。是以使用Inertia作為評估名額,會讓聚類算法在一些細長簇,環形簇,或者不規則形狀的流形時表現不佳:

機器學習:聚類算法的模型評估名額:輪廓系數

那我們可以使用什麼名額呢?聚類沒有标簽,即不知道真實答案的預測算法,我們必須完全依賴評價簇内的稠密程度(簇内差異小)和簇間的離散程度(簇外差異大)來評估聚類的效果。其中,輪廓系數是最常用的聚類算法的評價名額。它是對每個樣本來定義的,它能夠同時衡量:

1)樣本與其自身所在的簇中的其他樣本的相似度a,等于樣本與同一簇中所有其他點之間的平均距離;

2)樣本與其他簇中的樣本的相似度b,等于樣本與下一個最近的簇中的所有點之間的平均距離;

根據聚類的要求 ”簇内差異小,簇外差異大“,我們希望b永遠大于a,并且大得越多越好。

單個樣本的輪廓系數計算為:

s = b − a m a x ( a , b ) s=\frac{b-a}{max(a,b)} s=max(a,b)b−a​

這個公式可以被解析為:

機器學習:聚類算法的模型評估名額:輪廓系數

很容易了解輪廓系數範圍是(-1,1),其中值越接近1表示樣本與自己所在的簇中的樣本很相似,并且與其他簇中的樣本不相似,當樣本點與簇外的樣本更更相似的時候,輪廓系數就為負。當輪廓系數為0時,則代表兩個簇中的樣本相似度一緻,兩個簇本應該是一個簇。

如果一個簇中的大多數樣本具有比較高的輪廓系數,則簇會有較高的總輪廓系數,則整個資料集的平均輪廓系數越高,則聚類是合适的。如果許多樣本點具有低輪廓系數甚至負值,則聚類是不合适的,聚類的超參數K可能設定得太大或者太小。

在sklearn中,我們使用子產品metrics中的類silhouette_score來計算輪廓系數,它傳回的是一個資料集中,所有樣本的輪廓系數的均值。但我們還有同在metrics子產品中的silhouette_sample,它的參數與輪廓系數一緻,但傳回的是資料集中每個樣本自己的輪廓系數。

我們來看看輪廓系數在我們自建的資料集上表現如何:

在上篇博文《sklearn機器學習:K-Means》中,我們自己建了一個有4個中心的各向同性高斯團簇的資料點集,資料點分布如下

機器學習:聚類算法的模型評估名額:輪廓系數

下面分别以k=3,4,5來驗證一下輪廓系數的篩選效果:

n_clusters = 3
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
silhouette_score(X,cluster_.labels_)
           
n_clusters = 4
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
silhouette_score(X,cluster_.labels_)
           
n_clusters = 5
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
silhouette_score(X,cluster_.labels_)
           

可見,在k=4時,輪廓系數的值最大,符合我們建立的資料集屬性,可見輪廓系數的篩選性是值得肯定的。

array([ 0.62982017,  0.5034877 ,  0.56148795,  0.84881844,  0.56034142,
        0.78740319,  0.39254042,  0.4424015 ,  0.48582704,  0.41586457,
        0.62497924,  0.75540751,  0.50080674,  0.8452256 ,  0.54730432,
        ...
        0.5748237 ,  0.74655924,  0.57403918,  0.69733646,  0.52992071])
           

輪廓系數有很多優點,它在有限空間中取值,使得我們對模型的聚類效果有一個“參考”。并且,輪廓系數對資料的分布沒有假設,是以在很多資料集上都表現良好。但它在每個簇的分割比較清洗時表現最好。但輪廓系數也有缺陷,它在凸型的類上表現會虛高,比如基于密度進行的聚類,或通過DBSCAN獲得的聚類結果,如果使用輪廓系數來衡量,則會表現出比真實聚類效果更高的分數。