一.方法和演算法流程:
k-means是劃分方法中較經典的聚類演算法之一。由於該演算法的效率高,所以在對大規模資料進行聚類時被廣泛應用。目前,許多演算法均圍繞著該演算法進行擴充套件和改進。
k-means演算法以k為引數,把n個樣本分成k個簇,使簇內具有較高的相似度,而簇間的相似度較低。k-means演算法的處理過程如下:首先,隨機地 選擇k個樣本,每個樣本初始地代表了乙個簇的平均值或中心;對剩餘的每個樣本,根據其與各簇中心的距離,將它賦給最近的簇;然後重新計算每個簇的平均值。 這個過程不斷重複,直到準則函式收斂。
m個樣本
偽**如下:
記k個簇中心分別為u1,u2,u3……uk,每個簇的樣本數目為n1、n2……nk。
使用平方誤差做為誤差函式,得:
將該函式做為目標函式,求解該函式的最小值。可以使用梯度下降法求,該函式為凸函式,駐點為:
可以看到,要想使損失函式最小,聚類中心要為各簇中樣本點的平均值。由此可以看出,k-means演算法在每次迭代更新時使用各簇中樣本點的平均值為聚類中心是有道理的。
誤差函式使用曼哈頓距離時,簇中心點是各樣本點的中值;
解釋:在整個過程中都是使聚類的距離達到最小;
在當前簇劃分下,尋找新的簇中心點使得當前簇劃分下的距離達到最小;然後每個點尋找離自己最近的中心點,重新劃分簇,使得聚類距離進一步縮小,以此迴圈;當達到聚類距離最小時,重新劃分簇,再求中心點,中心點不再發生變化;
具體k-means演算法的執行過程可以參加下圖:
二.初值敏感:
k-means演算法的問題:k-means演算法是將簇中左右點的均值做為新的質心,但是當有異常值是,質心可能就會離大多數點比較遠。比如1,2,3,4,100五個樣本,均值是22,這樣類別中心就離樣本較遠,這時選取中位數做為質心是更好的選擇,這就是k-mediods(k-中值)聚類演算法。同時k-means是初值敏感的,即當選取不同的初始值時分類結果可能不同,如下圖:
三.總結:
優點:1、解決聚類問題的經典演算法,簡單、快速
2、當處理大資料集時,該演算法保持可伸縮性和高效率
3、當簇近似為高斯分布時,它的效果較好;
缺點:1、在簇的平均值可被定義的情況下才能使用,可能不適用於某些應用
2、k值的選擇是使用者指定的,不同的k得到的結果會有挺大的不同
改進:對k的選擇可以先用一些演算法分析資料的分布,如重心和密度等,然後選擇合適的
k3.對
k個初始質心的選擇比較敏感,容易陷入區域性最小值
改進:二分k均值(
bisecting k-means
)演算法,它對初始的
k個質心的選擇就不太敏感
4、不適合非凸形狀的簇或者大小差別很大的簇
4、對雜訊和孤立點敏感
5.資料
集比較大的時候,收斂會比較慢
。四.**實現:
注:1.每次重新構建的中心點不一定是存在的點,而是多個維度的中心;
from numpy import *
# 計算歐幾里得距離
def disteclud(veca, vecb):
return sqrt(sum(power(veca - vecb, 2))) # 求兩個向量之間的距離
# 構建聚簇中心,取k個(此例中為4)隨機質心
def randcent(dataset, k):
n = shape(dataset)[1] #特徵數
centroids = mat(zeros((k,n))) # 每個質心有n個座標值,總共要k個質心
#print(centroids)
for j in range(n):
minj = min(dataset[:,j])
maxj = max(dataset[:,j])
rangej = float(maxj - minj)
centroids[:,j] = minj + rangej * random.rand(k, 1)
#print(centroids)
return centroids
#x軸隨機值,y值隨機值
#k-means 聚類演算法
def kmeans(dataset, k, distmeans =disteclud, createcent = randcent):
m = shape(dataset)[0] #樣本數
clusterassment = zeros((m,2)) # 用於存放該樣本屬於哪類及質心距離
# clusterassment第一列存放該資料所屬的中心點,第二列是該資料到中心點的距離
centroids = createcent(dataset, k)
#print("-----",centroids)
clusterchanged = true # 用來判斷聚類是否已經收斂
while clusterchanged:
clusterchanged = false
for i in range(m): # 把每乙個資料點劃分到離它最近的中心點
mindist = inf;
minindex = -1;
for j in range(k):
distji = distmeans(centroids[j,:], dataset[i,:])
if distji < mindist:
mindist = distji;
minindex = j # 如果第i個資料點到第j個中心點更近,則將i歸屬為j
if clusterassment[i,0] != minindex:
clusterchanged = true; # 如果分配發生變化,則需要繼續迭代
clusterassment[i,:] = minindex,mindist**2 # 並將第i個資料點的分配情況存入字典
#0,1,2,3四個聚簇中心點index
for cent in range(k): # 重新計算中心點
ptsinclust = dataset[clusterassment[:,0]==cent] # 去第一列等於cent的所有列
centroids[cent,:] = mean(ptsinclust, axis = 0) # 算出這些資料的中心點
return centroids,clusterassment
K Means聚類演算法
k means聚類演算法 intergret kmeans演算法的基本思想是初始隨機給定k個簇中心,按照最鄰近原則把待分類樣本點分到各個簇。然後按平均法重新計算各個簇的質心,從而確定新的簇心。一直迭代,直到簇心的移動距離小於某個給定的值。k means聚類演算法主要分為三個步驟 1 第一步是為待聚類...
聚類演算法 K means
演算法接受引數 k 然後將事先輸入的n個資料物件劃分為 k個聚類以便使得所獲得的聚類滿足 同一聚類中的物件相似度較高 而不同聚類中的物件相似度較小。聚類相似度是利用各聚類中物件的均值所獲得乙個 中心物件 引力中心 來進行計算的。k means演算法是最為經典的基於劃分的聚類方法,是十大經典資料探勘演...
k means聚類演算法
說到聚類,得跟分類區別開來,分類是按人為給定的標準將樣本歸到某個類別中去,在機器學習中多是監督學習,也就是訓練樣本要給標籤 正確的類別資訊 而聚類是在某種規則下自動將樣本歸類,在機器學習中是無監督學習,不需要提前給樣本打標籤。k means聚類演算法,就是在某種度量方式下,將樣本自動劃分到k個類別中...