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