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均值解決的問題。從資料 模型訓練 測試 完整地完成乙個應用案例。這個案...