kmeans 聚類 k 值優化


kmeans 中k值一直是個令人頭疼的問題,這里提出幾種優化策略。

 

手肘法

核心思想

1. 肉眼評價聚類好壞是看每類樣本是否緊湊,稱之為聚合程度;

2. 類別數越大,樣本划分越精細,聚合程度越高,當類別數為樣本數時,一個樣本一個類,聚合程度最高;

3. 當k小於真實類別數時,隨着k的增大,聚合程度顯著提高,當k大於真實類別數時,隨着k的增大,聚合程度緩慢提升;

4. 大幅提升與緩慢提升的臨界是個肘點;

5. 評價聚合程度的數學指標類似 mse,均方差,是每個類別的樣本與該類中心的距離平方和比上樣本數

 

示例代碼

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
from sklearn.cluster import KMeans
from scipy.spatial.distance import cdist
# 1 數據可視化
cluster1 = np.random.uniform(0.5, 1.5, (2, 10))
cluster2 = np.random.uniform(3.5, 4.5, (2, 10))
X = np.hstack((cluster1, cluster2)).T
plt.figure()
plt.axis([0, 5, 0, 5])
plt.grid(True)
plt.plot(X[:, 0], X[:, 1], 'k.')
plt.show()

# 2 肘部法求最佳K值
K = range(1, 10)
mean_distortions = []
for k in K:
    kmeans = KMeans(n_clusters=k)
    kmeans.fit(X)
    mean_distortions.append(
        sum(
            np.min(
                cdist(X, kmeans.cluster_centers_, metric='euclidean'), axis=1))
        / X.shape[0])
plt.plot(K, mean_distortions, 'bx-')
plt.xlabel('k')
font = FontProperties(fname=r'c:\windows\fonts\msyh.ttc', size=20)
plt.ylabel(u'平均畸變程度', fontproperties=font)
plt.title(u'用肘部法確定最佳的K值', fontproperties=font)
plt.show()

 

輸出手肘圖

 可以明顯看出紅色圓圈是個肘點。

 

缺點

1. 不是所有的數據都能呈現這樣明顯的肘點;

2. 單純地以數據選擇k值,可能脫離實際;

 

補充

在實際任務中,我們可能根據業務來確定 k 值,如區分男女,k=2,區分人種,k=3,黃黑白;

 

輪廓系數法

結合類內聚合度和類間分離度來評價聚類效果。

 

計算方法

1. 計算樣本 i 到同簇內其他樣本的平均距離 ai;【ai越小,說明該樣本越應該被分到該簇,故可將 ai 視為簇內不相似度】

2. 計算簇內所有樣本的 ai;

3. 計算樣本 i 到其他簇內所有樣本的平均距離 bi,並取min;【bi 視為 i 的類間不相似度,bi為i到其他類的所有bi中min,bi越大,越不屬於其他類】

4. 樣本 i 的簇內不相似度 ai 和類間不相似度 bi,計算輪廓系數

□ s_i 越接近1, 則說明樣本 i 聚類合理。

□ s_i 越接近-1,說明樣本 i 更適合聚到其他類

□ s_i 越接近0,則說明樣本 i 在兩個簇的邊界上

 

這種方法計算量大,視情況使用。

 

 

 

參考資料:

https://blog.csdn.net/xiligey1/article/details/82457271

https://www.jianshu.com/p/f2b3a66188f1


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM