1. 程式人生 > >聚類演算法(一):k-均值 (k-means)演算法

聚類演算法(一):k-均值 (k-means)演算法

首先確保你在動手寫程式碼之前已經瞭解什麼是聚類分析。

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)