首先要來了解的一個概念就是聚類,簡單地說就是把相似的東西分到一組,同 Classification (分類)不同,對於一個 classifier ,通常需要你告訴它“這個東西被分為某某類”這樣一些例子,理想情況下,一個 classifier 會從它得到的訓練集中進行“學習”,從而具備對未知數據進行分類的能力,這種提供訓練數據的過程通常叫做 supervised learning (監督學習),而在聚類的時候,我們並不關心某一類是什么,我們需要實現的目標只是把相似的東西聚到一起,因此,一個聚類算法通常只需要知道如何計算相似 度就可以開始工作了,因此 clustering 通常並不需要使用訓練數據進行學習,這在 Machine Learning 中被稱作 unsupervised learning (無監督學習)。
我們經常接觸到的聚類分析,一般都是數值聚類,一種常見的做法是同時提取 N 種特征,將它們放在一起組成一個 N 維向量,從而得到一個從原始數據集合到 N 維向量空間的映射——你總是需要顯式地或者隱式地完成這樣一個過程,然后基於某種規則進行分類,在該規則下,同組分類具有最大的相似性。
假設我們提取到原始數據的集合為(x1, x2, …, xn),並且每個xi為d維的向量,K-means聚類的目的就是,在給定分類組數k(k ≤ n)值的條件下,將原始數據分成k類
S = {S1, S2, …, Sk},在數值模型上,即對以下表達式求最小值:
這里μi 表示分類Si 的平均值。
那么在計算機編程中,其又是如何實現的呢?其算法步驟一般如下:
1、從D中隨機取k個元素,作為k個簇的各自的中心。
2、分別計算剩下的元素到k個簇中心的相異度,將這些元素分別划歸到相異度最低的簇。
3、根據聚類結果,重新計算k個簇各自的中心,計算方法是取簇中所有元素各自維度的算術平均數。
4、將D中全部元素按照新的中心重新聚類。
5、重復第4步,直到聚類結果不再變化。
6、將結果輸出。
用數學表達式來說,
設我們一共有 N 個數據點需要分為 K 個 cluster ,k-means 要做的就是最小化
這個函數,其中 在數據點 n 被歸類到 cluster k 的時候為 1 ,否則為 0 。直接尋找
和
來最小化
並不容易,不過我們可以采取迭代的辦法:先固定
,選擇最優的
,很容易看出,只要將數據點歸類到離他最近的那個中心就能保證
最小。下一步則固定
,再求最優的
。將
對
求導並令導數等於零,很容易得到
最小的時候
應該滿足:
亦即 的值應當是所有 cluster k 中的數據點的平均值。由於每一次迭代都是取到
的最小值,因此
只會不斷地減小(或者不變),而不會增加,這保證了 k-means 最終會到達一個極小值。雖然 k-means 並不能保證總是能得到全局最優解,但是對於這樣的問題,像 k-means 這種復雜度的算法,這樣的結果已經是很不錯的了。
首先 3 個中心點被隨機初始化,所有的數據點都還沒有進行聚類,默認全部都標記為紅色,如下圖所示:
然后進入第一次迭代:按照初始的中心點位置為每個數據點着上顏色,重新計算 3 個中心點,結果如下圖所示:
可以看到,由於初始的中心點是隨機選的,這樣得出來的結果並不是很好,接下來是下一次迭代的結果:
可以看到大致形狀已經出來了。再經過兩次迭代之后,基本上就收斂了,最終結果如下:
不過正如前面所說的那樣 k-means 也並不是萬能的,雖然許多時候都能收斂到一個比較好的結果,但是也有運氣不好的時候會收斂到一個讓人不滿意的局部最優解,例如選用下面這幾個初始中心點:
最終會收斂到這樣的結果:
整體來講,K-means算法的聚類思想比較簡單明了,並且聚類效果也還算可以,算是一種簡單高效應用廣泛的 clustering 方法,接下來,我將討論其代碼實現過程。