原型聚類(lèi)之K均值算法分析與實(shí)現(xiàn)(Python)

算法原理

~~~~~原理很簡(jiǎn)單,我就不細(xì)說(shuō)了(如果這還看不懂,建議補(bǔ)一下數(shù)學(xué)知識(shí)),直接參考周志華老師的《機(jī)器學(xué)習(xí)》俏蛮,上面也把算法的實(shí)現(xiàn)過(guò)程總結(jié)了。

算法原理.PNG

算法流程分析

~~~~~下面先看一下算法的流程上遥,分析搏屑、理解每一個(gè)步驟才能正確寫(xiě)出程序。

算法的流程.PNG

~~~~~
算法過(guò)程第1行:根據(jù)要聚類(lèi)的簇?cái)?shù)k隨機(jī)選擇k個(gè)樣本作為均值向量粉楚。

~~~~~算法過(guò)程第3行:初始化聚類(lèi)結(jié)果的存儲(chǔ)變量

~~~~~算法過(guò)程第5行:計(jì)算m個(gè)樣本分別到k個(gè)均值向量的距離辣恋,dji表示第j個(gè)樣本到第i個(gè)均值向量的距離。(注意:這個(gè)步驟要計(jì)算第j個(gè)樣本分別到i = 1,2,...,k個(gè)均值向量的距離)

~~~~~算法過(guò)程第6行:從第5行的結(jié)果中模软,選出第j個(gè)樣本到各個(gè)均值向量的最小距離伟骨,確定該樣本的簇標(biāo)記。

~~~~~算法過(guò)程第7行:將第j個(gè)樣本按照簇標(biāo)記放入到存儲(chǔ)變量C對(duì)應(yīng)的位置燃异。

~~~~~算法過(guò)程第4~8行則是根據(jù)樣本到均值向量的距離携狭,將樣本分別劃分到距離均值向量最小的那標(biāo)記下,實(shí)現(xiàn)了樣本根據(jù)圍繞均值向量的緊密程度劃分到不同的類(lèi)中特铝。

~~~~~算法過(guò)程第9~16行:重新計(jì)算C中每個(gè)簇類(lèi)下樣本的均值向量暑中,然后與原均值向量進(jìn)行比較壹瘟,如果重新計(jì)算后的均值向量與原均值向量不相等鲫剿,則更新均值向量,否則不更新稻轨。

~~~~~最后如果所有的均值向量都不需要更新灵莲,則算法結(jié)束,這個(gè)時(shí)候算法已經(jīng)收斂了殴俱。

完整的實(shí)現(xiàn)代碼

import numpy as np
from numpy import *
import matplotlib.pyplot as plt
import math

#計(jì)算兩個(gè)向量之間的距離
def get_dist(X1, X2):
    N = shape(X1)[1]
    dist = 0

    for u in range(N):
        dist += abs(float(X1[0, u] - X2[0, u])) ** 2

    return sqrt(dist)

def mat_compare(x1, x2):
    n = shape(x1)[1]
    equal = True

    for i in range(n):
        if(x1[0, i] != x2[0, i]):
            equal = False
    return equal

#k均值聚類(lèi)算法
#輸入數(shù)據(jù):X是輸入的訓(xùn)練數(shù)據(jù)矩陣政冻,每一列是一簇
#輸入數(shù)據(jù):K是要分的類(lèi)數(shù)量
#返回?cái)?shù)據(jù):分好類(lèi)的列表
def k_means(X_arr, K, iterator_counts):
    X = mat(X_arr)
    m,n = shape(X)
    miu = mat(zeros((K, n)))
    update_flag_mat = mat(zeros((1, K)))
    C = []
    cnt = 0

    #隨機(jī)選取三個(gè)值作為均值向量
    miu[0, :] = X[5, :]
    miu[1, :] = X[11, :]
    miu[2, :] = X[26, :]
    lamda = mat(zeros((m, 1)))

    for i in range(K):
        C.append([[0.0, 0.0]])
    
    while(True):
        d = mat(zeros((m, K)))
        for j in range(m):
            for k in range(K):
                d[j, k] = get_dist(X[j, :], miu[k, :])
            lamda[j, 0] = argmin(d[j, :])
            mat_data = []
            for i in range(n):
                mat_data.append(float(X[j, i]))
            index = int(lamda[j, 0])
            (C[index]).append([float(X[j, 0]), float(X[j, 1])])
            if(update_flag_mat[0, index] == 0):
                update_flag_mat[0, index] = 1
                del C[index][0]
        update_flag = False
        for i in range(K):
            new_miu = mat(zeros((1, K)))
            Ci = mat(array(C[i]))   
            new_miu = mean(Ci, axis = 0)  
            if(mat_compare(new_miu, miu[i, :]) == False):
                update_flag = True
                for j in range(n):
                    miu[i, j] = new_miu[0, j]
        cnt += 1
        if(cnt >= iterator_counts):
            break
        if(update_flag == False):
            print("cnt = ", cnt)
            #break
        else:
            C.clear()
            update_flag_mat[0, :] = 0
            for i in range(K):
                C.append([[0.0, 0.0]])
    return C

def load_data_set(file_name):
    X = []

    fd = open(file_name)
    for line in fd.readlines():
        line_data = line.strip().split()
        X.append([float(line_data[0]), float(line_data[1])])
    return np.array(X)

def show_experiment_plot(C):
    D = mat(array(C[0]))
    plt.plot(D[:, 0], D[:, 1], "or")
    D = mat(array(C[1]))
    plt.plot(D[:, 0], D[:, 1], "ob")
    D = mat(array(C[2]))
    plt.plot(D[:, 0], D[:, 1], "og")

    plt.xlabel("X1")
    plt.ylabel("X2")
    plt.show()

if __name__ == "__main__":
    X = load_data_set("data_set.txt")
    C = k_means(X, 3, 6)
    print(C[0])
    print("-----------------------")
    print(C[1])
    print("-----------------------")
    print(C[2])
    print("-----------------------")
    print(len(C))
    show_experiment_plot(C)

測(cè)試數(shù)據(jù)

~~~~~本文的測(cè)試數(shù)據(jù)與周志華老師的《機(jī)器學(xué)習(xí)》這本書(shū)上的一致枚抵,初始化參數(shù)也是一樣的。

~~~~~測(cè)試數(shù)據(jù):

0.697 0.460
0.774 0.376
0.634 0.264
0.608 0.318
0.556 0.215
0.403 0.237
0.481 0.149
0.437 0.211
0.666 0.091
0.243 0.267
0.245 0.057
0.343 0.099
0.639 0.161
0.657 0.198
0.360 0.370
0.593 0.042
0.719 0.103
0.359 0.188
0.339 0.241
0.282 0.257
0.748 0.232
0.714 0.346
0.483 0.312
0.478 0.437
0.525 0.369
0.751 0.489
0.532 0.472
0.473 0.376
0.725 0.445
0.446 0.459

~~~~~書(shū)上的測(cè)試數(shù)據(jù)

測(cè)試數(shù)據(jù).PNG

~~~~~
本文的初始化參數(shù):

    #隨機(jī)選取三個(gè)值作為均值向量
    miu[0, :] = X[5, :]
    miu[1, :] = X[11, :]
    miu[2, :] = X[26, :]

~~~~~書(shū)上的初始化參數(shù):

初始化參數(shù).PNG

~~~~~
本文的迭代一次的實(shí)驗(yàn)結(jié)果:
實(shí)驗(yàn)結(jié)果1.PNG

實(shí)驗(yàn)結(jié)果2.PNG

~~~~~
書(shū)上的實(shí)驗(yàn)結(jié)果:
書(shū)上實(shí)驗(yàn)結(jié)果.PNG

~~~~~
經(jīng)過(guò)觀察明场,發(fā)現(xiàn)本文迭代1次的實(shí)驗(yàn)結(jié)果與書(shū)上迭代1次的結(jié)果是一樣的汽摹。但是我發(fā)現(xiàn),我的程序迭代一次就已經(jīng)收斂了苦锨,完全不知道書(shū)上的結(jié)果為什么迭代3次才能收斂逼泣?這讓我對(duì)書(shū)上的結(jié)果產(chǎn)生了懷疑,知道原因的可以下面留言討論一下舟舒。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拉庶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子秃励,更是在濱河造成了極大的恐慌氏仗,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夺鲜,死亡現(xiàn)場(chǎng)離奇詭異皆尔,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)币励,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)床佳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人榄审,你說(shuō)我怎么就攤上這事砌们。” “怎么了搁进?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵浪感,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我饼问,道長(zhǎng)影兽,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任莱革,我火速辦了婚禮峻堰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘盅视。我一直安慰自己捐名,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布闹击。 她就那樣靜靜地躺著镶蹋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贺归,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天淆两,我揣著相機(jī)與錄音,去河邊找鬼拂酣。 笑死秋冰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的婶熬。 我是一名探鬼主播丹莲,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼尸诽!你這毒婦竟也來(lái)了甥材?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤性含,失蹤者是張志新(化名)和其女友劉穎洲赵,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體商蕴,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叠萍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绪商。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苛谷。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖格郁,靈堂內(nèi)的尸體忽然破棺而出腹殿,到底是詐尸還是另有隱情,我是刑警寧澤例书,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布锣尉,位于F島的核電站,受9級(jí)特大地震影響决采,放射性物質(zhì)發(fā)生泄漏自沧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一树瞭、第九天 我趴在偏房一處隱蔽的房頂上張望拇厢。 院中可真熱鬧,春花似錦晒喷、人聲如沸孝偎。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)邪媳。三九已至捐顷,卻和暖如春荡陷,著一層夾襖步出監(jiān)牢的瞬間雨效,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工废赞, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留徽龟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓唉地,卻偏偏與公主長(zhǎng)得像据悔,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子耘沼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容