機器學習之K Means聚類演算法

2021-08-21 11:22:54 字數 4199 閱讀 2461

python**實現k-means演算法和二分k-means聚類演算法(用到的資料集testset2.txt)

from numpy import *

defloaddataset

(filename):

datamat =

fr = open(filename)

for line in fr.readlines():

curline = line.strip().split('\t')

fltline = list(map(float,curline))

return datamat

defdisteclud

(veca,vecb):

#計算歐氏距離

return sqrt(sum(power(veca-vecb,2)))

defrandcent

(dataset,k):

#隨機生成乙個聚類中心

n = shape(dataset)[1]

centroids = mat(zeros((k,n)))

for j in range(n):

minj = min(dataset[:,j])

rangej = float(max(dataset[:,j])-minj)

centroids[:,j] = minj + rangej * random.rand(k,1)

return centroids

#kmeans演算法,主要是通過兩個步驟進行迭代,1.計算損失,找距離最近的聚類中心,分配聚類中心

#2.根據每個聚類中心所屬資料,計算平均值更新聚類中心值

defkmeans

(dataset,k,distmeas=disteclud,createcent=randcent):

m = shape(dataset)[0]

clusterassment = mat(zeros((m,2)))

centroids = createcent(dataset,k)

clusterchanged = true

while clusterchanged:

clusterchanged = false

for i in range(m):

mindist = inf; minindex = -1

for j in range(k):

distji = distmeas(centroids[j,:],dataset[i,:])

if distji < mindist:

mindist = distji; minindex = j

if clusterassment[i,0] != minindex:

clusterchanged = true

clusterassment[i,:] = minindex,mindist**2

print(centroids)

for cent in range(k):

ptsinclust = dataset[nonzero(clusterassment[:,0].a==cent)[0]]

centroids[cent,:] = mean(ptsinclust,axis=0)

return centroids, clusterassment

#二分k-means演算法

defbikmeans

(dataset,k,distmeas=disteclud):

m = shape(dataset)[0]

clusterassment = mat(zeros((m,2)))

centroid0 = mean(dataset,axis=0).tolist()[0]

centlist = [centroid0]

for j in range(m):

clusterassment[j,1]=distmeas(mat(centroid0),dataset[j,:])**2

#迴圈迭代,直到聚類中心數目達到要求為止

while(len(centlist)for i in range(len(centlist)):

ptsincurrcluster = dataset[nonzero(clusterassment[:,0].a==i)[0],:] #找屬於當前聚類中心i的所有資料點

centroidmat,splitclustass = kmeans(ptsincurrcluster,2,distmeas) #利用k-means演算法將找到的屬於當前聚類中心的資料,再進k=2的聚類

ssesplit = sum(splitclustass[:,1]) #上面進行聚類運算元據點的所有損失

ssenotsplit = sum(clusterassment[nonzero(clusterassment[:,0].a!=i)[0],1]) #沒進行上面聚類的所有資料點的損失

print("ssesplit, and notsplit:",ssesplit,ssenotsplit)

if(ssesplit+ssenotsplit) < lowestsse: #如果兩者相加小於當前最小損失,即上面的分類時有效果的

bestcenttosplit = i #記錄下當前最好的切分類號,即這個類還可以繼續劃分

bestnewcents = centroidmat #記錄下上面分類返回的兩個聚類中心

bestclustass = splitclustass.copy() #記錄下上面聚類返回的資料點及對應的分配的新聚類中心編號(0,1)

lowestsse = ssesplit + ssenotsplit #更新最小損失值

#下面兩行**,將當前找到的最好的切分點(即類別號)切分出來的新類0,仍然沿用改最好的切分點,

#而新類1,則直接分配給當前最大的類別號(注意分類的類號是從0開始的,所以len(centlist)這個數字還沒有使用)

bestclustass[nonzero(bestclustass[:,0].a == 1)[0],0] = len(centlist)

bestclustass[nonzero(bestclustass[:,0].a == 0)[0],0] = bestcenttosplit

print('the bestcenttosplit is:',bestcenttosplit)

print('the len of bestclustass is:',len(bestclustass))

#這裡bestnewcents是matrix型,為了方便後面centlist裡的元素都是一維的,繼而返回時轉換為mat,所以轉換為array型

bestnewcents = array(bestnewcents)

#下面兩行**和上面兩行**類似,將最好切分點的聚類中心修改為,新劃分的0號的聚類中心,再將1號的聚類中心加入聚類中心list中

centlist[bestcenttosplit] = bestnewcents[0,:]

clusterassment[nonzero(clusterassment[:,0].a == bestcenttosplit)[0],:] = bestclustass

return mat(centlist),clusterassment

datmat = mat(loaddataset('./testset2.txt'))

mycentroids,clusterassing = kmeans(datmat,3)

centlist,mynewassments = bikmeans(datmat,3)

輸出結果如下圖

聚類是一種無監督的學習演算法,所謂無監督就是指事先並不知道要尋找的內容,即沒有目標變數,聚類將資料點歸到多個簇中,其中相似資料點處於同一簇中,而不相似資料點處於不同簇中。k-means演算法使用非常廣泛,以k個隨機質心開始,演算法會計算每個點到質心的距離,每個點會被分配到距其最近的簇的質心,然後緊接著基於新分配到簇的點更新簇質心,以上過程重複數次,直到簇質心不再改變。這個簡單的演算法非常有效,但也容易受初始質心的影響,為了獲得更好的聚類效果,又介紹了二分k-means聚類演算法,二分k-means聚類演算法首先將所有的點作為乙個簇,然後使用k-means(k=2)進行劃分,下一次迭代時,選擇有最大誤差的簇進行劃分,該過程重複迭代直到k個簇建立成功為止。整體來說,二分k-means的聚類效果要好於k-means演算法。

機器學習之聚類演算法 K Means

參考 聚類演算法可以分為 中心點方法 層次聚類方法 基於密度方法 基於網格 基於模型方法。其中最為經典的是k means演算法 k means屬於中心點方法 也有叫劃分方法 演算法經典簡單。演算法 人工選取k值,並選取k個點作為k個簇的質心 對所有樣本分別計算到k個簇的質心的距離 歐式或者曼哈頓 取...

機器學習演算法 之K means聚類

1.模型 k means演算法並沒有顯式的數學模型,演算法的目的是從資料集中得到k個中心點,每個中心點及其周圍的點形成乙個聚簇。k means是一種無監督的學習模型。k means的學習目標如下圖所示 2.策略 k mean演算法採用的損失函式是平方損失函式。每個簇的點距離中心的平方距離之和構成損失...

機器學習之K means聚類演算法

k均值演算法的計算過程非常直觀 1 從d中隨機取k個元素,作為k個簇的各自的中心。2 分別計算剩下的元素到k個簇中心的相異度,將這些元素分別劃歸到相異度最低的簇。3 根據聚類結果,重新計算k個簇各自的中心,計算方法是取簇中所有元素各自維度的算術平均數。4 將d中全部元素按照新的中心重新聚類。5 重複...