K-means演算法簡介
K-means是機器學習中一個比較常用的演算法,屬於無監督學習演算法,其常被用於資料的聚類,只需為它指定簇的數量即可自動將資料聚合到多類中,相同簇中的資料相似度較高,不同簇中資料相似度較低。
K-menas的優缺點:
優點:
- 原理簡單
- 速度快
- 對大資料集有比較好的伸縮性
缺點:
- 需要指定聚類 數量K
- 對異常值敏感
- 對初始值敏感
K-means的聚類過程
其聚類過程類似於梯度下降演算法,建立代價函式並通過迭代使得代價函式值越來越小
- 適當選擇c個類的初始中心;
- 在第k次迭代中,對任意一個樣本,求其到c箇中心的距離,將該樣本歸到距離最短的中心所在的類;
- 利用均值等方法更新該類的中心值;
- 對於所有的c個聚類中心,如果利用(2)(3)的迭代法更新後,值保持不變,則迭代結束,否則繼續迭代。
該演算法的最大優勢在於簡潔和快速。演算法的關鍵在於初始中心的選擇和距離公式。
K-means 例項展示
python中km的一些引數:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
sklearn.cluster.KMeans( n_clusters=8, init='k-means++', n_init=10, max_iter=300, tol=0.0001, precompute_distances='auto', verbose=0, random_state=None, copy_x=True, n_jobs=1, algorithm='auto' ) n_clusters: 簇的個數,即你想聚成幾類 init: 初始簇中心的獲取方法 n_init: 獲取初始簇中心的更迭次數,為了彌補初始質心的影響,演算法預設會初始10個質心,實現演算法,然後返回最好的結果。 max_iter: 最大迭代次數(因為kmeans演算法的實現需要迭代) tol: 容忍度,即kmeans執行準則收斂的條件 precompute_distances:是否需要提前計算距離,這個引數會在空間和時間之間做權衡,如果是True 會把整個距離矩陣都放到記憶體中,auto 會預設在資料樣本大於featurs*samples 的數量大於12e6 的時候False,False 時核心實現的方法是利用Cpython 來實現的 verbose: 冗長模式(不太懂是啥意思,反正一般不去改預設值) random_state: 隨機生成簇中心的狀態條件。 copy_x: 對是否修改資料的一個標記,如果True,即複製了就不會修改資料。bool 在scikit-learn 很多介面中都會有這個引數的,就是是否對輸入資料繼續copy 操作,以便不修改使用者的輸入資料。這個要理解Python 的記憶體機制才會比較清楚。 n_jobs: 並行設定 algorithm: kmeans的實現演算法,有:’auto’, ‘full’, ‘elkan’, 其中 ‘full’表示用EM方式實現 雖然有很多引數,但是都已經給出了預設值。所以我們一般不需要去傳入這些引數,引數的。可以根據實際需要來呼叫。 |
下面展示一個程式碼例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
from sklearn.cluster import KMeans from sklearn.externals import joblib from sklearn import cluster import numpy as np # 生成10*3的矩陣 data = np.random.rand(10,3) print data # 聚類為4類 estimator=KMeans(n_clusters=4) # fit_predict表示擬合+預測,也可以分開寫 res=estimator.fit_predict(data) # 預測類別標籤結果 lable_pred=estimator.labels_ # 各個類別的聚類中心值 centroids=estimator.cluster_centers_ # 聚類中心均值向量的總和 inertia=estimator.inertia_ print lable_pred print centroids print inertia 程式碼執行結果 [0 2 1 0 2 2 0 3 2 0] [[ 0.3028348 0.25183096 0.62493622] [ 0.88481287 0.70891813 0.79463764] [ 0.66821961 0.54817207 0.30197415] [ 0.11629904 0.85684903 0.7088385 ]] 0.570794546829 |
為了更直觀的描述,這次在圖上做一個展示,由於影像上繪製二維比較直觀,所以資料調整到了二維,選取100個點繪製,聚類類別為3類
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
from sklearn.cluster import KMeans from sklearn.externals import joblib from sklearn import cluster import numpy as np import matplotlib.pyplot as plt data = np.random.rand(100,2) estimator=KMeans(n_clusters=3) res=estimator.fit_predict(data) lable_pred=estimator.labels_ centroids=estimator.cluster_centers_ inertia=estimator.inertia_ #print res print lable_pred print centroids print inertia for i in range(len(data)): if int(lable_pred[i])==0: plt.scatter(data[i][0],data[i][1],color='red') if int(lable_pred[i])==1: plt.scatter(data[i][0],data[i][1],color='black') if int(lable_pred[i])==2: plt.scatter(data[i][0],data[i][1],color='blue') plt.show() |
可以看到聚類效果還是不錯的,對k-means的聚類效率進行了一個測試,將維度擴寬到50維
資料規模 | 消耗時間 | 資料維度 |
---|---|---|
10000條 | 4s | 50維 |
100000條 | 30s | 50維 |
1000000條 | 4’13s | 50維 |
對於百萬級的資料,擬合時間還是能夠接受的,可見效率還是不錯,對模型的儲存與其它的機器學習演算法模型儲存類似
1 2 |
from sklearn.externals import joblib joblib.dump(km,"model/km_model.m") |