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 重複...