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

2021-08-27 05:42:45 字數 3192 閱讀 2314

kmeans演算法中k值的確定是很重要的。

下面利用python中sklearn模組進行資料聚類的k值選擇

資料集自製資料集,格式如下:

①手肘法

手肘法的核心指標是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值就是資料的真實聚類數。當然,這也是該方法被稱為手肘法的原因。

python**:

import pandas as pd

import numpy as np

from sklearn.cluster import kmeans

import matplotlib.pyplot as plt

import xlrd

# 從excel中讀取資料存入陣列

rawdata = xlrd.open_workbook('kmeansdata.xlsx')

table = rawdata.sheets()[0]

data =

for i in range(table.nrows):

if i == 0:

continue

else:

featurelist = ['age', 'gender', 'degree']

mdl = pd.dataframe.from_records(data, columns=featurelist)

# '利用sse選擇k'

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

for k in range(1, 9):

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

estimator.fit(np.array(mdl[['age', 'gender', 'degree']]))

x = range(1, 9)

plt.xlabel('k')

plt.ylabel('sse')

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

plt.show()

效果圖:

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

②輪廓係數法

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

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

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

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

python**:

import pandas as pd

import numpy as np

from sklearn.cluster import kmeans

from sklearn.metrics import silhouette_score

import matplotlib.pyplot as plt

import xlrd

# 從excel中讀取資料存入陣列

rawdata = xlrd.open_workbook('kmeansdata.xlsx')

table = rawdata.sheets()[0]

data =

for i in range(table.nrows):

if i == 0:

continue

else:

featurelist = ['age', 'gender', 'degree']

mdl = pd.dataframe.from_records(data, columns=featurelist)

scores = # 存放輪廓係數

for k in range(2, 9):

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

estimator.fit(np.array(mdl[['age', 'gender', 'degree']]))

x = range(2, 9)

plt.xlabel('k')

plt.ylabel('輪廓係數')

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

plt.show()

效果圖:

說明:建議比較兩個方法選出的k值,如果沒有特殊情況的話,建議首先考慮用手肘法。

參考資料:

姊妹篇:python進行kmeans聚類

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值的選取

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

K means聚類最優k值的選取

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