先引用IDMer整理的圖初步瞭解下K-means
K-means也被稱爲C-means,因爲它的目標是要找到c個均值向量u1,u2,……uc。除上面提到的用處,k-means還常用於加速其它算法的收斂。聚類算法主要有兩類:硬聚類和軟聚類(FCM)。K-means屬於前者。
K-means的兩大難點是確定c的數值和避免算法的抖動(不穩定性)。對這兩個問題都有大量的針對性的研究。
算法的僞代碼爲:
- Begin initialize n,c,u1,u2,……uc
- Do 按照最近鄰ui分類n個樣本
- 重新計算ui
- Until ui 不再改變
- Return u1,u2,……uc
- End
其複雜度爲O(ndcT),d表示特徵數量;T爲迭代次數。實際應用中通常迭代次數都不會太多。
硬聚類k-means
在該算法中任意樣本屬於類別i的概率要麼是1要麼是0. 所以在計算過程中距離度量算法確定之後,只需要計算樣本離哪類的聚類中心近就將該樣本劃分爲哪類,即樣本屬於該類的概率爲1,屬於其它c-1類的概率都爲0. 這樣的規則使得計算簡單。但最後的聚類結果容易出現局部最優。因此,在次基礎上,模糊K-means被提出,我們通常我們稱爲FCM(Fuzzy C-Means)。
K-means聚類2維數據的迭代軌跡,圖中用Voronoi網格標出分類結果。Voronoi單元中心即爲聚類中心
軟聚類FCM
在FCM中每個樣本屬於某類別的概率不是絕對的1或0,而是介於[0~1]之間的一個值。樣本屬於所有類別的概率和爲1. 該樣本在當前迭代中屬於哪類的概率最大就將該樣本劃分到哪類中。
FCM算法僞代碼:
- begin initialize n,c,b, u1,u2,……uc, P(wi|xj),i=1,2……c;j=1,2,……n
- 歸一化, P(wi|xj)
- do 重新計算ui
- 重新計算P(wi|xj)
- until ui和P(wi|xj)變化很小
- return u1,u2,……uc
- End
常用的結束條件:
- u1,u2,……uc的變化小於某個閾值
- 迭代次數T大於某個閾值。
由於對不熟悉的樣本的收斂速度未知,通常兩個條件都會設置。K-means通常也被歸類爲迭代優化算法。
關於FCM與k-means 性能的比較參考:http://www.eurojournals.com/ejsr_46_3_02.pdf
作爲較早的基本算法,目前k-means和FCM都有較多實現。常用工具多有對其的支持,網上源碼也較多。以matlab中FCM函數爲100個隨機樹分2類的例子:
data = rand(100, 2);
[center,U,obj_fcn] = fcm(data, 2);
plot(data(:,1), data(:,2),'o');
maxU = max(U);
index1 = find(U(1,:) == maxU);
index2 = find(U(2, :) == maxU);
line(data(index1,1),data(index1, 2),'linestyle','none',...
'marker','*','color','g');
line(data(index2,1),data(index2, 2),'linestyle','none',...
'marker', '*','color','r');
另外,開源項目Mahout對K-Means進行了分佈式實現。通過MapReduce實現的分佈式K-means支持更大數據量的聚類。
更多信息參考:http://www.tnove.com/?cat=40
Wiki K-Means: http://en.wikipedia.org/wiki/K-means_clustering
Mahout學習——K-Means Clustering: http://www.cnblogs.com/vivounicorn/archive/2011/10/08/2201986.html