1. 程式人生 > >sklearn基本用法----K-means

sklearn基本用法----K-means

K-means(K-均值)

1.定義
       k-means演算法源於訊號處理中的一種向量量化方法,現在則更多地作為一種聚類分析方法流行於資料探勘領域。
       k-means聚類的目的是:把 n個點(可以是樣本的一次觀察或一個例項)劃分到k個聚類中,使得每個點都屬於離他最近的均值(此即聚類中心)對應的聚類,以之作為聚類的標準。用這k個聚類的均值來代表相應各類樣本時所得的總體誤差最小。這個問題將歸結為一個把資料空間劃分為Voronoi cells的問題。
       這個問題在計算上是困難的(NP困難),不過存在高效的啟發式演算法。一般情況下,都使用效率比較高的啟發式演算法,它們能夠快速收斂於一個區域性最優解。這些演算法通常類似於通過迭代優化方法處理高斯混合分佈的最大期望演算法(EM演算法)。而且,它們都使用聚類中心來為資料建模;然而k-means聚類傾向於在可比較的空間範圍內尋找聚類,期望-最大化技術卻允許聚類有不同的形狀。
       k-means演算法的基礎是最小誤差平方和準則,採用誤差平方和準則函式作為聚類準則函式。
       k-means聚類與k-nn(k-近鄰)之間沒有任何關係(後者是另一流行的機器學習技術),k-nn將在下一次部落格中介紹。
2.歷史


       雖然其思想能夠追溯到1957年的Hugo Steinhaus ,術語“k-均值”於1967年才被James MacQueen 首次使用。標準演算法則是在1957年被Stuart Lloyd作為一種脈衝碼調製的技術所提出,但直到1982年才被貝爾實驗室公開出版 。在1965年,E.W.Forgy發表了本質上相同的方法,所以這一演算法有時被稱為Lloyd-Forgy方法。更高效的版本則被Hartigan and Wong提出(1975/1979)A more efficient version was proposed and published in Fortran by Hartigan and Wong in 1975/1979。
3.演算法過程

(1)從N個數據物件中隨機選取K個物件作為初始聚類中心。
(2)對剩餘的每個資料物件按照最小距離原則把它分配到最近的中心物件的類。
(3)重新計算已經得到的各個類的均值(中心物件),讓它作為新的聚類中心。
(4)迭代2~3步直至新的中心物件與原中心物件相等或小於指定閾值,演算法結束
(5)得到k個聚類。
4.演算法優缺點
(1)優點:
      ①演算法簡單,快速;
      ②對大資料集有較高的效率且可收縮。
      ③時間複雜度近於線性,適合挖掘大規模資料集。
(2)缺點:
      ①在 K-means 演算法中 K 是事先給定的,這個 K 值的選定是非常難以估計的。很多時候,事先並不知道給定的資料集應該分成多少個類別才最合適。
      ②在 K-means 演算法中,首先需要根據初始聚類中心來確定一個初始劃分,然後對初始劃分進行優化。這個初始聚類中心的選擇對聚類結果有較大的影響,一旦初始值選擇的不好,可能無法得到有效的聚類結果,這也成為 K-means演算法的一個主要問題。對於該問題的解決,許多演算法採用遺傳演算法(GA)。
      ③ 從 K-means 演算法框架可以看出,該演算法需要不斷地進行樣本分類調整,不斷地計算調整後的新的聚類中心,因此當資料量非常大時,演算法的時間開銷是非常大的。所以需要對演算法的時間複雜度進行分析、改進,提高演算法應用範圍。
5.應用

       k-均值聚類(尤其是使用如Lloyd’s演算法的啟發式方法的聚類)即使是在巨大的資料集上也非常容易部署實施。正因為如此,它在很多領域都得到的成功的應用,如市場劃分、機器視覺、 地質統計學、天文學和農業等。它經常作為其他演算法的預處理步驟,比如要找到一個初始設定。

from sklearn import cluster,datasets
import numpy as np 

iris = datasets.load_iris()
X = iris.data
y = iris.target
km = cluster.KMeans(n_clusters = 3)
km.fit(X)
k_y = km.predict(X)
#根據實際情況設定對映
k2y = np.array([1,0,2])
print(k2y[k_y])
print((k2y[k_y] == y).astype(int).mean())

用pickle模組的方法儲存訓練後的模型,方便下次直接使用。

import pickle
with open('cc_kmean.pkl','wb') as f:
    pickle.dump(km,f)
with open('cc_kmean.pkl','rb') as f:
    cc_km = pickle.load(f)
print(cc_km.predict(X))
print((k2y[cc_km.predict(X)] == y).astype(int).mean())

辣麼多好吃噠,然額我並不是一個吃貨!!!
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述