手寫kmeans

算法:

  1. 首先確定一個k值,即我們希望將數據集經過聚類得到k個集合。
  2. 從數據集中隨機選擇k個數據點作爲質心。
  3. 對數據集中每一個點,計算其與每一個質心的距離(如歐式距離),離哪個質心近,就劃分到那個質心所屬的集合。
  4. 把所有數據歸好集合後,一共有k個集合。然後重新計算每個集合的質心。
  5. 如果新計算出來的質心和原來的質心之間的距離小於某一個設置的閾值(表示重新計算的質心的位置變化不大,趨於穩定,或者說收斂),我們可以認爲聚類已經達到期望的結果,算法終止。
  6. 如果新質心和原質心距離變化很大,需要迭代3~5步驟。

代碼:

import numpy as np
import matplotlib.pyplot as plt

# map 100*100
high = 100
width = 100
# create random data
data = np.random.rand(100, 2)
data = data * [high, width]
data = np.hstack((data, np.zeros([100, 1])))
# count of classes
classes = 5


def distance(point1, center):
    return np.sqrt((point1[0] - center[0]) ** 2 + (point1[1] - center[1]) ** 2)


def color(i):
    global classes
    return i * 255. / classes


if __name__ == '__main__':
    plt.ion()
    # select center randomly
    centers = np.random.randint(0, 100, [classes])
    centers_data = []
    for i in range(classes):
        data[i][2] = i
        centers_data.append(data[i])
    while True:
        colors = [color(x) for x in data[:, 2]]
        plt.scatter(data[:, 0], data[:, 1], c=colors)
        plt.pause(0.5)
        # caculate nearest center
        for i in range(100):
            distances = np.array([distance(data[i], center_data) for center_data in centers_data])
            i_class = np.argmin(distances)
            data[i][2] = i_class
        # caculate new center
        new_centers_data = np.zeros([classes, 2])
        new_centers_count = np.zeros([classes])
        for j in range(5):
            for i in range(100):
                if data[i][2] == j:
                    new_centers_count[j] += 1
                    new_centers_data[j] += data[i][0:2]
        new_centers_data /= np.array([new_centers_count]).T
        dist = np.max([distance(new_centers_data[i], centers_data[i]) for i in range(classes)])
        print('max distance ', dist)
        if dist < 1e-4:
            break
        centers_data = new_centers_data
    plt.ioff()
    plt.show()
    print('kmeans completed.')

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章