python手動實現K_means聚類(指定K值)
前言
這幾天作業,用到了k_means聚類,作為一名deeper,怎麼能不手動實現一下呢?然後,我就錯過了作業的提交時間。。。。
實現
- 原理
簡單來說,可以分為以下幾步:
- 指定有幾個簇
- 每個簇任選一個點作為初值(資料中的點),中心點(幾個簇就幾個中心點),會有很多種情況
- 通過指定的距離函式,計算資料中每個點與中心點的距離
- 將計算的點加入到與其最近的簇中
- 所有點都進行一遍之後,重新計算中心點(簇中的每個點加起來,求平均值)
- 重複以上步驟,直至簇不會變化
- 將所有的情況進行計算,找出最小的(也可以通過設定閾值),就是最合適的聚類(當然也有很多評判方式,這裡實現一個最簡單的,通過求出簇中的所有點到中心點的平方均值,補充:除了計算簇內部的值要求最小之外,也可以計算簇與簇之間的值越大。因為最理想的情況就是簇內部越近越好,簇與簇之間越遠越好。)
#Author:龍文漢
#Data:2020.11.18
#Discription:聚類演算法
import numpy as np
import copy
import itertools
class K_means():
def __init__(self,data,cu_num):
self.arry_first = data
self.cu_num = cu_num
self.cu = []
self.arry = []
#初始化每個簇,根據設定的簇數量,隨機新增簇
def Cu_initial(self,x):
#x = random.sample(range(0,len(self.arry)-self.cu_num),self.cu_num)
#print(x)
# x = np.random.randint(1,6,self.cu_num,"int32")#會重複
self.arry = copy.deepcopy(self.arry_first)
#print("^^^^^^^",self.arry)
self.cu = []
for i in x:
self.cu.append([])
self.cu[-1].append(data[i])
self.arry.remove(data[i])
#print(self.arry)
#計算歐氏距離
def Ou_in(self,data1,data2):
#print(data1,data2)
ans = ((data1[0]-data2[0])**2+(data1[1]-data2[1])**2)**0.5
#print(ans)
return ans
#計算每個簇的平方和均差
def Pinfang(self,tem):
# cu_center = 0
# for i in cu:
# cu_center+=i
# cu_center /= len(cu)
# pinfang = 0
# for i in cu:
# pinfang += (cu-cu_center)**2
pingfang = 0
for cu in tem:
cu_center = np.mean(cu,axis=0)
pingfang += np.sum(list(map(lambda x:self.Ou_in(x,cu_center)**2,cu)))
return pingfang
#開始進行沒一簇的聚類
def Evualution(self):
first = 1
while(True):#一直迴圈,直到簇不再變化
center_list = []
tem = copy.deepcopy(self.cu) # 暫時簇的形式,便於對後面進行對比,注意複製形式,地址的問題
if first==0:
self.cu = []
self.arry = copy.deepcopy(self.arry_first)
for i in range(self.cu_num):#計算每一個簇的中心點
center_list.append(np.mean(tem[i], axis=0))
if first==0:
self.cu.append([])
if first == 1:
first = 0
print("每個簇的中心點",center_list)
for i in self.arry:#依次對每個點進行迭代計算(根據歐式距離決定歸屬)
print("開始對該點的聚類",i)
ans_list = [] # 一個點對於每一個簇的歐式距離集合
for x in center_list:#依次迭代每個中心簇
ans_list.append(self.Ou_in(i, x))#增加一個點對每個簇的歐式距離
print("該點和所有簇的歐式距離集合",ans_list)
print("最小的歐式距離為",min(ans_list),"index是",ans_list.index(min(ans_list)))
self.cu[ans_list.index(min(ans_list))].append(i)#更新簇,將該點新增到歐式距離最小的簇中
print("新增該節點之後的簇",self.cu)
print("原來的簇", tem)
print("更新之後的簇",self.cu)
if (self.cu == tem):#如果簇已經不變,則說明此時完成了聚類
return tem
print("所有的點本輪聚類結束(在這之前的中心點不改變)")
#開始找出最優解
def Best(self):
min_list = []
min_pin = 100000000
x = list(itertools.permutations(range(len(self.arry_first)),self.cu_num))
for w in x:
self.Cu_initial(w)
tem = self.Evualution()
pin = self.Pinfang(tem)
print("本次的平方差值為",pin)
if pin < min_pin:
min_pin=pin
min_list = self.cu
return min_list,min_pin
if __name__ == "__main__":
data = [[4.0, 2.5], [1.5, 1.0], [3.0, 1.5], [4.5, 3.5], [4.0, 2.5], [2.5, 5.0]]
# data.remove([4.0, 2.5])
# print(data)
k_means = K_means(data,2)
answer = k_means.Best()
print(answer)
相關文章
- 譜聚類的python實現聚類Python
- C均值聚類 C實現 Python實現聚類Python
- 【Python機器學習實戰】聚類演算法(1)——K-Means聚類Python機器學習聚類演算法
- 聚類演算法與K-means實現聚類演算法
- K-Means聚類分析以及誤差平方和SSE(Python實現)聚類Python
- k-means聚類聚類
- 聚類之K均值聚類和EM演算法聚類演算法
- MVO優化DBSCAN實現聚類優化聚類
- 利用python的KMeans和PCA包實現聚類演算法PythonPCA聚類演算法
- 04聚類演算法-程式碼案例一-K-means聚類聚類演算法
- FCM聚類演算法詳解(Python實現iris資料集)聚類演算法Python
- 層級聚類和Python實現的初學者指南(附連結)聚類Python
- 【Python機器學習實戰】聚類演算法(2)——層次聚類(HAC)和DBSCANPython機器學習聚類演算法
- 自己動手實現Java中的StringBuffer類Java
- 吳恩達《Machine Learning》精煉筆記 8:聚類 KMeans 及其 Python實現吳恩達Mac筆記聚類Python
- 【機器學習】K-means聚類分析機器學習聚類
- java中介面多個實現類,如何指定實現類,根據子類型別選擇實現方法Java型別
- python range()函式指定數值Python函式
- MMM全連結聚類演算法實現聚類演算法
- 勞動節快樂!手寫個核心價值觀編碼工具 - Python實現Python
- 機器學習經典聚類演算法 —— k-均值演算法(附python實現程式碼及資料集)機器學習聚類演算法Python
- 機器學習之分類:指定閾值機器學習
- k-medoids與k-Means聚類演算法的異同聚類演算法
- Linux 中實現按照每一列的類別計算 指定列值的平均數Linux
- 一文簡述多種無監督聚類演算法的Python實現聚類演算法Python
- python 介面實現類的Python
- 手動指定埠執行
- [Python手撕]滑動視窗最大值Python
- 數值計算:前向和反向自動微分(Python實現)Python
- 手把手教你在多種無監督聚類演算法實現Python(附程式碼)聚類演算法Python
- DOTween實現緩動變值動效
- 聚類分析聚類
- JVM效能最佳化 —— 類載入器,手動實現類的熱載入JVM
- 【數值方法-Python實現】Crout分解+追趕法實現Python
- 從零開始學機器學習——K-Means 聚類機器學習聚類
- 演算法金 | K-均值、層次、DBSCAN聚類方法解析演算法聚類
- 如何實現手機瀏覽器自動喚醒微信開啟指定頁面瀏覽器
- Python的類及單例實現Python單例