注:本系列全部博客將持續更新併發布在github和gitee上,您能夠經過github、gitee下載本系列全部文章筆記文件。javascript
1 聚類¶
本文咱們來總結K-means算法。css
與以前介紹過的諸多分類算法不一樣,K-means算法屬於聚類算法的範疇。說到這裏,必須得因此說分類算法與聚類算法的區別。html
分類算法與聚類算法最本質的區別在於分類算法是一種有監督學習方法,這一類算法在真正用於實踐前,必須經過已知樣本標籤的數據進行訓練,以創建樣本特徵屬性到樣本標籤的最佳擬合模型;與之相反,無監督學習方法能夠在沒有任何先驗知識的狀況下進行分類,這種方法根據類似性原則,將具備較高類似度的數據對象劃分至同一類簇,將具備較高相異度的數據對象劃分至不一樣類簇,最終實現對數據集的分類。html5
2 K-means算法¶
2.1 算法思想¶
K-means算法是一種基於距離的聚類算法,這類聚類算法以距離來度量對象間的類似性,兩樣本對象間距離越大,類似性越小。關於K-means算法,有一個很是經典的故事:java
有4個牧師去郊區村莊授課,剛開始,4個牧師在村莊裏分別隨機選了一個位置,而後將位置公佈給全村村民,村民收到消息後,紛紛選擇最近的一個牧師那裏去聽課。牧師授課時,衆多村民反饋路途太遠,因而牧師記錄了來聽本身授課的全部村民的居住地址,第二次授課時,牧師選擇本身記錄的村民的中心位置做爲新的授課位置,而後將位置公佈給全村村民,村民收到4位牧師新的授課位置後,一樣根據距離選擇最近的牧師去聽課。以後4位牧師的每次一次授課都根據來聽本身講課的村民登記的居住地址來更新下一次授課的位置,而村民也更新4位牧師更新的位置來選擇授課牧師,直到村民的選擇再也不發生變化,則牧師授課的位置也完全穩定下來。node
K-means算法思想與上面故事中牧師選位所表現出來的原理是十分類似的,最終的目的都是實現全部樣本數據(村民)到聚類中心(牧師)的距離之和最小化。K-means算法實現步驟以下:python
輸入:數據集$D = \{ {x_1},{x_2}, \cdots ,{x_n}\} $,聚類個數$k$jquery
輸出:聚類結果類簇linux
(1)隨機初始化$k$個樣本做爲聚類中心$\{ {\mu _1},{\mu _2}, \cdots ,{\mu_k}\} $;android
(2)計算數據集中全部樣本$x_i$到各個聚類中心$\mu_j$的距離$dist({x_i},{\mu _j})$,並將$x_i$劃分到距離最小的聚類中心所在類簇中;
(3)對於每個類簇,更新其聚類中心:${\mu _i} = \frac{1}{{|{c_i}|}}\sum\limits_{x \in {c_i}} x $
(4)重複(2)(3)步驟,直到聚類中心再也不有明顯變化或知足迭代次數。
總結而言,K-means算法整個流程可總結爲一個優化問題,經過不斷迭代使得目標函數收斂,K-means算法目標函數爲: $$J = \sum\nolimits_{j = 1}^k {\sum\nolimits_{i = 1}^n {dist({x_i},{\mu _j})} } $$
從目標函數中能夠看出,有兩個因素對聚類結果有着相當重要的影響:$k$值、距離度量方式。
對於$k$值,這是K-means算法一個繞不開的問題,直接影響着最終聚類結果的準確性,在如何肯定$k$值問題上,傳統的的K-means算法在對數據分佈未知的狀況下只能經過屢次嘗試不一樣的$k$值來探索最優取值。值得一說的是,衆多專家學者針對K-means算法中如何肯定$k$值、甚至避開$k$值的的問題對K-means算法進行優化改進,設計了許多改進的K-means算法,這又是一個大話題了,本文不在深究。
下面在說說距離度量的問題。
2.2 距離度量¶
對於K-means算法這類基於距離(其餘還有基於密度、網格、層次、模型)的聚類算法,距離度量貫穿了算法的整個流程,因此選擇一種合適的距離度量方式尤其重要。
這裏列舉幾種常見的距離度量方式。
(1)閔可夫斯基距離(Minkowski Distance) 對於兩個給定的$d$維數據樣本$X = ({x_1},{x_2}, \cdots ,{x_p})$,$Y = ({y_1},{y_2}, \cdots ,{y_p})$,閔可夫斯基距離定義爲: $$dist(X,Y) = \root p \of {\sum\limits_{i = 1}^d {|{x_i} - {y_i}{|^p}} } $$
當$p=1$時,閔可夫斯基距離又被稱爲曼哈頓距離(Manhattan Distance): $$dist(X,Y) = \sum\limits_{i = 1}^d {|{x_i} - {y_i}|} $$ 曼哈頓距離能夠看作是數據樣本在各維度差值的絕對值之和,又被稱爲折線距離、街區距離。相比於歐氏距離,曼哈頓距離沒進行平方運算,因此對離羣點不敏感。
當$p=2$時,閔可夫斯基距離就是咱們熟悉的歐氏距離: $$dist(X,Y) = \sqrt {\sum\limits_{i = 1}^d {|{x_i} - {y_i}{|^2}} } $$
(2)餘弦距離(Cosine)
餘弦距離以兩向量夾角餘弦值來反映類似度,取值在$[0,1]$之間,值越大,類似度越大。
$$dist(X,Y) = \cos (X,Y) = \frac{{\sum\nolimits_{i = 1}^d {{x_i}{y_i}} }}{{\sqrt {\sum\nolimits_{i = 1}^d {{{({x_i})}^2}} } \sqrt {\sum\nolimits_{i = 1}^d {{{({y_i})}^2}} } }}$$
餘弦距離在文本識別中應用比較廣泛。
(3)切比雪夫距離 (Chebyshev Distance )
切比雪夫距離是以各維度差值的最大值做爲最終的類似度: $$dist(X,Y) = \mathop {\max }\limits_i (|{x_i} - {y_i}|)$$
除了這三個經常使用距離外,還有馬氏距離、皮爾遜相關係數、KL散度等等距離度量方法。
2.3 算法總結¶
K-means算法是一個應用十分普遍、出場率極高的一個聚類算法,思想簡單,解釋性強,設定好$k$值後便可輸出指定數量的類簇。不過,在實際應用中,也須要注意K-means算法的不足之處:
- K-means算法的$k$值必須在聚類前肯定,在缺少對數據集分佈認知的狀況下這每每是很難估計的,只能經過屢次的嘗試探索最佳的$k$值。
- K-means算法第一次迭代時的$k$個聚類中心對算法最終結果有很大影響,但在K-means算法中,第一次迭代的$k$各聚類中心是隨機選定的,這給算法聚類結果帶來了不肯定性。
- K-means算法對非球狀分佈的數據集上表現不佳。K-means算法這類基於距離的聚類算法基本假設是同一類簇內部對象間距離遠小於不一樣類簇間對象距離,這種假設至關於將類簇看做是一個球狀,因此對非球狀分佈的數據集,K-means算法表現可能並不佳。
- K-means算法在不斷迭代過程當中使得算法逐漸優化,在每一次迭代中,都必須計算每個對象與聚類中心的距離,因此當數據量很是大時,時間開銷比較大。
天下沒有免費的偏差,也沒有適合全部場景的算法,想要享受算法有點,就必須承受算法的不足,根據實際應用選擇合適的算法纔是最佳選擇。
3 python實現K-means算法¶