聚類演算法(一):k-均值 (k-means)演算法
阿新 • • 發佈:2019-01-29
首先確保你在動手寫程式碼之前已經瞭解什麼是聚類分析。
k-均值演算法----一種基於形心地技術的聚類演算法。k-均值演算法的英文名是k-means,那麼這個演算法是怎麼工作的呢?
k-均值演算法把簇的形心定義為簇內點的均值。它的處理流程如下:1.在資料點集D中隨機的選擇k個物件(這個k表示你要講資料集分成幾個簇),每個物件代表一個簇的初始均值或中心。2.對剩下的每個物件,根據其與哥哥簇中心的歐氏距離,將它分配到最相似的簇。3.k-均值演算法迭代的改善內變差。對於每個簇,它使用上次迭代分配到該簇的物件,計算新的均值。 4.使用更新的均值作為新的簇中心。重新分配所有物件。 5.迭代繼續,直到分配穩定,本輪行程的簇的中心點座標與前一輪行程的簇相同。
演算法:k-均值
輸入:k:簇的數目
D:包含n個物件的資料集
輸出:k個簇的集合
方法:
1.從D中任意選擇k個物件作為初始簇中心;
2.repeat
3.根據簇中物件的均值,將每個物件分配到最相似的簇;
4. 更新簇的均值,即重新計算每個簇中物件的均值;
5.until 不再發生變化
原始碼(Python)
__author__ = 'ChiXu_15s103144_HIT' import random import math def K_means(data, k): center = [] cluster = [] dis = [] demo_cluster = [] flag = 0 i = 0 len_data = len(data) while i<k: cluster.append(data[random.randint(0, len_data-1)]) #在資料中隨機的找點放進cluster中 if cluster in center: cluster = [] continue else: center.append(cluster) #起始狀態,每個簇裡只有一個隨機點 cluster = [] i += 1 while True: new_cluster = [] for i in xrange(len_data): for j in xrange(k): #分別計算它與k箇中心點的距離 lenth = Distance(data[i],center[j][0]) dis.append(lenth) #選出距離最短的中心點,並放進center中 dis_copy = dis min_dis = sorted(dis)[0] if min_dis == 0: dis = [] dis_copy = [] continue else: mark = dis_copy.index(min_dis) center[mark].append(data[i]) dis = [] dis_copy = [] #計算每個cluster中的平均中心點 for i in xrange(k): new_cluster.append(Cluster_Average(center[i])) for i in xrange(k): if new_cluster[i] == center[i][0]: flag += 1 if flag == k: #如果簇內的平均中心點不再發生變化,則return return center else: #否則用新的平均中心點取代原來的平均中心點 flag = 0 center = [] for i in xrange(k): #center.append(new_cluster[i]) demo_cluster.append(new_cluster[i]) center.append(demo_cluster) demo_cluster = [] def Cluster_Average(cluster): #計算cluster內平均中心點 average = [] total_x = total_y = 0 len_cluster = len(cluster) for i in xrange(len_cluster): total_x += cluster[i][0] total_y += cluster[i][1] average.append(total_x/len_cluster) average.append(total_y/len_cluster) return average def Distance(point1, point2): #計算兩點歐氏距離 if point1 == point2: return 0 else: dis_x = point2[0] - point1[0] dis_y = point2[1] - point1[1] dis = math.sqrt(dis_x**2 + dis_y**2) return dis point = [] data = [] num = raw_input('請輸入隨機點陣的數目:') for i in xrange(int(num)): #構造隨機點陣 point.append(random.randint(1,100)) point.append(random.randint(1,100)) data.append(point) point = [] k = raw_input('請輸入中心點k的數目:') center = K_means(data,int(k)) print(center)