在k-means算法里開始選取的聚類中點是隨機的,每次都會照成不同的聚類結果。有一個解決方案叫做k-means++,可以有效的選擇初始聚類中心點。參考 http://theory.stanford.edu/~sergei/papers/kMeansPP-soda.pdf。
在《白話大數據與機器學習》里使用了sklearn里的KMeans來處理數據, 默認使用的就是k-means++:
訓練模型 clf = KMeans(n_clusters=3, init=’k-means++’).fit(x, y)
這里我們來實現一下k-means++算法,看看該算法具體是如何實現的。
1 訓練模型
使用kmeans++算法初始化聚類中點:
假設有一個數據集合X,里面有N條記錄。
[x1, x2, x3, x4, x5, x6, ...]
第一次從X中隨機取一條記錄xi,當做聚類的第一個中心點。
然后重復以下步驟:
對每條記錄,計算其與最近的一個中點之間的距離D(xn)並保存到一個數據組里,計算距離公式有很多,歐式距離,曼哈頓距離等。
D(x) = [D(x1), D(x2), D(x3), D(x4), D(x5), D(x6), ...]
對計算得到的距離加和
Sum(D(x))
然后再用D(x)里的各條記錄分別除以距離加和值 D(xn)/Sum(D(x))
[D(x1)/Sum(D(x)),
D(x2)/Sum(D(x)),
D(x3)/Sum(D(x)),
D(x4)/Sum(D(x)),
D(x5)/Sum(D(x)),
D(x6)/Sum(D(x)), ... ...]
得到下面這樣的概率分布數組
[P(x1),
P(x2),
P(x3),
P(x4),
P(x5),
P(x6),
...]
接着計算累加和
[P(x1),
P(x1) + P(x2),
P(x1) + P(x2) + P(x3),
P(x1) + P(x2) + P(x3) + P(x4),
P(x1) + P(x2) + P(x3) + P(x4) + P(x5),
P(x1) + P(x2) + P(x3) + P(x4) + P(x5) + P(x6),
... ...]
從該數組中隨機取一條記錄,用它的下標在記錄X中取值 當做下一個聚類中心點。
當聚類中心點初始完畢之后接下來就是使用k-means算法,聚攏各類:
計算所有點和各個中心點之間的距離,取離自己最近的中心點歸為那個聚類。
{0: [x1, x2, x3],
1: [x4, x5, x6],
......}
重新計算各個簇的中點,取各個特征列的均值,得到新的中心點。
[(x1 + x2 + x3) / 3,
(x4 + x5 + x6) / 3,
...]
重復上述步驟 直到沒有中心點移動。
完整代碼可以訪問https://github.com/azheng333/Ml_Algorithm.git進行下載。
(完)
關注大數據尖端技術發展,關注奇點大數據