1. 程式人生 > >KMeans聚類演算法分析以及實現

KMeans聚類演算法分析以及實現

KMeans

KMeans是一種無監督學習聚類方法, 目的是發現數據中資料物件之間的關係,將資料進行分組,組內的相似性越大,組間的差別越大,則聚類效果越好。

無監督學習,也就是沒有對應的標籤,只有資料記錄.通過KMeans聚類,可以將資料劃分成一個簇,進而發現數據之間的關係.

聚類過程

原理

KMeans演算法是將資料 x 1 ,

x 2 , . . . , x n
{x^1, x^2 ,..., x^n} 聚類成k個簇,其中每個 x i R n
x^i \in R^n
, 演算法具體描述:

  1. 隨機選擇k個聚類質心點: μ 1 , μ 2 , . . . , μ k \mu_1, \mu_2, ..., \mu_k ;
  2. 重複下面過程直到收斂{
    對於每一個數據i,計算其屬於的簇:
    c ( i ) : = a r g m i n j x ( i ) μ j 2 c^{(i)} := argmin_j||x^{(i)}-\mu_j||^2 ;
    對於每個簇j,重新計算簇質心:
    μ j = i = 1 n 1 ( c i = = j ) x i i = 1 n 1 ( c ( i ) = j ) \mu_j=\frac{\sum_{i=1}^n1{(c^i==j)}x^i}{\sum_{i=1}^n1{(c^{(i)}=j)}}
    }

用語言描述來說,就是:隨機確定k個初始點作為簇中心; 為每個資料分配簇[計算每條資料和簇中心的相似度,分配到最相似的簇上];根據簇中的資料點對每個簇中心進行更新.反覆重複直到收斂為止.

虛擬碼:

建立k個點作為起始質心;
當任意一個點的簇分配結果發生改變時:
    對資料集中的每個資料點:
        對每個質心: 
            計算質心和當前資料點的相似度 
        將資料點分配到最近的質心所代表的簇上 
    對於每個簇,計算簇中所有點的均值,並將均值作為新的簇中心[質心]

存在問題及其處理方法

  • 必須事先給出k(要生成的簇的數目),而且對初值敏感,對於不同的初始值,可能會導致不同結果。
  • 不適合於發現非凸面形狀的簇或者大小差別很大的簇。
  • 對於“躁聲”和孤立點資料是敏感的,因為簇的中心是通過計算資料的平均值得到的,這些資料的存在會使聚類的中心發生很大的偏移;
  • 容易陷入到區域性最優解.

對於區域性最優解的問題,一方面可以像決策樹一樣,對最後生成的聚類效果進行"剪枝"處理,但有所不同,因為要保證簇數目不變,所有處理進行"剪枝處理"外,還需要"增枝處理",具體可以依據某種指標[SSE sum of square errors]選擇指標最大的簇嘗試劃分, 然後選擇兩個進行合併,保證簇的數目不變.

另一方面,可以對kmeans進行優化處理,存在一種二分kMeans處理.

二分k均值:首先將所有資料看成一個簇,然後將該簇一分為二,之後選擇其中一個簇繼續劃分, 如何選擇簇取決於對其劃分是否可以最大程度的降低SSE的值;然後反覆重複,直到得到K個簇為止.

程式碼實現

github地址: repository