K-means聚類算法的三種改進(K-means++,ISODATA,Kernel K-means)介紹與對比

  1、概述git

      在本篇文章中將對四種聚類算法(K-means,K-means++,ISODATA和Kernel K-means)進行詳細介紹,並利用數據集來真實地反映這四種算法之間的區別。github

      首先須要明確的是上述四種算法都屬於"硬聚類」算法,即數據集中每個樣本都是被100%肯定得分到某一個類別中。與之相對的"軟聚類」能夠理解爲每一個樣本是以必定的機率被分到某一個類別中。算法

      先簡要闡述下上述四種算法之間的關係,已經瞭解過經典K-means算法的讀者應該會有所體會。沒有了解過K-means的讀者能夠先看下面的經典K-means算法介紹再回來看這部分。函數

     (1) K-means與K-means++:原始K-means算法最開始隨機選取數據集中K個點做爲聚類中心,而K-means++按照以下的思想選取K個聚類中心:假設已經選取了n個初始聚類中心(0<n<K),則在選取第n+1個聚類中心時:距離當前n個聚類中心越遠的點會有更高的機率被選爲第n+1個聚類中心。在選取第一個聚類中心(n=1)時一樣經過隨機的方法。能夠說這也符合咱們的直覺:聚類中心固然是互相離得越遠越好。這個改進雖然直觀簡單,可是卻很是得有效。學習

      (2) K-means與ISODATA:ISODATA的全稱是迭代自組織數據分析法。在K-means中,K的值須要預先人爲地肯定,而且在整個算法過程當中沒法更改。而當遇到高維度、海量的數據集時,人們每每很難準確地估計出K的大小。ISODATA就是針對這個問題進行了改進,它的思想也很直觀:當屬於某個類別的樣本數過少時把這個類別去除,當屬於某個類別的樣本數過多、分散程度較大時把這個類別分爲兩個子類別。測試

      (3) K-means與Kernel K-means:傳統K-means採用歐式距離進行樣本間的類似度度量,顯然並非全部的數據集都適用於這種度量方式。參照支持向量機中核函數的思想,將全部樣本映射到另一個特徵空間中再進行聚類,就有可能改善聚類效果。本文不對Kernel K-means進行詳細介紹。優化

      能夠看到,上述三種針對K-means的改進分別是從不一樣的角度出發的,所以都很是具備表明意義。目前應用普遍的應該仍是K-means++算法(例如2016年末的NIPS上也有針對K-means++的改進,感興趣的讀者能夠進一步學習)。spa

 

2、經典K-means算法插件

    算法描述以下,很是清晰易懂。經典K-means算法應該是每一個無監督學習教程開頭都會講的內容,故再也不多費口舌說一遍了。blog

圖1圖1. 經典K-means算法

 

      值得一提的是關於聚類中心數目(K值)的選取,的確存在一種可行的方法,叫作Elbow Method:經過繪製K-means代價函數與聚類數目K的關係圖,選取直線拐點處的K值做爲最佳的聚類中心數目。但在這邊不作過多的介紹,由於上述方法中的拐點在實際狀況中是不多出現的。比較提倡的作法仍是從實際問題出發,人工指定比較合理的K值,經過屢次隨機初始化聚類中心選取比較滿意的結果。

 

3、K-means++算法

      2007年由D. Arthur等人提出的K-means++針對圖1中的第一步作了改進。能夠直觀地將這改進理解成這K個初始聚類中心相互之間應該分得越開越好。整個算法的描述以下圖所示:

圖2

    圖2. K-means++算法

      下面結合一個簡單的例子說明K-means++是如何選取初始聚類中心的。數據集中共有8個樣本,分佈以及對應序號以下圖所示:

demo圖3. K-means++示例

      假設通過圖2的步驟一後6號點被選擇爲第一個初始聚類中心,那在進行步驟二時每一個樣本的D(x)和被選擇爲第二個聚類中心的機率以下表所示:

圖3

    其中的P(x)就是每一個樣本被選爲下一個聚類中心的機率。最後一行的Sum是機率P(x)的累加和,用於輪盤法選擇出第二個聚類中心。方法是隨機產生出一個0~1之間的隨機數,判斷它屬於哪一個區間,那麼該區間對應的序號就是被選擇出來的第二個聚類中心了。例如1號點的區間爲[0,0.2),2號點的區間爲[0.2, 0.525)。

      從上表能夠直觀的看到第二個初始聚類中心是1號,2號,3號,4號中的一個的機率爲0.9。而這4個點正好是離第一個初始聚類中心6號點較遠的四個點。這也驗證了K-means的改進思想:即離當前已有聚類中心較遠的點有更大的機率被選爲下一個聚類中心。能夠看到,該例的K值取2是比較合適的。當K值大於2時,每一個樣本會有多個距離,須要取最小的那個距離做爲D(x)

 

4、ISODATA算法

     放在最後也是最複雜的就是ISODATA算法。正如以前所述,K-means和K-means++的聚類中心數K是固定不變的。而ISODATA算法在運行過程當中可以根據各個類別的實際狀況進行兩種操做來調整聚類中心數K:(1)分裂操做,對應着增長聚類中心數;(2)合併操做,對應着減小聚類中心數。

    下面首先給出ISODATA算法的輸入(輸入的數據和迭代次數再也不單獨介紹):

      [1] 預期的聚類中心數目Ko:雖然在ISODATA運行過程當中聚類中心數目是可變的,但仍是須要由用戶指定一個參考標準。事實上,該算法的聚類中心數目變更範圍也由Ko決定。具體地,最終輸出的聚類中心數目範圍是 [Ko/2, 2Ko]。

      [2] 每一個類所要求的最少樣本數目Nmin:用於判斷當某個類別所包含樣本分散程度較大時是否能夠進行分裂操做。若是分裂後會致使某個子類別所包含樣本數目小於Nmin,就不會對該類別進行分裂操做。

      [3] 最大方差Sigma:用於衡量某個類別中樣本的分散程度。當樣本的分散程度超過這個值時,則有可能進行分裂操做(注意同時須要知足[2]中所述的條件)。

      [4] 兩個類別對應聚類中心之間所容許最小距離dmin:若是兩個類別靠得很是近(即這兩個類別對應聚類中心之間的距離很是小),則須要對這兩個類別進行合併操做。是否進行合併的閾值就是由dmin決定。

      相信不少人看完上述輸入的介紹後對ISODATA算法的流程已經有所猜想了。的確,ISODATA算法的原理很是直觀,不過因爲它和其餘兩個方法相比須要額外指定較多的參數,而且某些參數一樣很難準確指定出一個較合理的值,所以ISODATA算法在實際過程當中並無K-means++受歡迎。

      首先給出ISODATA算法主體部分的描述,以下圖所示:

圖4

圖4. ISODATA算法的主體部分

     上面描述中沒有說明清楚的是第5步中的分裂操做和第6步中的合併操做。下面首先介紹合併操做:

圖5

圖5. ISODATA算法的合併操做

     最後是ISODATA算法中的分裂操做。

圖6

圖6. ISODATA算法的分裂操做

      最後,針對ISODATA算法總結一下:該算法可以在聚類過程當中根據各個類所包含樣本的實際狀況動態調整聚類中心的數目。若是某個類中樣本分散程度較大(經過方差進行衡量)而且樣本數量較大,則對其進行分裂操做;若是某兩個類別靠得比較近(經過聚類中心的距離衡量),則對它們進行合併操做。

       可能沒有表述清楚的地方是ISODATA-分裂操做的第1步和第2步。一樣地以圖三所示數據集爲例,假設最初1,2,3,4,5,6,8號被分到了同一個類中,執行第1步和第2步結果以下所示:

圖7

      而在正確分類狀況下(即1,2,3,4爲一類;5,6,7,8爲一類),方差爲0.33。所以,目前的方差遠大於理想的方差,ISODATA算法就頗有可能對其進行分裂操做。

 

5、聚類算法源代碼

      我已經將上述三種算法整合成一個Matlab函數Clustering.m。讀者能夠直接使用該函數對數據集進行聚類。因爲代碼比較長,並且代碼插件還不怎麼會用,就不在文中介紹了。須要使用的讀者能夠點擊下面的連接下載使用(歡迎Star和Fork,以後會不按期補充新的算法和優化的):

https://github.com/AaronX121/Unsupervised-Learning-Clustering

     使用方式很是簡單,目前支持三種形式的輸入,分別對應着上面的三種算法:

     [centroid, result] = Clustering(data, ‘kmeans’, k , iteration);

     [centroid, result] = Clustering(data, ‘kmeans++’, k , iteration);

     [centroid, result] =

   Clustering(data, ‘isodata’, desired_k , iteration, minimum_n, maximum_variance, minimum_d);

      其中的輸入data是一個矩陣,每一行表明數據集中的一個樣本。其餘輸入的意義與上面的算法描述中一一對應。輸出的centroid是聚類中心的位置,result是每一個樣本所對應的類別索引。

 

6、數據集測試

      最後以一個簡單的知足二維高斯分佈的數據集爲例,展現上述三種算法的聚類結果,以下圖所示。

測試結果

圖7. 一個簡單數據集上三種算法的聚類效果(綠色加號表明聚類中心位置)

相關文章
相關標籤/搜索