K means聚類最優k值的選取

2021-08-28 14:44:34 字數 3247 閱讀 7124

最近做了乙個資料探勘的專案,挖掘過程中用到了k-means聚類方法,但是由於根據行業經驗確定的聚類數過多並且並不一定是我們獲取到資料的真實聚類數,所以,我們希望能從資料自身出發去確定真實的聚類數,也就是對資料而言的最佳聚類數。為此,我查閱了大量資料和部落格資源,總結出主流的確定聚類數k的方法有以下兩類。

1.1 理論

手肘法的核心指標是sse(sum of the squared errors,誤差平方和),

其中,ci是第i個簇,p是ci中的樣本點,mi是ci的質心(ci中所有樣本的均值),sse是所有樣本的聚類誤差,代表了聚類效果的好壞。

手肘法的核心思想是:隨著聚類數k的增大,樣本劃分會更加精細,每個簇的聚合程度會逐漸提高,那麼誤差平方和sse自然會逐漸變小。並且,當k小於真實聚類數時,由於k的增大會大幅增加每個簇的聚合程度,故sse的下降幅度會很大,而當k到達真實聚類數時,再增加k所得到的聚合程度回報會迅速變小,所以sse的下降幅度會驟減,然後隨著k值的繼續增大而趨於平緩,也就是說sse和k的關係圖是乙個手肘的形狀,而這個肘部對應的k值就是資料的真實聚類數。當然,這也是該方法被稱為手肘法的原因。

1.2 實踐

我們對預處理後資料.csv 中的資料利用手肘法選取最佳聚類數k。具體做法是讓k從1開始取值直到取到你認為合適的上限(一般來說這個上限不會太大,這裡我們選取上限為8),對每乙個k值進行聚類並且記下對於的sse,然後畫出k和sse的關係圖(毫無疑問是手肘形),最後選取肘部對應的k作為我們的最佳聚類數。python實現如下:

import pandas as pd

from sklearn.cluster import kmeans

import matplotlib.pyplot as plt

df_features = pd.read_csv(r'c:\預處理後資料.csv',encoding='gbk') # 讀入資料

'利用sse選擇k'

sse = # 存放每次結果的誤差平方和

for k in range(1,9):

estimator = kmeans(n_clusters=k) # 構造聚類器

estimator.fit(df_features[['r','f','m']])

x = range(1,9)

plt.xlabel('k')

plt.ylabel('sse')

plt.plot(x,sse,'o-')

plt.show()

畫出的k與sse的關係圖如下:

顯然,肘部對於的k值為4,故對於這個資料集的聚類而言,最佳聚類數應該選4

2.1 理論

該方法的核心指標是輪廓係數(silhouette coefficient),某個樣本點xi的輪廓係數定義如下:

其中,a是xi與同簇的其他樣本的平均距離,稱為凝聚度,b是xi與最近簇中所有樣本的平均距離,稱為分離度。而最近簇的定義是

其中p是某個簇ck中的樣本。事實上,簡單點講,就是用xi到某個簇所有樣本平均距離作為衡量該點到該簇的距離後,選擇離xi最近的乙個簇作為最近簇。

求出所有樣本的輪廓係數後再求平均值就得到了平均輪廓係數。平均輪廓係數的取值範圍為[-1,1],且簇內樣本的距離越近,簇間樣本距離越遠,平均輪廓係數越大,聚類效果越好。那麼,很自然地,平均輪廓係數最大的k便是最佳聚類數。

2.2 實踐

我們同樣使用2.1中的資料集,同樣考慮k等於1到8的情況,對於每個k值進行聚類並且求出相應的輪廓係數,然後做出k和輪廓係數的關係圖,選取輪廓係數取值最大的k作為我們最佳聚類係數,python實現如下:

import pandas as pd

from sklearn.cluster import kmeans

from sklearn.metrics import silhouette_score

import matplotlib.pyplot as plt

df_features = pd.read_csv(r'c:\users\61087\desktop\專案\爬蟲資料\預處理後資料.csv',encoding='gbk')

scores = # 存放輪廓係數

for k in range(2,9):

estimator = kmeans(n_clusters=k) # 構造聚類器

estimator.fit(df_features[['r','f','m']])

x = range(2,9)

plt.xlabel('k')

plt.ylabel('輪廓係數')

plt.plot(x,scores,'o-')

plt.show()

得到聚類數k與輪廓係數的關係圖:

可以看到,輪廓係數最大的k值是2,這表示我們的最佳聚類數為2。但是,值得注意的是,從k和sse的手肘圖可以看出,當k取2時,sse還非常大,所以這是乙個不太合理的聚類數,我們退而求其次,考慮輪廓係數第二大的k值4,這時候sse已經處於乙個較低的水平,因此最佳聚類係數應該取4而不是2。

但是,講道理,k=2時輪廓係數最大,聚類效果應該非常好,那為什麼sse會這麼大呢?在我看來,原因在於輪廓係數考慮了分離度b,也就是樣本與最近簇中所有樣本的平均距離。為什麼這麼說,因為從定義上看,輪廓係數大,不一定是凝聚度a(樣本與同簇的其他樣本的平均距離)小,而可能是b和a都很大的情況下b相對a大得多,這麼一來,a是有可能取得比較大的。a一大,樣本與同簇的其他樣本的平均距離就大,簇的緊湊程度就弱,那麼簇內樣本離質心的距離也大,從而導致sse較大。所以,雖然輪廓係數引入了分離度b而限制了聚類劃分的程度,但是同樣會引來最優結果的sse比較大的問題,這一點也是值得注意的。

總結從以上兩個例子可以看出,輪廓係數法確定出的最優k值不一定是最優的,有時候還需要根據sse去輔助選取,這樣一來相對手肘法就顯得有點累贅。因此,如果沒有特殊情況的話,我還是建議首先考慮用手肘法。

K Means聚類最優k值的選取

最近做乙個文字分類的專案,在最開始的時候會用到k means的聚類方法,因此需要在文字上找到最佳的聚類數。1.1 理論 手肘法的評價k值好壞的標準是sse sum of the squared errors ss e p ci p mi 2s se p ci p mi 2其中 c i c i代表第 ...

K means聚類最優k值的選取

我們希望能從資料自身出發去確定真實的聚類數,也就是對資料而言的最佳聚類數 1.手肘法 1.1 理論 手肘法的核心指標是sse sum of the squared errors,誤差平方和 其中,ci是第i個簇,p是ci中的樣本點,mi是ci的質心 ci中所有樣本的均值 sse是所有樣本的聚類誤差,...

kmeans聚類選擇最優K值python實現

kmeans演算法中k值的確定是很重要的。下面利用python中sklearn模組進行資料聚類的k值選擇 資料集自製資料集,格式如下 手肘法 手肘法的核心指標是sse sum of the squared errors,誤差平方和 其中,ci是第i個簇,p是ci中的樣本點,mi是ci的質心 ci中所...