網(wǎng)站制作模板下載/公司宣傳軟文
K均值聚類方法是一種劃分聚類方法,它是將數(shù)據(jù)分成互不相交的K類。K均值法先指定聚類數(shù),目標(biāo)是使每個(gè)數(shù)據(jù)到數(shù)據(jù)點(diǎn)所屬聚類中心的總距離變異平方和最小,規(guī)定聚類中心時(shí)則是以該類數(shù)據(jù)點(diǎn)的平均值作為聚類中心。
?
01K均值法原理與步驟
對于有N個(gè)數(shù)據(jù)的數(shù)據(jù)集,我們想把它們聚成K類,開始需要指定K個(gè)聚類中心,假設(shè)第i類有ni個(gè)樣本數(shù)據(jù),計(jì)算每個(gè)數(shù)據(jù)點(diǎn)分別到聚類中心的距離平方和,距離這里直接用的歐式距離,還有什么海明距離、街道距離、余弦相似度什么的其實(shí)都可以,這里聚類的話,歐式距離就好。
(1)、所有類別樣本數(shù)等于總樣本數(shù),即每個(gè)類類是互不相同的
(2)、每一類(假設(shè)是第i類)中數(shù)據(jù)點(diǎn)到聚類中心距離平方總和di為:
xi表示第i類各點(diǎn)平均值(聚類中心)
(3)、K類數(shù)據(jù)點(diǎn)距離之和為:
這樣就會(huì)有一個(gè)KN的距離平方和矩陣,每一列(比如第j列)的最小值對應(yīng)的行數(shù)(比如第i行)就表明:第j個(gè)數(shù)據(jù)樣本屬于第i類別。這樣,每個(gè)數(shù)據(jù)就會(huì)分別屬于不同的類別了。
比如,表格中紅色部分?jǐn)?shù)據(jù)點(diǎn)x2到第一類的聚類中心距離最小,則x2就屬于第一類。
K均值步驟:
- 隨機(jī)選取K個(gè)數(shù)據(jù)點(diǎn)作為(起始)聚類中心;
- 按照距離最近原則分配數(shù)據(jù)點(diǎn)到對應(yīng)類;
- 計(jì)算每類的數(shù)據(jù)點(diǎn)平均值(新的聚類中心);
- 計(jì)算數(shù)據(jù)點(diǎn)到聚類中心總距離;
- 如果與上一次相比總距離下降,聚類中心替換;
- 直到總距離不再下降或者達(dá)到指定計(jì)算次數(shù)。
其實(shí),這個(gè)過程相對比較簡單,給我一組聚類中心,總能根據(jù)到聚類中心距離最小原則生成一組聚類方案,然后計(jì)算各個(gè)類別到聚類中心距離總和是否下降,如果距離總和下降,就繼續(xù)計(jì)算每類數(shù)據(jù)點(diǎn)平均值(新的聚類中心),對應(yīng)的聚類方案要好(還是那句話:給我一組聚類中心,總能根據(jù)到聚類中心距離最小原則生成一組聚類方案),然后不斷計(jì)算,直到距離總和下降幅度很小(幾乎收斂),或者達(dá)到指定計(jì)算次數(shù)。
K-means算法缺點(diǎn)主要是:
- 對異常值敏感;
- 需要提前確定k值;
- 結(jié)果不穩(wěn)定;
02 K均值算法Python的實(shí)現(xiàn)
思路:
- 首先用random模塊產(chǎn)生隨機(jī)聚類中心;
- 用numpy包簡化運(yùn)算;
- 寫了一個(gè)函數(shù)實(shí)現(xiàn)一個(gè)中心對應(yīng)一種聚類方案;
- 不斷迭代;
- matplotlib包結(jié)果可視化。
代碼如下:
- import numpy as np
- import random as rd
- import matplotlib.pyplot as plt
- import math
- #數(shù)據(jù)
- dat = np.array([[14,22,15,20,30,18,32,13,23,20,21,22,23,24,35,18],
- [15,28,18,30,35,20,30,15,25,23,24,25,26,27,30,16]])
- print(dat)
- #聚類中心#
- n = len(dat[0])
- N = len(dat)n
- k = 3
- #-------隨機(jī)產(chǎn)生-----#
- center = rd.sample(range(n),k)
- center = np.array([dat.T[i] for i in center])
- print(‘初始聚類中心為:’)
- print(center)
- print(‘-----------------------’)
- ?
- #計(jì)算聚類中心
- def cent(x):
- return(sum(x)/len(x))
- ?
- #計(jì)算各點(diǎn)到聚類中心的距離之和
- def dist(x):
- #聚類中心
- m0 = cent(x)
- dis = sum(sum((x-m0)2))
- return(dis)
- ?
- #距離
- def f(center):
- c0 = []
- c1 = []
- c2 = []
- D = np.arange(k*n).reshape(k,n)
- d0 = center[0]-dat.T
- d1 = center[1]-dat.T
- d2 = center[2]-dat.T
- d = np.array([d0,d1,d2])
- for i in range(k):
- D[i] = sum((d[i]2).T)
- for i in range(n):
- ind = D.T[i].argmin()
- if(ind 0):
- c0.append(i)#分配類別
- else:
- if(ind 1):
- c1.append(i)
- else:
- c2.append(i)
- C0 = np.array([dat.T[i] for i in c0])
- C1 = np.array([dat.T[i] for i in c1])
- C2 = np.array([dat.T[i] for i in c2])
- C = [C0,C1,C2]
- print([c0,c1,c2])
- s = 0
- for i in C:
- s+=dist(i)
- return(s,C)
- ?
- n_max = 50
- #初始距離和
- print(‘第1次計(jì)算!’)
- dd,C = f(center)
- print(‘距離和為’+str(dd))
- print(‘第2次計(jì)算!’)
- center = [cent(i) for i in C]
- Dd,C = f(center)
- print(‘距離和為’+str(Dd))
- K = 3
- ?
- while(K<n_max):
- #兩次差值很小并且計(jì)算了一定次數(shù)
- if(math.sqrt(dd-Dd)<1 and K>20):
- break;
- print(‘第’+str(K)+‘次計(jì)算!’)
- dd = Dd
- print(‘距離和為’+str(dd))
- #當(dāng)前聚類中心
- center = [cent(i) for i in C]
- Dd,C = f(center)
- K+=1
- ?
- ?
- #—聚類結(jié)果可視化部分—#
- ?
- j = 0
- for i in C:
- if(j 0):
- plt.plot(i.T[0],i.T[1],‘ro’)
- if(j 1):
- plt.plot(i.T[0],i.T[1],‘b+’)
- if(j == 2):
- plt.plot(i.T[0],i.T[1],‘g*’)
- j+=1
- ?
- plt.show()
?
(1):聚類成功的例子:
對于不合適的初始隨機(jī)聚類中心,一般而言不會(huì)失敗,成功次數(shù)較多。
可以看出,其實(shí)第五次就收斂了,共分成了三類。它們的標(biāo)簽序號(hào)為:
第一類:[1, 3, 8, 9, 10, 11, 12, 13];
第二類:[4, 6, 14];
第三類:[0, 2, 5, 7, 15]
聚類圖:
聚類結(jié)果與實(shí)際情況一致
(2):聚類失敗的例子:
有時(shí)候可能會(huì)失敗,運(yùn)行實(shí)驗(yàn)了三次出現(xiàn)了一次敗筆,迭代過程如下:
散點(diǎn)圖:
聚類失敗圖
顯然,由于初始點(diǎn)的隨機(jī)選取不當(dāng),導(dǎo)致聚類嚴(yán)重失真!這聚類效果明顯就很差,表明隨機(jī)產(chǎn)生的初始聚類中心應(yīng)該不合適,最后不管怎么迭代,都不可能生成合適的聚類了,這與k-means算法的原理確實(shí)可以解釋的。這就是k-means的最顯著的缺點(diǎn)!
03K均值算法的R語言實(shí)現(xiàn)
用的還是上面程序一樣的數(shù)據(jù),R語言聚類就很方便,直接調(diào)用kmeans(data,聚類數(shù))就能方便完成:
- rm(list = ls())
- path <- ‘C:\Users\26015\Desktop\clu.txt’
- dat <- read.csv(path,header = FALSE)
- dat <- t(dat)
- kc <- kmeans(dat,3)
- summary(kc)
- kc
查看聚類結(jié)果:
- K-means clustering with 3 clusters of sizes 8, 3, 5
- ?
- Cluster means:
- [,1] [,2]
- 1 21.87500 26.00000
- 2 32.33333 31.66667
- 3 15.60000 16.80000
聚成3類,分別有8,3,5個(gè)數(shù)據(jù)
Clustering vector:
V1? V2? V3? V4? V5? V6? V7? V8? V9
3?? 1?? 3??1?? 2?? 3?? 2?? 3??1
V10 V11 V12 V13 V14 V15 V16
1?? 1?? 1?? 1?? 1?? 2?? 3
第一類:2,4,9,10,11,12,13,14
第二類:1,3,6,8,16;
第三類:5,7,15
由于Python下標(biāo)是從“0”開始,所以兩種方法聚類結(jié)果實(shí)際上是一樣的!