在資料探勘中,k-means演算法是一種cluster analysis的演算法,其主要是來計算資料聚集的演算法,主要通過不斷地取離種子點最近均值的演算法。
問題k-means演算法主要解決的問題如下圖所示。我們可以看到,在圖的左邊有一些點,我們用肉眼可以看出來有四個點群,但是我們怎麼通過電腦程式找出這幾個點群來呢?於是就出現了我們的k-means演算法(wikipedia鏈結)
k-means要解決的問題
演算法概要
這個演算法其實很簡單,如下圖所示:
從上圖中,我們可以看到,a,b,c,d,e是五個在圖中點。而灰色的點是我們的種子點,也就是我們用來找點群的點。有兩個種子點,所以k=2。
然後,k-means的演算法如下:
隨機在圖中取k(這裡k=2)個種子點。
然後對圖中的所有點求到這k個種子點的距離,假如點pi離種子點si最近,那麼pi屬於si點群。(上圖中,我們可以看到a,b屬於上面的種子點,c,d,e屬於下面中部的種子點)
接下來,我們要移動種子點到屬於他的「點群」的中心。(見圖上的第三步)
然後重複第2)和第3)步,直到,種子點沒有移動(我們可以看到圖中的第四步上面的種子點聚合了a,b,c,下面的種子點聚合了d,e)。
這個演算法很簡單,但是有些細節我要提一下,求距離的公式我不說了,大家有初中畢業水平的人都應該知道怎麼算的。我重點想說一下「求點群中心的演算法」。
求點群中心的演算法
1)minkowski distance公式——λ可以隨意取值,可以是負數,也可以是正數,或是無窮大。
2)euclidean distance公式——也就是第乙個公式λ=2的情況
3)cityblock distance公式——也就是第乙個公式λ=1的情況
這三個公式的求中心點有一些不一樣的地方,我們看下圖(對於第乙個λ在0-1之間)。
(1)minkowski distance (2)euclidean distance (3)cityblock distance
上面這幾個圖的大意是他們是怎麼個逼近中心的,第乙個圖以星形的方式,第二個圖以同心圓的方式,第三個圖以菱形的方式。
k-means的演示
操作是,滑鼠左鍵是初始化點,右鍵初始化「種子點」,然後勾選「show history」可以看到一步一步的迭代。
注:這個演示的鏈結也有乙個不錯的k means tutorial。
k-means++演算法
k-means主要有兩個最重大的缺陷——都和初始值有關:
我在這裡重點說一下k-means++演算法步驟:
先從我們的資料庫隨機挑個隨機點當「種子點」。
對於每個點,我們都計算其和最近的乙個「種子點」的距離d(x)並儲存在乙個陣列裡,然後把這些距離加起來得到sum(d(x))。
然後,再取乙個隨機值,用權重的方式來取計算下乙個「種子點」。這個演算法的實現是,先取乙個能落在sum(d(x))中的隨機值random,然後用random -= d(x),直到其<=0,此時的點就是下乙個「種子點」。
重複第(2)和第(3)步直到所有的k個種子點都被選出來。
進行k-means演算法。
相關的**你可以在這裡找到「implement the k-means++ algorithm」(牆)另,apache的通用資料學庫也實現了這一演算法
k-means演算法應用
看到這裡,你會說,k-means演算法看來很簡單,而且好像就是在玩座標點,沒什麼真實用處。而且,這個演算法缺陷很多,還不如人工呢。是的,前面的例子只是玩二維座標點,的確沒什麼意思。但是你想一下下面的幾個問題:
1)如果不是二維的,是多維的,如5維的,那麼,就只能用計算機來計算了。
2)二維座標點的x,y 座標,其實是一種向量,是一種數學抽象。現實世界中很多屬性是可以抽象成向量的,比如,我們的年齡,我們的喜好,我們的商品,等等,能抽象成向量的目的就是可以讓計算機知道某兩個屬性間的距離。如:我們認為,18歲的人離24歲的人的距離要比離12歲的距離要近,鞋子這個商品離衣服這個商品的距離要比電腦要近,等等。
mahout探索之旅 kmeans演算法(上)
k means演算法是聚類演算法,k在在這裡指的是分類的型別數 根據經驗指出會出現幾個類別 所以在開始設定的時候非常關鍵,演算法的原理是首先假定k個分類點,然後根據歐式距離計算分類,然後去同分類的均值作為新的聚簇中心,迴圈操作直到收斂。演算法的關鍵在k個值的選取上,如果均值選得恰當將有利於演算法的快...
k means演算法不足
a.k 不確定 對於初始條件和聚類的個數 k 並沒有乙個標準的方法來給定。初始條件不同會對結果產生比較大的影響,因為有時演算法會跳入區域性最優。所以解決方法之一,就是多次執行演算法,隨機分割,比較結果之間的差異。b.區域性最優 如果要達到全域性最優,需要用到其他一些技術,比如模擬退火或者遺傳演算法等...
Kmeans演算法實現
include opencv2 highgui highgui.hpp include opencv2 core core.hpp include using namespace cv using namespace std static void help int main int argc ch...