一、算法簡介
- 均值漂移算法首先找到一個中心點center(隨機選擇),然后根據半徑划分一個范圍
- 把這個范圍內的點輸入簇c的標記個數加1
- 在這個范圍內,計算其它點到這個點的平均距離,並把這個平均距離當成偏移量 shift
- 把中心點center移動偏移量 shift 個單位,當成新的中心點
- 重復上述步驟直到 shift小於一定閾值,即收斂
- 如果當前簇c的center和另一個簇c2的center距離小於一定閾值,則把當前簇歸類為c2,否則聚類的類別+1
- 重復1、2、3、4、5、6直到所有點都遍歷過
- 如果一個點既被簇c1遍歷過,也被簇c2遍歷過,則把其歸類為標記數多的簇
根據上述描述均值漂移聚類也就是根據密度來聚類的,樣本會屬於密度最大的那個類別的簇
二、一些計算
1、基礎偏移量
- Sh為球半徑內的點集合
- 也就是用集合內的點與質心相減得到累計的偏移量
2、高斯偏移量
- 在基礎偏移量計算中,集合范圍內距離簇心越遠的點擁有越大的權重,這不合理
- 距離簇心越近的點應該跟簇心的類別越接近,因此此類的點應該有更大的權重
3、更新新的質心為
三、Code
1 from scipy.spatial import distance 2 from sklearn.neighbors import NearestNeighbors 3 from sklearn.cluster.dbscan_ import DBSCAN 4 from sklearn.cluster.dbscan_ import dbscan 5 import numpy as np 6 from matplotlib import pyplot as plt 7 from sklearn.cluster import MeanShift, estimate_bandwidth 8 9 from sklearn.cluster.tests.common import generate_clustered_data 10 11 min_samples = 10 12 eps = 0.0309 13 14 X = generate_clustered_data(seed=1, n_samples_per_cluster=1000) 15 16 #quantile 控制是否同一類別的距離 17 bandwidth = estimate_bandwidth(X, quantile=0.3, n_samples=len(X)) 18 meanshift = MeanShift(bandwidth=bandwidth, bin_seeding=True) # 構建對象 19 meanshift.fit(X) 20 labels = meanshift.labels_ 21 22 print(np.unique(labels)) 23 24 fig, ax = plt.subplots() 25 cluster_num = len(np.unique(labels)) # label的個數,即自動划分的族群的個數 26 for i in range(0, cluster_num): 27 x = [] 28 y = [] 29 for ind, label in enumerate(labels): 30 if label == i: 31 x.append(X[ind][0]) 32 y.append(X[ind][1]) 33 ax.scatter(x, y, s=1) 34 35 plt.show()
結果