機器學習作業9 k均值聚類

2021-08-13 09:46:19 字數 4576 閱讀 1382

k均值聚類,這次作業要求自動確定均值 = =

k均值聚類(固定k)大致步驟:

隨機選擇k個點作為初始的簇中心

計算每個點到每個簇中心的距離,選擇最小的作為該點屬於的簇類

將每個簇的點取平均獲得乙個新的簇中心

重複2、3步驟直至簇中心不再變化

輸出簇劃分

偽**表示(from書p203):

因為要確定k值,所以怕是沒法直接sklearn了

自己實現的kmeans,為了優雅,分了幾個函式,fit先初始化然後產生一開始的類簇

隨後的迴圈迭代兩行便是上面口述步驟的二三步:得到新分類,每個類計算新中心,收斂時結束。其中計算新分類呼叫了get_dist()計算距離矩陣,

class

kmeans:

data = np.array()

n, k = 0, 0

definit_center

(self):

center = # center of clusters

while len(center) < k: # 產生k個不重複的隨機數

cen = random.randint(0, n - 1)

if cen not

in center:

for i in range(len(center)): # 到data裡面取點

center[i] = data[center[i]]

return center

defget_dist

(self, center):

dist = np.zeros((n, k))

for j in range(n):

for i in range(k):

dist[j][i] = np.linalg.norm(center[i] - data[j])

return dist

defget_clusters

(self, center):

dist = self.get_dist(center)

label = np.argmin(dist, 1)

clusters =

for i in range(n):

return label, clusters

defnew_center

(self, label, clusters):

center =

for i in range(k):

return center

defover

(self, c0, c1):

for i in range(k):

print(c0[i]- c1[i])

if np.linalg.norm(c0[i]-c1[i]) > eps: return

false

return

true

deffit

(self, data, k):

self.data, self.k, self.n = data, k, len(data)

center0 = self.init_center()

while

true:

label, clusters = self.get_clusters(center0)

center1 = self.new_center(label, clusters)

if self.over(center0, center1): break

center0 = center1

return label

debug的時候用的樣例資料

data = np.array([[-9.38526262,  2.74797643],

[-11.8458768, 2.06863466],

[-0.84464735, -3.6778601 ],

[-9.55019081, 2.91500874],

[-0.29088953, -4.58059872],

[-0.90988716, -2.43335193],

[-9.82206029, 2.66678343],

[-0.28556052, -3.97549066],

[-1.51725199, -2.53455834],

[-10.6981788, 3.64205984]])

label = np.array([0, 0, 1, 0, 1, 1, 0, 1, 1, 0])

測試一下樣例資料

if __name__ == '__main__':

n, k = 10, 2

data, label = get_data(n, k)

cls = kmeans()

fit_label = cls.fit(data=data, k=k)

print(label)

print(fit_label)

結果

[ 0.87505124 -0.06011619]

[ 0. 0.]

[ 0. 0.]

[0 0 1 0 1 1 0 1 1 0]

[0 0 1 0 1 1 0 1 1 0]

與原先設定的label一模一樣,當然,迭代兩輪就結束了

為了寫**和除錯的方便,我在這裡之前都使用了樣例資料

def

get_data

(n, k):

# sample data, use in debug

''' data = np.array([[-9.38526262, 2.74797643],

[-11.8458768, 2.06863466],

[-0.84464735, -3.6778601 ],

[-9.55019081, 2.91500874],

[-0.29088953, -4.58059872],

[-0.90988716, -2.43335193],

[-9.82206029, 2.66678343],

[-0.28556052, -3.97549066],

[-1.51725199, -2.53455834],

[-10.6981788, 3.64205984]])

label = np.array([0, 0, 1, 0, 1, 1, 0, 1, 1, 0])

'''data, label = make_blobs(n_samples=n, n_features=2, centers=k)

return data, label

加大資料

再大我有點擔心機器效能了

試一下三維資料

很好,我大概成功造了乙個車輪

不會寫,抄了彭先生的

這裡參考了彭先生的方法,其實聚類的k值很大程度上看人的喜好(也就是分幾類),我們,就窮舉吧= =列舉我們需要的k,然後計算每次的類簇「半徑」,取半徑之和下降最快的k為我們要的k,在實際應用中,其實這就是個調參的過程

def

no_k_fit

(self, data):

central_dots, radius = , np.zeros(self.__max_k, np.float32)

# 尋找最佳的k值,k值範圍在1到max_k之間

for k in range(1, self.__max_k):

_, distance_group, data_type = self.__fit_k_means(data, k)

type_distance = np.min(distance_group, axis=0)

# 計算各個簇的半徑(中心點到簇中最遠的點的距離)之和

for idx in range(k):

type_data_idx = np.where(data_type == idx)

radius[k] += np.max(type_distance[type_data_idx])

# 加權求和,k用於抑制

radius[k] = np.sqrt(radius[k]) * k

# 交叉相減,得出半徑之和下降最快的k值,並認定為最佳k值

best_k = np.argmax(radius[:self.__max_k-1] - radius[1:])

self.__dots = central_dots[best_k]

Python機器學習 9 聚類演算法之K均值

我們之前接觸的所有機器學習演算法都有乙個共同特點,那就是分類器會接受2個向量 乙個是訓練樣本的特徵向量x,乙個是樣本實際所屬的型別向量y。由於訓練資料必須指定其真實分類結果,因此這種機器學習統稱為有監督學習。然而有時候,我們只有訓練樣本的特徵,而對其型別一無所知。這種情況,我們只能讓演算法嘗試在訓練...

機器學習實戰 K均值聚類

1.概述 聚類是一種無監督學習,它將相似的物件歸到同乙個簇中。聚類方法幾乎可以應用於所有物件,簇內的物件越相似,聚類的效果越好。k 均值聚類之所以稱為是因為它可以發現k個不同的簇,且每個簇的中心採用簇中所含值的均值計算而成。2.簇識別 cluster identification 簇識別給出聚類結果...

機器學習 作業4 K均值演算法 應用

1.應用k means演算法進行壓縮 讀取一張 觀察檔案大小,佔記憶體大小,資料結構,線性化 用kmeans對畫素顏色進行聚類 獲取每個畫素的顏色類別,每個類別的顏色 觀察壓縮的檔案大小,佔記憶體大小 2.觀察學習與生活中可以用k均值解決的問題。從資料 模型訓練 測試 完整地完成乙個應用案例。這個案...