K-means聚类最优k值的选取
?????? 最近做了一個數據挖掘的項目,挖掘過程中用到了K-means聚類方法,但是由于根據行業經驗確定的聚類數過多并且并不一定是我們獲取到數據的真實聚類數,所以,我們希望能從數據自身出發去確定真實的聚類數,也就是對數據而言的最佳聚類數。為此,我查閱了大量資料和博客資源,總結出主流的確定聚類數k的方法有以下兩類。
1.手肘法
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實現如下:
顯然,肘部對于的k值為4,故對于這個數據集的聚類而言,最佳聚類數應該選4
2. 輪廓系數法
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 pltdf_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']])Scores.append(silhouette_score(df_features[['R','F','M']],estimator.labels_,metric='euclidean')) 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值的选取的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java设置随机数_java设置随机数教
- 下一篇: 《高级无线网络—4G技术》——第2章