公號:碼農充電站pro
主頁:https://codeshellme.github.io
之前介紹到的一些機器學習演算法都是監督學習演算法。所謂監督學習,就是既有特徵資料,又有目標資料。
而本篇文章要介紹的K 均值演算法是一種無監督學習。
與分類演算法相比,無監督學習演算法又叫聚類演算法,就是隻有特徵資料,沒有目標資料,讓演算法自動從資料中“學習知識”,將不同類別的資料聚集到相應的類別中。
1,K 均值演算法
K 均值的英文為K-Means,其含義是:
- K:表示該演算法可以將資料劃分到K 個不同的組中。
- 均值:表示每個組的中心點是組內所有值的平均值。
K 均值演算法可以將一個沒有被分類的資料集,劃分到K 個類中。某個資料應該被劃分到哪個類,是通過該資料與群組中心點的相似度決定的,也就是該資料與哪個類的中心點最相似,則該資料就應該被劃分到哪個類中。
關於如何計算事物之間的相似度,可以參考文章《計算機如何理解事物的相關性》。
使用K 均值演算法的一般步驟是:
- 確定K 值是多少:
- 對於K 值的選擇,可以通過分析資料,估算資料應該分為幾個類。
- 如果無法估計確切值,可以多試幾個K 值,最終將劃分效果最好的K 值作為最終選擇。
- 選擇K 箇中心點:一般最開始的K 箇中心點是隨機選擇的。
- 將資料集中的所有資料,通過與中心點的相似度劃分到不同的類別中。
- 根據類別中的資料平均值,重新計算每個類別中心點的位置。
- 迴圈迭代第3,4步,直到中心點的位置幾乎不再改變,分類過程就算完畢。
2,K 均值演算法的實現
K 均值演算法是一個聚類演算法,sklearn 庫中的 cluster 模組實現了一系列的聚類演算法,其中就包括K 均值演算法。
來看下KMeans 類的原型:
KMeans(
n_clusters=8,
init='k-means++',
n_init=10,
max_iter=300,
tol=0.0001,
precompute_distances='deprecated',
verbose=0,
random_state=None,
copy_x=True,
n_jobs='deprecated',
algorithm='auto')
可以看KMeans 類有很多引數,這裡介紹幾個比較重要的引數:
- n_clusters: 即 K 值,可以隨機設定一些 K 值,選擇聚類效果最好的作為最終的 K 值。
- init:選擇初始中心點的方式:
- init='k-means++':可加快收斂速度,是預設方式,也是比較好的方式。
- init='random ':隨機選擇中心點。
- 也可以自定義方式,這裡不多介紹。
- n_init:初始化中心點的運算次數,預設是 10。如果 K 值比較大,可以適當增大 n_init 的值。
- algorithm:k-means 的實現演算法,有auto,full,elkan三種。
- 預設是auto,根據資料的特點自動選擇用full或者elkan。
- max_iter:演算法的最大迭代次數,預設是300。
- 如果聚類很難收斂,設定最大迭代次數可以讓演算法儘快結束。
下面對一些二維座標中的點進行聚類,看下如何使用K 均值演算法。
3,準備資料點
下面是隨機生成的三類座標點,每類有20 個點,不同類的點的座標在不同的範圍內:
- A 類點:Ax 表示A 類點的橫座標,Ay 表示A 類點的縱座標。橫縱座標範圍都是 (0, 20]。
- B 類點:Bx 表示B 類點的橫座標,By 表示B 類點的縱座標。橫縱座標範圍都是 (40, 60]。
- C 類點:Cx 表示C 類點的橫座標,Cy 表示C 類點的縱座標。橫縱座標範圍都是 (70, 90]。
Ax = [20, 6, 14, 13, 8, 19, 20, 14, 2, 11, 2, 15, 19, 4, 4, 11, 13, 4, 15, 11]
Ay = [14, 19, 17, 16, 3, 7, 9, 18, 20, 3, 4, 12, 9, 17, 14, 1, 18, 17, 3, 5]
Bx = [53, 50, 46, 52, 57, 42, 47, 55, 56, 57, 56, 50, 46, 46, 44, 44, 58, 54, 47, 57]
By = [60, 57, 57, 53, 54, 45, 54, 57, 49, 53, 42, 59, 54, 53, 50, 50, 58, 58, 58, 51]
Cx = [77, 75, 71, 87, 74, 70, 74, 85, 71, 75, 72, 82, 81, 70, 72, 71, 88, 71, 72, 80]
Cy = [85, 77, 82, 87, 71, 71, 77, 88, 81, 73, 80, 72, 90, 77, 89, 88, 83, 77, 90, 72]
我們可以用 Matplotlib 將這些點畫在二維座標中,程式碼如下:
import matplotlib.pyplot as plt
plt.scatter(Ax + Bx + Cx, Ay + By + Cy, marker='o')
plt.show()
畫出來的圖如下,可看到這三類點的分佈範圍還是一目瞭然的。
關於如何使用 Matplotlib 繪圖,可以參考文章《如何使用Python 進行資料視覺化》。
4,對資料聚類
下面使用K 均值演算法對資料點進行聚類。
建立K 均值模型物件:
from sklearn.cluster import KMeans
# 設定 K 值為 3,其它引數使用預設值
kmeans = KMeans(n_clusters=3)
準備資料,共三大類,60 個座標點:
train_data = [
# 前20 個為 A 類點
[20, 14], [6, 19], [14, 17], [13, 16], [8, 3], [19, 7], [20, 9],
[14, 18], [2, 20], [11, 3], [2, 4], [15, 12], [19, 9], [4, 17],
[4, 14], [11, 1], [13, 18], [4, 17], [15, 3], [11, 5],
# 中間20 個為B 類點
[53, 60], [50, 57], [46, 57], [52, 53], [57, 54], [42, 45], [47, 54],
[55, 57], [56, 49], [57, 53], [56, 42], [50, 59], [46, 54], [46, 53],
[44, 50], [44, 50], [58, 58], [54, 58], [47, 58], [57, 51],
# 最後20 個為C 類點
[77, 85], [75, 77], [71, 82], [87, 87], [74, 71], [70, 71], [74, 77],
[85, 88], [71, 81], [75, 73], [72, 80], [82, 72], [81, 90], [70, 77],
[72, 89], [71, 88], [88, 83], [71, 77], [72, 90], [80, 72],
]
擬合模型:
kmeans.fit(train_data)
對資料進行聚類:
predict_data = kmeans.predict(train_data)
檢視聚類結果,其中的0,1,2 分別代表不同的類別:
>>> print(predict_data)
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
通過觀察最終的聚類結果predict_data,可以看到,前,中,後20 個資料分別被分到了不同的類中,也非常符合我們的預期,說明K 均值演算法的聚類結果還是很不錯的 。
因為本例中的二維座標點的分佈界限非常明顯,所以最終的聚類結果非常不錯。
5,總結
本篇文章主要介紹了K 均值演算法的原理,及sklearn 庫對它的實現,並且演示瞭如何使用K 均值演算法對二維資料點進行聚類。
(本節完。)
推薦閱讀:
歡迎關注作者公眾號,獲取更多技術乾貨。