k均值聚類 注釋

2021-10-07 06:39:00 字數 3467 閱讀 4388

**全是《機器學習》上的,只是將其整合到了一起,能夠執行手寫體識別。

內容大部分進行了注釋,可能有些注釋不夠精準或者不容理解,見諒!

import numpy as np #用來調整陣列和矩陣

import matplotlib as mpl #用來設定字型和正負號

import matplotlib.pyplot as plt #畫圖框

import warnings #用來設定警告

datamat= [[0.697, 0.460],[0.774, 0.376],[0.634, 0.264],[0.608, 0.318],\

[0.556, 0.215],[0.430, 0.237],[0.481, 0.149],[0.437, 0.211],\

[0.666, 0.091],[0.243, 0.267],[0.245, 0.057],[0.343, 0.099],\

[0.639, 0.161],[0.657, 0.198],[0.360, 0.370],[0.593, 0.042],\

[0.719, 0.103],[0.359, 0.188],[0.339, 0.241],[0.282, 0.257],\

[0.748, 0.232],[0.714, 0.346],[0.483, 0.312],[0.478, 0.437],\

[0.525, 0.369],[0.751, 0.489],[0.532, 0.472],[0.473, 0.376],\

[0.725, 0.445],[0.446, 0.459]] #輸入資料

def disteclud(veca, vecb): #計算距離

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

def randcent(dataset, k): #構建質心

warnings.******filter("ignore") #將警告忽略掉

n = np.shape(dataset)[1] #記錄矩陣的寬度

centroids = np.mat(np.zeros((k, n))) #生成乙個矩陣用來存放質心

for j in range(n):

minj = min (dataset[:,j])

rangej = float(max(dataset[:, j]) - minj) #確定隨機點再資料集內

centroids[:, j] = minj + rangej * np.random.rand(k, 1) # 構建簇質心

return centroids

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

m = np.shape(dataset)[0] # 矩陣行數

clusterassment = np.mat(np.zeros((m, 2))) #記錄簇索引和誤差

centroids = createcent(dataset, k) #質心

clusterchanged = true

while clusterchanged:

clusterchanged = false

for i in range(m):

mindist = np.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#更新簇分配結果矩陣中該點對應的簇索引和最小距離

for cent in range(k):

ptsinclust = dataset[np.nonzero(clusterassment[:, 0].a == cent)[0]]]#獲取簇分配結果矩陣中屬於當前cent簇的所有索引列表,並對應到資料集中的點,全部取出放入新的列表

centroids[cent, :] = np.mean(ptsinclust, axis=0) #對得到的列表按列取均值,作為該簇的最新的質心放入簇質心列表

return centroids, clusterassment

def testkmeans(k):

global datamat

datamat = np.mat(datamat)

mycentroids, clustassing = kmeans(datamat, k)

print ('mycentroids:\n', mycentroids)

mpl.rcparams['font.sans-serif'] = [u'simhei'] # 指定顯示字型

mpl.rcparams['axes.unicode_minus'] = false # 解決儲存影象中負號'-'顯示為方塊的問題

plt.figure(1, facecolor='white') # 建立乙個新圖形, 背景色設定為白色

plt.scatter(np.array(mycentroids[:, 0]), np.array(mycentroids[:, 1]), marker='+', alpha=1, s=150) #繪製質心

for cent in range(k): #開始繪製西瓜資料的點

xing=['o','v','^','1','2','3','*','s','+','d','x'] #設定形狀

ptsinclust = datamat[np.nonzero(clustassing[:, 0].a == cent)[0]]

plt.scatter(np.array(ptsinclust[:, 0]), np.array(ptsinclust[:, 1]), marker=xing[cent], alpha=1) #設定畫點時的形狀

plt.show()

if __name__=='__main__':

k_numy=int(input("請輸入質心數:"))

testkmeans(k_numy) #畫圖

質心為6:

質心為5:

質心為3:

K 均值聚類

剛剛寫了篇分級聚類的,趁著餘熱,再寫一下關於k 均值聚類的。為了突出k 均值聚類的特點,先黑一下分級聚類。跟k 均值聚模擬起來,分級聚類演算法有一下缺點 第一,的那個沒有額外投入的時候,樹形試圖是不會真正將資料拆分成不同組的。第二,分級聚類的計算演算法計算量相當大。當兩個節點合併之後,節點之間的距離...

k均值聚類

k均值聚類就是利用歐氏距離的度量將距離相近的樣本分為k類 a.假設有m個樣本,首先隨機選擇k個樣本作為聚類的質心 要分成k類 b.然後對於每個樣本,計算它到每個質心的距離,將它歸類於距離最小的那個質心 c.接著對初步分類的k個類別重新計算該類的質心,也就是對每個類別的樣本座標求平均 d.重複 b 步...

k均值聚類演算法

輸入 簇的數目k和包含n個物件的資料庫。輸出 k個簇,使平方誤差準則最小。演算法步驟 1.為每個聚類確定乙個初始聚類中心,這樣就有k 個初始聚類中心。2.將樣本集中的樣本按照最小距離原則分配到最鄰近聚類 3.使用每個聚類中的樣本均值作為新的聚類中心。4.重複步驟2.3直到聚類中心不再變化。5.結束,...