github:kmeans代碼實現1、kmeans代碼實現2(包含二分k-means)
本文算法均使用python3實現
1 聚類算法
對於"監督學習"(supervised learning),其訓練樣本是帶有標記信息的,並且監督學習的目的是:對帶有標記的數據集進行模型學習,從而便於對新的樣本進行分類。而在“無監督學習”(unsupervised learning)中,訓練樣本的標記信息是未知的,目標是通過對無標記訓練樣本的學習來揭示數據的內在性質及規律,為進一步的數據分析提供基礎。對於無監督學習,應用最廣的便是"聚類"(clustering)。
“聚類算法”試圖將數據集中的樣本划分為若干個通常是不相交的子集,每個子集稱為一個“簇”(cluster),通過這樣的划分,每個簇可能對應於一些潛在的概念或類別。
我們可以通過下面這個圖來理解:




2 kmeans算法
kmeans算法又名k均值算法。其算法思想大致為:先從樣本集中隨機選取 $ k $ 個樣本作為簇中心,並計算所有樣本與這 $ k $ 個“簇中心”的距離,對於每一個樣本,將其划分到與其距離最近的“簇中心”所在的簇中,對於新的簇計算各個簇的新的“簇中心”。
根據以上描述,我們大致可以猜測到實現kmeans算法的主要三點:
(1)簇個數 $ k $ 的選擇
(2)各個樣本點到“簇中心”的距離
(3)根據新划分的簇,更新“簇中心”
2.1 kmeans算法要點
(1) $ k $ 值的選擇
$ k $ 的選擇一般是按照實際需求進行決定,或在實現算法時直接給定 $ k $ 值。
(2) 距離的度量
給定樣本 $ x^{(i)} = \lbrace x_1^{(i)},x_2^{(i)},,...,x_n^{(i)}, \rbrace 與 x^{(j)} = \lbrace x_1^{(j)},x_2^{(j)},,...,x_n^{(j)}, \rbrace ,其中 i,j=1,2,...,m,表示樣本數,n表示特征數 $ 。距離的度量方法主要分為以下幾種:
(2.1)有序屬性距離度量(離散屬性 $ \lbrace1,2,3 \rbrace $ 或連續屬性):
閔可夫斯基距離(Minkowski distance): $$ dist_{mk}(x^{(i)},x^{(j)})=(\sum_{u=1}^n |x_u^{(i)}-x_u^{(j)}|^p)^{\frac{1}{p}} $$
歐氏距離(Euclidean distance),即當 $ p=2 $ 時的閔可夫斯基距離: $$ dist_{ed}(x^{(i)},x^{(j)})=||x^{(i)}-x^{(j)}||2=\sqrt{\sum{u=1}^n |x_u^{(i)}-x_u^{(j)}|^2} $$
曼哈頓距離(Manhattan distance),即當 $ p=1 $ 時的閔可夫斯基距離: $$ dist_{man}(x^{(i)},x^{(j)})=||x^{(i)}-x^{(j)}||1=\sum{u=1}^n |x_u^{(i)}-x_u^{(j)}| $$
(2.2)無序屬性距離度量(比如{飛機,火車,輪船}):
VDM(Value Difference Metric): $$ VDM_p(x_u^{(i)},x_u^{(j)}) = \sum_{z=1}^k \left|\frac{m_{u,x_u^{(i)},z}}{m_{u,x_u^{(i)}}} - \frac{m_{u,x_u^{(j)},z}}{m_{u,x_u^{(j)}}} \right|^p $$
其中 $ m_{u,x_u^{(i)}} $ 表示在屬性 $ u $ 上取值為 $ x_u^{(i)} $ 的樣本數, $ m_{u,x_u^{(i)},z} $ 表示在第 $ z $ 個樣本簇中屬性 $ u $ 上取值為 $ x_u^{(i)} $ 的樣本數, $ VDM_p(x_u^{(i)},x_u^{(j)}) $ 表示在屬性 $ u $ 上兩個離散值 $ x_u^{(i)} 與 x_u^{(i)} $ 的 $ VDM $ 距離 。
(2.3)混合屬性距離度量,即為有序與無序的結合: $$ MinkovDM_p(x^{(i)},x^{(j)}) = \left( \sum_{u=1}^{n_c} | x_u^{(i)} - x_u^{(j)} | ^p + \sum_{u=n_c +1}^n VDM_p (x_u^{(i)},x_u^{(j)}) \right) ^{\frac{1}{p}} $$
其中含有 $ n_c $ 個有序屬性,與 $ n-n_c $ 個無序屬性。
本文數據集為連續屬性,因此代碼中主要以歐式距離進行距離的度量計算。
(3) 更新“簇中心”
對於划分好的各個簇,計算各個簇中的樣本點均值,將其均值作為新的簇中心。
2.2 kmeans算法過程
輸入:訓練數據集 $ D ={x^{(1)},x^{(2)},...,x^{(m)}}$ ,聚類簇數 $ k $ ;
過程:函數 $ kMeans(D, k, maxIter) $ .
1:從 $ D $ 中隨機選擇 $ k $ 個樣本作為初始“簇中心”向量: $ {\mu^{(1)},\mu^{(2)},...,,\mu^{(k)}} $ :
2:repeat
3: 令 $ C_i = \emptyset (1 \leq i \leq k ) $
4: for $ j= 1,2,...,m $ do
5: 計算樣本 $ x^{(j)} $ 與各“簇中心”向量 $ \mu^{(i)} (1 \leq i \leq k ) $ 的歐式距離
6: 根據距離最近的“簇中心”向量確定 $ x^{(j)} $ 的簇標記: $ \lambda_j = argmin_{i \in \lbrace 1,2,...,k \rbrace}d_{ji} $
7: 將樣本 $ x^{(j)} $ 划入相應的簇: $ C_{\lambda_j} = C_{\lambda_j} \bigcup \lbrace x^{(j)} \rbrace $ ;
8: end for
9: for $ i= 1,2,...,k $ do
10: 計算新“簇中心”向量: $ (\mu^{(i)})' = \frac{1}{|C_i|} \sum_{x \in C_i}x $ ;
11: if $ (\mu^{(i)})' = \mu^{(i)} $ then
12: 將當前“簇中心”向量 $ \mu^{(i)} $ 更新為 $ (\mu^{(i)})' $
13: else
14: 保持當前均值向量不變
15: end if
16: end for
17: else
18:until 當前“簇中心”向量均未更新
輸出:簇划分 $ C={C_1,C_2,...,C_K} $
為避免運行時間過長,通常設置一個最大運行輪數或最小調整幅度閾值,若達到最大輪數或調整幅度小於閾值,則停止運行。
過程如下圖:

2.2 kmeans算法分析
kmeans算法由於初始“簇中心”點是隨機選取的,因此最終求得的簇的划分與隨機選取的“簇中心”有關,也就是說,可能會造成多種 $ k $ 個簇的划分情況。這是因為kmeans算法收斂到了局部最小值,而非全局最小值。
3 二分k-means算法
基於kmeans算法容易使得結果為局部最小值而非全局最小值這一缺陷,對算法加以改進。使用一種用於度量聚類效果的指標SSE(Sum of Squared Error),即對於第 $ i $ 個簇,其SSE為各個樣本點到“簇中心”點的距離的平方的和,SSE值越小表示數據點越接近於它們的“簇中心”點,聚類效果也就越好。以此作為划分簇的標准。
算法思想是:先將整個樣本集作為一個簇,該“簇中心”點向量為所有樣本點的均值,計算此時的SSE。若此時簇個數小於 $ k $ ,對每一個簇進行kmeans聚類($ k=2 $) ,計算將每一個簇一分為二后的總誤差SSE,選擇SSE最小的那個簇進行划分操作。
3.1 kmeans算法過程
輸入:訓練數據集 $ D ={x^{(1)},x^{(2)},...,x^{(m)}}$ ,聚類簇數 $ k $ ;
過程:函數 $ kMeans(D, k, maxIter) $ .
1:將所有點看做一個簇,計算此時“簇中心”向量:$ \mu^{(1)} = \frac{1}{m} \sum_{x \in D}x $
2:while $ “簇中心”個數h < k $ :
3: for $ i= 1,2,...,h $ do
4: 將第 $ i $ 個簇使用 kmeans算法進行划分,其中 $ k = 2 $
5: 計算划分后的誤差平方和 $ SSE_i $
5: 比較 $ k $ 種划分的SSE值,選擇SSE值最小的那種簇划分進行划分
5: 更新簇的分配結果
5: 添加新的“簇中心”
18:until 當前“簇中心”個數達到 $ k $
輸出:簇划分 $ C={C_1,C_2,...,C_K} $
3.2 二分k-means算法分析
二分k-means算法不再隨機選取簇中心,而是從一個簇出發,根據聚類效果度量指標SSE來判斷下一步應該對哪一個簇進行划分,因此該方法不會收斂到局部最小值,而是收斂到全局最小值。
引用及參考:
[1]《機器學習》周志華著
[2]《機器學習實戰》Peter Harrington著
[3]https://blog.csdn.net/google19890102/article/details/26149927
寫在最后:本文參考以上資料進行整合與總結,屬於原創,文章中可能出現理解不當的地方,若有所見解或異議可在下方評論,謝謝!
若需轉載請注明:https://www.cnblogs.com/lliuye/p/9144312.html