K-Means算法是無監督的聚類算法,它實現起來比較簡單,聚類效果也不錯,所以應用很普遍。K-Means算法有大量的變體,本文就從最傳統的K-Means算法講起,在其基礎上講述K-Means的優化變體方法。包括初始化優化K-Means++, 距離計算優化elkan K-Means算法和大數據狀況下的優化Mini Batch K-Means算法。算法
K-Means算法的思想很簡單,對於給定的樣本集,按照樣本之間的距離大小,將樣本集劃分爲K個簇。讓簇內的點儘可能緊密的連在一塊兒,而讓簇間的距離儘可能的大。學習
若是用數據表達式表示,假設簇劃分爲$(C_1,C_2,...C_k)$,則咱們的目標是最小化平方偏差E:$$ E = \sum\limits_{i=1}^k\sum\limits_{x \in C_i} ||x-\mu_i||_2^2$$測試
其中$\mu_i$是簇$C_i$的均值向量,有時也稱爲質心,表達式爲:$$\mu_i = \frac{1}{|C_i|}\sum\limits_{x \in C_i}x$$大數據
若是咱們想直接求上式的最小值並不容易,這是一個NP難的問題,所以只能採用啓發式的迭代方法。優化
K-Means採用的啓發式方式很簡單,用下面一組圖就能夠形象的描述。rest
上圖a表達了初始的數據集,假設k=2。在圖b中,咱們隨機選擇了兩個k類所對應的類別質心,即圖中的紅色質心和藍色質心,而後分別求樣本中全部點到這兩個質心的距離,並標記每一個樣本的類別爲和該樣本距離最小的質心的類別,如圖c所示,通過計算樣本和紅色質心和藍色質心的距離,咱們獲得了全部樣本點的第一輪迭代後的類別。此時咱們對咱們當前標記爲紅色和藍色的點分別求其新的質心,如圖4所示,新的紅色質心和藍色質心的位置已經發生了變更。圖e和圖f重複了咱們在圖c和圖d的過程,即將全部點的類別標記爲距離最近的質心的類別並求新的質心。最終咱們獲得的兩個類別如圖f。blog
固然在實際K-Mean算法中,咱們通常會屢次運行圖c和圖d,才能達到最終的比較優的類別。it
在上一節咱們對K-Means的原理作了初步的探討,這裏咱們對K-Means的算法作一個總結。基礎
首先咱們看看K-Means算法的一些要點。原理
1)對於K-Means算法,首先要注意的是k值的選擇,通常來講,咱們會根據對數據的先驗經驗選擇一個合適的k值,若是沒有什麼先驗知識,則能夠經過交叉驗證選擇一個合適的k值。
2)在肯定了k的個數後,咱們須要選擇k個初始化的質心,就像上圖b中的隨機質心。因爲咱們是啓發式方法,k個初始化的質心的位置選擇對最後的聚類結果和運行時間都有很大的影響,所以須要選擇合適的k個質心,最好這些質心不能太近。
好了,如今咱們來總結下傳統的K-Means算法流程。
輸入是樣本集$D=\{x_1,x_2,...x_m\}$,聚類的簇樹k,最大迭代次數N
輸出是簇劃分$C=\{C_1,C_2,...C_k\}$
1) 從數據集D中隨機選擇k個樣本做爲初始的k個質心向量: $\{\mu_1,\mu_2,...,\mu_k\}$
2)對於n=1,2,...,N
a) 將簇劃分C初始化爲$C_t = \varnothing \;\; t =1,2...k$
b) 對於i=1,2...m,計算樣本$x_i$和各個質心向量$\mu_j(j=1,2,...k)$的距離:$d_{ij} = ||x_i - \mu_j||_2^2$,將$x_i$標記最小的爲$d_{ij}$所對應的類別$\lambda_i$。此時更新$C_{\lambda_i} = C_{\lambda_i} \cup \{x_i\}$
c) 對於j=1,2,...,k,對$C_j$中全部的樣本點從新計算新的質心$\mu_j = \frac{1}{|C_j|}\sum\limits_{x \in C_j}x$
e) 若是全部的k個質心向量都沒有發生變化,則轉到步驟3)
3) 輸出簇劃分$C=\{C_1,C_2,...C_k\}$
在上節咱們提到,k個初始化的質心的位置選擇對最後的聚類結果和運行時間都有很大的影響,所以須要選擇合適的k個質心。若是僅僅是徹底隨機的選擇,有可能致使算法收斂很慢。K-Means++算法就是對K-Means隨機初始化質心的方法的優化。
K-Means++的對於初始化質心的優化策略也很簡單,以下:
a) 從輸入的數據點集合中隨機選擇一個點做爲第一個聚類中心$\mu_1$
b) 對於數據集中的每個點$x_i$,計算它與已選擇的聚類中心中最近聚類中心的距離$D(x_i) = arg\;min||x_i- \mu_r||_2^2\;\;r=1,2,...k_{selected}$
c) 選擇一個新的數據點做爲新的聚類中心,選擇的原則是:$D(x)$較大的點,被選取做爲聚類中心的機率較大
d) 重複b和c直到選擇出k個聚類質心
e) 利用這k個質心來做爲初始化質心去運行標準的K-Means算法
在傳統的K-Means算法中,咱們在每輪迭代時,要計算全部的樣本點到全部的質心的距離,這樣會比較的耗時。那麼,對於距離的計算有沒有可以簡化的地方呢?elkan K-Means算法就是從這塊入手加以改進。它的目標是減小沒必要要的距離的計算。那麼哪些距離不須要計算呢?
elkan K-Means利用了兩邊之和大於等於第三邊,以及兩邊之差小於第三邊的三角形性質,來減小距離的計算。
第一種規律是對於一個樣本點$x$和兩個質心$\mu_{j_1}, \mu_{j_2}$。若是咱們預先計算出了這兩個質心之間的距離$D(j_1,j_2)$,則若是計算髮現$2D(x,j_1) \leq D(j_1,j_2)$,咱們當即就能夠知道$D(x,j_1) \leq D(x, j_2)$。此時咱們不須要再計算$D(x, j_2)$,也就是說省了一步距離計算。
第二種規律是對於一個樣本點$x$和兩個質心$\mu_{j_1}, \mu_{j_2}$。咱們能夠獲得$D(x,j_2) \geq max\{0, D(x,j_1) - D(j_1,j_2)\}$。這個從三角形的性質也很容易獲得。
利用上邊的兩個規律,elkan K-Means比起傳統的K-Means迭代速度有很大的提升。可是若是咱們的樣本的特徵是稀疏的,有缺失值的話,這個方法就不使用了,此時某些距離沒法計算,則不能使用該算法。
在統的K-Means算法中,要計算全部的樣本點到全部的質心的距離。若是樣本量很是大,好比達到10萬以上,特徵有100以上,此時用傳統的K-Means算法很是的耗時,就算加上elkan K-Means優化也依舊。在大數據時代,這樣的場景愈來愈多。此時Mini Batch K-Means應運而生。
顧名思義,Mini Batch,也就是用樣本集中的一部分的樣原本作傳統的K-Means,這樣能夠避免樣本量太大時的計算難題,算法收斂速度大大加快。固然此時的代價就是咱們的聚類的精確度也會有一些下降。通常來講這個下降的幅度在能夠接受的範圍以內。
在Mini Batch K-Means中,咱們會選擇一個合適的批樣本大小batch size,咱們僅僅用batch size個樣原本作K-Means聚類。那麼這batch size個樣本怎麼來的?通常是經過無放回的隨機採樣獲得的。
爲了增長算法的準確性,咱們通常會多跑幾回Mini Batch K-Means算法,用獲得不一樣的隨機採樣集來獲得聚類簇,選擇其中最優的聚類簇。
初學者很容易把K-Means和KNN搞混,二者其實差異仍是很大的。
K-Means是無監督學習的聚類算法,沒有樣本輸出;而KNN是監督學習的分類算法,有對應的類別輸出。KNN基本不須要訓練,對測試集裏面的點,只須要找到在訓練集中最近的k個點,用這最近的k個點的類別來決定測試點的類別。而K-Means則有明顯的訓練過程,找到k個類別的最佳質心,從而決定樣本的簇類別。
固然,二者也有一些類似點,兩個算法都包含一個過程,即找出和某一個點最近的點。二者都利用了最近鄰(nearest neighbors)的思想。
K-Means是個簡單實用的聚類算法,這裏對K-Means的優缺點作一個總結。
K-Means的主要優勢有:
1)原理比較簡單,實現也是很容易,收斂速度快。
2)聚類效果較優。
3)算法的可解釋度比較強。
4)主要須要調參的參數僅僅是簇數k。
K-Means的主要缺點有:
1)K值的選取很差把握
2)對於不是凸的數據集比較難收斂
3)若是各隱含類別的數據不平衡,好比各隱含類別的數據量嚴重失衡,或者各隱含類別的方差不一樣,則聚類效果不佳。
4) 採用迭代方法,獲得的結果只是局部最優。
5) 對噪音和異常點比較的敏感。
(歡迎轉載,轉載請註明出處。歡迎溝通交流: liujianping-ok@163.com)