K-Means

什么是聚類

聚類試圖將數(shù)據(jù)集中的樣本劃分為若干個通常是不相交的子集硼控,每個子集成為一個“簇”疫鹊。通過這樣的劃分蔑穴,每個簇可能對應于一些潛在的概念(也就是類別),如“淺色瓜” “深色瓜”烙博,“有籽瓜” “無籽瓜”,甚至“本地瓜” “外地瓜”等烟逊;需說明的是渣窜,這些概念對聚類算法而言事先是未知的,聚類過程僅能自動形成簇結構宪躯,簇對應的概念語義由使用者來把握和命名乔宿。

聚類和分類的區(qū)別?

聚類是無監(jiān)督的學習算法访雪,分類是有監(jiān)督的學習算法详瑞。所謂有監(jiān)督就是有已知標簽的訓練集(也就是說提前知道訓練集里的數(shù)據(jù)屬于哪個類別),機器學習算法在訓練集上學習到相應的參數(shù)臣缀,構建模型坝橡,然后應用到測試集上。而聚類算法是沒有標簽的精置,聚類的時候计寇,我們并不關心某一類是什么,我們需要實現(xiàn)的目標只是把相似的東西聚到一起脂倦。

性能度量

聚類的目的是把相似的樣本聚到一起番宁,而將不相似的樣本分開,類似于“物以類聚”赖阻,很直觀的想法是同一個簇中的相似度要盡可能高蝶押,而簇與簇之間的相似度要盡可能的低。
性能度量大概可分為兩類: 一是外部指標政供, 二是內部指標 播聪。
外部指標:將聚類結果和某個“參考模型”進行比較朽基。
內部指標:不利用任何參考模型,直接考察聚類結果离陶。

K-Means的原理

對于給定的樣本集稼虎,按照樣本之間的距離大小,將樣本集劃分為K個簇招刨。讓簇內的點盡量緊密的連在一起霎俩,而讓簇間的距離盡量的大

K-Means算法

給定樣本集D,k-means算法針對聚類所得簇劃分C最小化平方誤差沉眶。


這條公式在一定程度上刻畫了簇內樣本圍繞簇均值向量的緊密程度打却,E值越小則簇內樣本相似度越高。
最小化上面的公式并不容易谎倔,找到它的最優(yōu)解需考察樣本集D內所有可能的簇劃分柳击,這是一個NP難問題。因此片习,k-means算法采用了貪心策略捌肴,通過迭代優(yōu)化來近似求解上面的公式。算法流程如下:
K-Means算法

其中第一行對均值向量進行初始化藕咏,在第4-8行與第9-16行依次對當前簇劃分及均值向量迭代更新状知,若迭代更新后聚類結果保持不變,則在第18行將當前簇劃分結果返回孽查。

下面以西瓜數(shù)據(jù)集4.0為例來演示k-means算法的學習過程饥悴。我們將編號為i的樣本稱為xi,這是一個包含“密度”與“含糖率”兩個屬性值的二維向量盲再。
西瓜數(shù)據(jù)集4.0

假定簇數(shù)k=3西设,算法開始是隨機選取三個樣本x6,x12,x27作為初始均值向量,即

考察樣本x1=(0.697答朋;0.460)济榨,它與當前均值向量u1,u2绿映,u3的距離分別是0.369擒滑,0.506,0.166叉弦,因此x1將被劃入簇C3中丐一。類似的,對數(shù)據(jù)集中所有的樣本考察一遍后淹冰,可得當前簇劃分為
于是库车,可從C1,C2樱拴,C3分別求出新的均值向量
更新當前均值向量后柠衍,不斷重復上述過程洋满,如下圖所示,第五輪迭代產生的結果與第四輪迭代相同珍坊,于是算法停止牺勾,得到最終的簇劃分。

K-Means與KNN

初學者會很容易就把K-Means和KNN搞混阵漏,其實兩者的差別還是很大的驻民。
K-Means是無監(jiān)督學習的聚類算法,沒有樣本輸出履怯;而KNN是監(jiān)督學習的分類算法回还,有對應的類別輸出。KNN基本不需要訓練叹洲,對測試集里面的點柠硕,只需要找到在訓練集中最近的k個點,用這最近的k個點的類別來決定測試點的類別运提。而K-Means則有明顯的訓練過程仅叫,找到k個類別的最佳質心,從而決定樣本的簇類別糙捺。
當然,兩者也有一些相似點笙隙,兩個算法都包含一個過程洪灯,即找出和某一個點最近的點。兩者都利用了最近鄰(nearest neighbors)的思想竟痰。

K-Means的優(yōu)點與缺點

優(yōu)點:
簡單签钩,易于理解和實現(xiàn);收斂快坏快,一般僅需5-10次迭代即可铅檩,高效
缺點:
1,對K值得選取把握不同對結果有很大的不同
2莽鸿,對于初始點的選取敏感昧旨,不同的隨機初始點得到的聚類結果可能完全不同
3,對于不是凸的數(shù)據(jù)集比較難收斂
4祥得,對噪點過于敏感兔沃,因為算法是根據(jù)基于均值的
5,結果不一定是全局最優(yōu)级及,只能保證局部最優(yōu)
6乒疏,對球形簇的分組效果較好,對非球型簇饮焦、不同尺寸怕吴、不同密度的簇分組效果不好窍侧。

代碼部分

讀取數(shù)據(jù)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
dataset = pd.read_csv('watermelon_4.csv', delimiter=",")
data = dataset.values
print(dataset)

K-Means算法

import random
def distance(x1, x2):
    return sum((x1-x2)**2)
def Kmeans(D,K,maxIter):
    m, n = np.shape(D)
    if K >= m:
        return D
    initSet = set()
    curK = K
    while(curK>0):  # 隨機選取k個樣本
        randomInt = random.randint(0, m-1)
        if randomInt not in initSet:
            curK -= 1
            initSet.add(randomInt)
    U = D[list(initSet), :]  # 均值向量
    C = np.zeros(m)
    curIter = maxIter
    while curIter > 0:
        curIter -= 1
        for i in range(m):
            p = 0
            minDistance = distance(D[i], U[0])
            for j in range(1, K):
                if distance(D[i], U[j]) < minDistance:
                    p = j
                    minDistance = distance(D[i], U[j])
            C[i] = p
        newU = np.zeros((K, n))
        cnt = np.zeros(K)
        for i in range(m):
            newU[int(C[i])] += D[i]
            cnt[int(C[i])] += 1
        changed = 0
        for i in range(K):
            newU[i] /= cnt[i]
            for j in range(n):
                if U[i, j] != newU[i, j]:
                    changed = 1
                    U[i, j] = newU[i, j]
        if changed == 0:
            return U, C, maxIter-curIter
    return U, C, maxIter-curIter

作圖查看結果

U, C, iter = Kmeans(data,3,10)
# print(U)
# print(C)
# print(iter)

f1 = plt.figure(1)
plt.title('watermelon_4')
plt.xlabel('density')
plt.ylabel('ratio')
plt.scatter(data[:, 0], data[:, 1], marker='o', color='g', s=50)
plt.scatter(U[:, 0], U[:, 1], marker='o', color='r', s=100)
# plt.xlim(0,1)
# plt.ylim(0,1)
m, n = np.shape(data)
for i in range(m):
    plt.plot([data[i, 0], U[int(C[i]), 0]], [data[i, 1], U[int(C[i]), 1]], "c--", linewidth=0.3)
plt.show()

輸出如下:


上圖劃分了三個簇,每個簇的命名都是由我們來命名转绷,例如伟件,我們可以把它們分別命名為:好瓜、中等瓜暇咆、壞瓜锋爪。
數(shù)據(jù)以及代碼可以到我碼云下載

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市爸业,隨后出現(xiàn)的幾起案子其骄,更是在濱河造成了極大的恐慌,老刑警劉巖扯旷,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拯爽,死亡現(xiàn)場離奇詭異,居然都是意外死亡钧忽,警方通過查閱死者的電腦和手機毯炮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來耸黑,“玉大人桃煎,你說我怎么就攤上這事〈罂” “怎么了为迈?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長缺菌。 經常有香客問我葫辐,道長,這世上最難降的妖魔是什么伴郁? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任耿战,我火速辦了婚禮,結果婚禮上焊傅,老公的妹妹穿的比我還像新娘剂陡。我一直安慰自己,他們只是感情好狐胎,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布鹏倘。 她就那樣靜靜地躺著,像睡著了一般顽爹。 火紅的嫁衣襯著肌膚如雪纤泵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天,我揣著相機與錄音捏题,去河邊找鬼玻褪。 笑死,一個胖子當著我的面吹牛公荧,可吹牛的內容都是我干的带射。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼循狰,長吁一口氣:“原來是場噩夢啊……” “哼窟社!你這毒婦竟也來了?” 一聲冷哼從身側響起绪钥,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤灿里,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后程腹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匣吊,經...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年寸潦,在試婚紗的時候發(fā)現(xiàn)自己被綠了色鸳。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡见转,死狀恐怖命雀,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情斩箫,我是刑警寧澤吏砂,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站校焦,受9級特大地震影響,放射性物質發(fā)生泄漏统倒。R本人自食惡果不足惜寨典,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望房匆。 院中可真熱鬧耸成,春花似錦、人聲如沸浴鸿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽岳链。三九已至花竞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掸哑,已是汗流浹背约急。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工零远, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人厌蔽。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓牵辣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親奴饮。 傳聞我的和親對象是個殘疾皇子纬向,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內容