聚类算法:K-Means
1.K-Means定義:
K-Means是一種無監督的基于距離的聚類算法,簡單來說,就是將無標簽的樣本劃分為k個簇(or類)。它以樣本間的距離作為相似性的度量指標,常用的距離有曼哈頓距離、歐幾里得距離和閔可夫斯基距離。兩個樣本點的距離越近,其相似度就越高;距離越遠,相似度越低。
目的是,實現簇內的距離盡量小(緊湊),而簇間的距離盡可能大(分開)。 我們使用誤差平方和SSE作為聚類質量的目標函數,該值越小表明樣本簇內較緊密。
1.1關鍵問題:
- (1)k值的選擇(法一:根據經驗;法二:借助交叉驗證選。評價k值的好壞,有手肘法(以簇內誤差平方和SSE作為度量聚類質量的目標函數,以誤差平方和較小的作為最終聚類結果,通過作圖,快速辨認變化較大對應的k值,參考劉順祥kmeans實操內容)、輪廓系數Silhouette Coefficient(from sklearn.metrics import silhouette_score 可計算,結果在[-1,1]之間,越大代表內聚度和分離度相對較好)和Calinski-Harabasz Index(在sklearn中,有metrics.calinski_harabaz_score,分數越高越好)。
- (2)k個質心的選擇方式 (質心之間最好不要太近)
1.2例子講解:
借助下圖,講解最簡單的2個分類問題:
(a)給出的樣本數據
(b)隨機選取2個樣本點作為質心,一個紅色a1,一個藍色b1(選取的樣本可以不在原始樣本中)
(c)計算所有樣本到這兩個質心的距離,and then 將樣本劃分到兩個距離中距離較小的那一類中。于是,樣本分成了紅藍兩派。
(d)對c圖中的紅藍兩派,找出對應簇的新的質心:a2、b2,并標記其位置。
(e)重新計算所有樣本到質心:a2、b2的距離,and then 將樣本劃分到兩個距離中距離較小的那一類中。于是,樣本被重新劃分成了兩類。
(f)重復d、e步,直到質心的位置不再變化。
2.python操作:
在sklearn中,一般用sklearn.cluster.KMeans解決問題。
針對數據量非常大的情況,如樣本量>10萬,特征數量>100。這時就要用Mini Batch K-Means解決問題。它抽取原始樣本中的部分樣本作為新的樣本集來聚類,這樣會降低聚類的精確度(這一般在可接受范圍內),但是減少了計算的時間。
python官方文檔:
- sklearn.cluster.KMeans:
https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans - sklearn.cluster.MiniBatchKMeans:
https://scikit-learn.org/stable/modules/generated/sklearn.cluster.MiniBatchKMeans.html
2.1 KMeans類
sklearn中的KMeans算法僅支持歐式距離,因為其他距離不能保證算法的收斂性。
class sklearn.cluster.KMeans(n_clusters=8, init=’k-means++’, n_init=10, max_iter=300, tol=0.0001, precompute_distances=’auto’, verbose=0, random_state=None, copy_x=True, n_jobs=None, algorithm=’auto’)
- (1)n_clusters :聚類個數k,默認為8.
- (2)init :{‘k-means++’, ‘random’ or an ndarray} ,質心的選擇方式, 默認為‘k-means++’.
‘random’:隨機選取k個質心.
‘k-means++’ :普通版KMeans的優化版,隨機選取一個質心后,計算所有樣本到質心1的距離,然后根據距離選取新的質心2,接著計算樣本到最近質心的距離,再選出質心3,重復計算距離,直至找到k個質心為止。是對隨機選取的一個優化版。 - (3)n_init :int,默認為10.
設置重復該算法次數m,每次選取不一樣的質心,然后選取這m個結果的最優output。 - (4)max_iter :int, default: 300
單次運行的k-means算法的最大迭代次數 - (5)random_state :設置數據復現的參數
- (6)algorithm :有三種參數設置,“auto”, “full” or “elkan”,默認是”auto”.
最基礎的KMeans用“full”,而“elkan”利用三角不等式(兩邊之和大于第三邊、兩邊之差小于第三邊)減少距離的計算,加快算法的迭代速度,是對基本版KMeans的優化,但它不適用于稀疏數據. 對于稠密數據,“auto” 會選用“elkan” ,對于稀疏數據,會用 “full”.
對應Attributes:
- (1)cluster_centers_ : 輸出聚類的質心
- (2)labels_ :輸出樣本聚類后所屬的類別
- (3)inertia_ : 浮點型,輸出簇內離差平方和
- (4)n_iter_ : 整數,輸出運行的迭代次數
先用make_blobs產生聚類數據,再用KMeans進行分類
from sklearn.datasets import make_blobs #產生聚類數據 #5000個樣本,每個樣本有兩個特征,質心為centers所給出,此例中有4個質心,每個類的方差由cluster_std給出,random_state為數據復現用 x, y = make_blobs(n_samples=3000, n_features=2, centers=[[-1,-1], [0,0], [1,1], [2,2]], cluster_std=[0.4, 0.7, 0.2, 0.2], random_state =2019) #作圖看原始數據 import matplotlib.pyplot as plt %matplotlib inline plt.scatter(x[:, 0],x[:,1]) <matplotlib.collections.PathCollection at 0xc431eefc18>令k=2、3、4,然后評估每個k值的好壞
from sklearn.cluster import KMeans y_1 = KMeans(n_clusters=2, random_state=2020).fit_predict(x) plt.scatter(x[:, 0], x[:, 1],c=y_1) from sklearn import metrics metrics.calinski_harabaz_score(x,y_1) 8255.3432347343351隨著k的遞增,Calinski-Harabaz Index的分數也越來越高。分類成4個簇的分類效果最好。
也可以利用簇內誤差平方和來選擇最佳K值:
SSE = [] for i in range(1,11): #k取1-10,計算簇內誤差平方和km = KMeans(n_clusters=i, random_state=2019)km.fit(x)SSE.append(km.inertia_) plt.plot(range(1,11), SSE, marker='v') plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標簽 plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號 plt.xlabel('k值', size=15) plt.ylabel('簇內誤差平方和SSE', size=15) <matplotlib.text.Text at 0xb6d86b1c88>2.2 MiniBatchKMeans類
class sklearn.cluster.MiniBatchKMeans(n_clusters=8, init=’k-means++’, max_iter=100, batch_size=100, verbose=0, compute_labels=True, random_state=None, tol=0.0, max_no_improvement=10, init_size=None, n_init=3, reassignment_ratio=0.01)
- (1)n_init:用不同的初始化質心運行算法的次數。每次用不一樣的采樣數據集來跑不同的初始化質心運行算法,與KMeans類有所區別。
- (2)batch_size:指定采集樣本的大小,默認是100.如果數據集的類別較多或者噪音點較多,需要增加這個值以達到較好的聚類效果。
- (3)init_size: 用來做質心初始值候選的樣本個數,默認是batch_size的3倍,一般用默認值就可以了。
- (4)reassignment_ratio: 某個類別質心被重新賦值的最大次數比例,這個和max_iter一樣是為了控制算法運行時間的。這個比例是占樣本總數的比例,乘以樣本總數就得到了每個類別質心可以重新賦值的次數。如果取值較高的話算法收斂時間可能會增加,尤其是那些暫時擁有樣本數較少的質心。默認是0.01。如果數據量不是超大的話,比如1w以下,建議使用默認值。如果數據量超過1w,類別又比較多,可能需要適當減少這個比例值。具體要根據訓練集來決定。
- (5)max_no_improvement:即連續多少個Mini Batch沒有改善聚類效果的話,就停止算法, 和reassignment_ratio, max_iter一樣是為了控制算法運行時間的。默認是10。
可以看到當抽取300個樣本數據出來做KMeans時,k從1—>4增大時,calinski_harabaz_score逐漸遞增。當k=4時,聚類效果最好,calinski_harabaz_score為9122。當k增大為5時,看到評分的下降,說明聚類為4類時最好。
抽樣與不抽樣的比較:用原始的3000個樣本數據時,當k=4時,calinski_harabaz_score為9151,大于抽樣時劃分4類時對應的評分:9122??梢娫谟眯颖緯r,精確度有所下降,但是最后聚類效果還是可以的。
3.KMeans的優缺點:
1.算法原理比較簡單,可解釋性強,對凸數據的收斂較快。
2.較適用于樣本集為團簇密集狀的,而對條狀、環狀等非團簇狀的樣本,聚類效果較一般。
3.對事先給定的k值、初始質心的選擇比較敏感,不同的選擇可能導致結果差異較大。
4.最后的結果為局部最優,而不是全局最優。
5.對噪點、異常點較敏感。
在實際操作中,注意:
(1)模型的輸入數據必須為數值型數據,如果是離散型,一定要做啞變量處理。
(2)此算法是基于距離運算的,為防止量綱帶來的影響,需要將數據標準化處理(零-均值規范)
(3)最終聚類分析算法的評價,可用RI評價法(蘭德指數)、F評價法、誤差平方和、輪廓系數(Silhouette)、calinski-harabaz Index等,參考https://www.cnblogs.com/niniya/p/8784947.html。
轉載于:https://www.cnblogs.com/wyy1480/p/10353342.html
總結
以上是生活随笔為你收集整理的聚类算法:K-Means的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Charles青花瓷抓包
- 下一篇: Yolov5目标检测模型运行遇到的相关问