介紹
kmeans算法又名k均值算法。
算法思想:先從樣本集中隨機選取 𝑘k 個樣本作為簇中心,並計算所有樣本與這 𝑘k 個“簇中心”的距離,對於每一個樣本,將其划分到與其距離最近的“簇中心”所在的簇中,對於新的簇計算各個簇的新的“簇中心”。
實現kmeans算法的三點:
(1)簇個數 𝑘k 的選擇
(2)各個樣本點到“簇中心”的距離
(3)根據新划分的簇,更新“簇中心”
數據集:
代碼:
import numpy as np # vecA,vecB是數組形式 # 歐式距離 def distEclud(vecA,vecB): return sum((vecA-vecB)**2)**0.5
import numpy as np dataset=[ [73,40,7], [60,15,5], [61,19,2], [34,18,6], [67,26,10], [91,40,4], [101,40,13], [81,40,6], [88,40,8], [122,40,17], [102,50,17], [87,50,12], [116,50,11], [110,50,17], [164,50,17], [40,30,1], [76,40,17], [118,50,9], [160,50,15], [96,50,16] ] # 利用numpy.array函數將其轉變為標准矩陣 dataset = np.array(dataset) print(dataset[0]) # 列數 print(np.shape(dataset)[1])
def kmeans0(dataset,k): # 樣本的個數 m = np.shape(dataset)[0] # 保存每個樣本的聚類情況,第一列表示該樣本屬於某一類,第二列是與聚類中心的距離 clusterAssment = np.mat(np.zeros((m,2))) # 產生隨機質心,將列表形式轉換為數組形式 centroids = np.array(randCent(dataset,k)) # 控制聚類算法迭代停止的標志,當聚類不再改變時,就停止迭代 clusterChanged = True while clusterChanged: # 先進行本次迭代,如果聚類還是改變,最后把該標志改為True,從而繼續下一次迭代 clusterChanged = False for i in range(m): # 遍歷每一個樣本 # 每個樣本與每個質心計算距離 # 采用一趟冒泡排序找出最小的距離,並找出對應的類 # 計算與質心的距離時,剛開始需要比較,記為無窮大 mindist = np.inf for j in range(k): # 遍歷每一類 # print(np.array(dataset[i,:])) # print(centroids) distj =distEclud(dataset[i,:],centroids[j,:]) if distj<mindist: mindist = distj minj = j # 遍歷完k個類,本次樣本已聚類 if clusterAssment[i,0] !=minj: # 判斷本次聚類結果和上一次是否一致 clusterChanged = True # 只要有一個聚類結果改變,就重新迭代 clusterAssment[i,:] = minj,mindist**2 # 類別,與距離 # 外層循環結束,每一個樣本都有了聚類結果 # 更新質心 for cent in range(k): # 找出屬於相同一類的樣本 data_cent = dataset[np.nonzero(clusterAssment[:,0].A == cent)[0]] centroids[cent,:] = np.mean(data_cent,axis=0) return centroids,clusterAssment
結果1:
#提取不同類別的數據 n=(clusterAssment.size+1)//2 loan_data0=np.empty(shape=[0,2]) loan_data1=np.empty(shape=[0,2]) loan_data2=np.empty(shape=[0,2]) for i in range(n): # print(clusterAssment[i][0]) if(clusterAssment[i][0]==0.0): loan_data0=np.append(loan_data0,[[i,0]],axis = 0) if(clusterAssment[i][0]==1.0): loan_data1=np.append(loan_data1,[[i,1]],axis = 0) if(clusterAssment[i][0]==2.0): loan_data2=np.append(loan_data2,[[i,2]],axis = 0) print("第一類:") print(loan_data0) print("第二類:") print(loan_data1) print("第三類:") print(loan_data2)
作圖
import matplotlib.pyplot as plt X0=[x[0] for x in loan_data0] Y0=[x[1] for x in loan_data0] X1=[x[0] for x in loan_data1] Y1=[x[1] for x in loan_data1] X2=[x[0] for x in loan_data2] Y2=[x[1] for x in loan_data2] plt.scatter(X0, Y0) plt.scatter(X1, Y1) plt.scatter(X2, Y2) plt.show()
結果3:
圖說明: