1. 程式人生 > >K-means和K-means++的演算法原理及sklearn庫中引數解釋、選擇

K-means和K-means++的演算法原理及sklearn庫中引數解釋、選擇

前言:

  這篇博文主要介紹k-means聚類演算法的基本原理以及它的改進演算法k-means的原理及實現步驟,同時文章給出了sklearn機器學習庫中對k-means函式的使用解釋和引數選擇。

K-means介紹:

  K-means演算法是很典型的基於距離的聚類演算法,採用距離 作為相似性的評價指標,即認為兩個物件的距離越近,其相似度就越大。該演算法認為簇是由距離靠近的物件組成的,因此把得到緊湊且獨立的簇作為最終目標。
  k-means演算法特點在於:同一聚類的簇內的物件相似度較高;而不同聚類的簇內的物件相似度較小
  

演算法實現過程:


這裡寫圖片描述

 1、隨機在圖中取K(這裡K=2)個種子點。
 2、然後對圖中的所有點求到這K個種子點的距離,假如點Pi離種子點Si最近,那麼Pi屬於Si點群。(上圖中,我們可以看到A,B屬於上面種子的點群,C,D,E屬於下面種子的點群)
 3、接下來,我們要移動種子點到屬於他的“點群”的中心。(見圖上的第三步),這裡求中心的方法最簡單的是直接將中心定為點群各個座標的平均值

,也可以參考下面三種求中心的方法。
 4、然後重複第2)和第3)步,直到,種子點沒有移動(我們可以看到圖中的第四步上面的種子點聚合了A,B,C,下面的種子點聚合了D,E)。
 

求聚類中心的另外三種方法:

(1)Minkowski Distance 公式 —— λ 可以隨意取值,可以是負數,也可以是正數,或是無窮大。


這裡寫圖片描述

(2)Euclidean Distance 公式 —— 也就是第一個公式 λ=2 的情況


這裡寫圖片描述

(3)CityBlock Distance 公式 —— 也就是第一個公式 λ=1 的情況


這裡寫圖片描述

這三個公式的求中心點有一些不一樣的地方,這三個方法逼近中心的方式不太一樣,第一種以星形的方式,第二種以同心圓的方式,第三種以菱形的方式。

----------------------------------

k-means 優缺點:

K-Means聚類演算法的優點主要集中在:
 1.演算法快速、簡單;
 2.對大資料集有較高的效率並且是可伸縮性的;
 3.時間複雜度近於線性,而且適合挖掘大規模資料集。K-Means聚類演算法的時間複雜度是O(n×k×t) ,其中n代表資料集中物件的數量,t代表著演算法迭代的次數,k代表著簇的數目 

k-means的缺點:
  1、在 K-means 演算法中 K 是事先給定的,這個 K 值的選定是非常難以估計的。很多時候,事先並不知道給定的資料集應該分成多少個類別才最合適。
  2、 在 K-means 演算法中,首先需要根據初始聚類中心來確定一個初始劃分,然後對初始劃分進行優化。這個初始聚類中心的選擇對聚類結果有較大的影響,一旦初始值選擇的不好,可能無法得到有效的聚類結果,這也成為 K-means演算法的一個主要問題。
  3、從 K-means 演算法框架可以看出,該演算法需要不斷地進行樣本分類調整,不斷地計算調整後的新的聚類中心,因此當資料量非常大時,演算法的時間開銷是非常大的。所以需要對演算法的時間複雜度進行分析、改進,提高演算法應用範圍。


  
對於上述的初始聚類中心的選擇可以用k-means++來解決:

k-means ++介紹:

k-means++演算法選擇初始seeds的基本思想就是:初始的聚類中心之間的相互距離要儘可能的遠。

演算法步驟:
(1)從輸入的資料點集合中隨機選擇一個點作為第一個聚類中心
(2)對於資料集中的每一個點x,計算它與最近聚類中心(指已選擇的聚類中心)的距離D(x)
(3)選擇一個新的資料點作為新的聚類中心,選擇的原則是:D(x)較大的點,被選取作為聚類中心的概率較大
(4)重複2和3直到k個聚類中心被選出來
(5)利用這k個初始的聚類中心來執行標準的k-means演算法

  從上面的演算法描述上可以看到,演算法的關鍵是第3步,如何將D(x)反映到點被選擇的概率上,一種演算法如下:
(1)先從我們的資料庫隨機挑個隨機點當“種子點”
(2)對於每個點,我們都計算其和最近的一個“種子點”的距離D(x)並儲存在一個數組裡,然後把這些距離加起來得到Sum(D(x))。
(3)然後,再取一個隨機值,用權重的方式來取計算下一個“種子點”。這個演算法的實現是,先取一個能落在Sum(D(x))中的隨機值Random,然後用Random -= D(x),直到其<=0,此時的點就是下一個“種子點”。
(4)重複2和3直到k個聚類中心被選出來
(5)利用這k個初始的聚類中心來執行標準的k-means演算法
可以看到演算法的第三步選取新中心的方法,這樣就能保證距離D(x)較大的點,會被選出來作為聚類中心了。至於為什麼原因比較簡單,如下圖 所示:
這裡寫圖片描述

假設A、B、C、D的D(x)如上圖所示,當演算法取值Sum(D(x))*random時,該值會以較大的概率落入D(x)較大的區間內,所以對應的點會以較大的概率被選中作為新的聚類中心。

sklearn.cluster.KMeans 引數介紹

為什麼要介紹sklearn這個庫裡的kmeans?
  這個是現在python機器學習最流行的整合庫,同時由於要用這個方法,直接去看英文文件既累又浪費時間、效率比較低,所以還不如平時做個筆記、打個基礎。
  這裡還有一個原因,上面介紹了k-means++,sklearn.cluster.KMeans這個類對於初始聚類中心的選擇剛好預設選擇的就是k-means ++。

引數:

n_clusters:整形,預設值=8 【生成的聚類數,即產生的質心(centroids)數。】
max_iter:整形,預設值=300
執行一次k-means演算法所進行的最大迭代數。
n_init:整形,預設值=10
用不同的質心初始化值執行演算法的次數,最終解是在inertia意義下選出的最優結果。
init:有三個可選值:’k-means++’, ‘random’,或者傳遞一個ndarray向量。
此引數指定初始化方法,預設值為 ‘k-means++’。
(1)‘k-means++’ 用一種特殊的方法選定初始質心從而能加速迭代過程的收斂(即上文中的k-means++介紹
(2)‘random’ 隨機從訓練資料中選取初始質心。
(3)如果傳遞的是一個ndarray,則應該形如 (n_clusters, n_features) 並給出初始質心。
precompute_distances:三個可選值,‘auto’,True 或者 False。
預計算距離,計算速度更快但佔用更多記憶體。
(1)‘auto’:如果 樣本數乘以聚類數大於 12million 的話則不預計算距離。This corresponds to about 100MB overhead per job using double precision.
(2)True:總是預先計算距離。
(3)False:永遠不預先計算距離。
tol:float形,預設值= 1e-4 與inertia結合來確定收斂條件。
n_jobs:整形數。 指定計算所用的程序數。內部原理是同時進行n_init指定次數的計算。
(1)若值為 -1,則用所有的CPU進行運算。若值為1,則不進行並行運算,這樣的話方便除錯。
(2)若值小於-1,則用到的CPU數為(n_cpus + 1 + n_jobs)。因此如果 n_jobs值為-2,則用到的CPU數為總CPU數減1。
random_state:整形或 numpy.RandomState 型別,可選
用於初始化質心的生成器(generator)。如果值為一個整數,則確定一個seed。此引數預設值為numpy的隨機數生成器。
copy_x:布林型,預設值=True
當我們precomputing distances時,將資料中心化會得到更準確的結果。如果把此引數值設為True,則原始資料不會被改變。如果是False,則會直接在原始資料
上做修改並在函式返回值時將其還原。但是在計算過程中由於有對資料均值的加減運算,所以資料返回後,原始資料和計算前可能會有細小差別。

屬性:

cluster_centers_:向量,[n_clusters, n_features] (聚類中心的座標)

Labels_: 每個點的分類
inertia_:float形
每個點到其簇的質心的距離之和。

Notes:
  這個k-means運用了 Lioyd’s 演算法,平均計算複雜度是 O(k*n*T),其中n是樣本量,T是迭代次數。
  計算複雜讀在最壞的情況下為 O(n^(k+2/p)),其中n是樣本量,p是特徵個數。(D. Arthur and S. Vassilvitskii, ‘How slow is the k-means method?’ SoCG2006)
  在實踐中,k-means演算法時非常快的,屬於可實踐的演算法中最快的那一類。但是它的解只是由特定初始值所產生的區域性解。所以為了讓結果更準確真實,在實踐中要用不同的初始值重複幾次才可以。

Methods:

fit(X[,y]):
 計算k-means聚類。
fit_predictt(X[,y]):
 計算簇質心並給每個樣本預測類別。
fit_transform(X[,y]):
計算簇並 transform X to cluster-distance space。
get_params([deep]):
 取得估計器的引數。
predict(X):predict(X)
 給每個樣本估計最接近的簇。
score(X[,y]):
 計算聚類誤差
set_params(**params):
 為這個估計器手動設定引數。
transform(X[,y]): 將X轉換為群集距離空間。
 在新空間中,每個維度都是到叢集中心的距離。 請注意,即使X是稀疏的,轉換返回的陣列通常也是密集的。

參考文獻: