1、首先确定一个k值,即我们希望将数据集经过聚类得到k个集合。
2、从数据集中随机选择k个数据点作为质心。
3、对数据集中每一个点,计算其与每一个质心的距离(如欧式距离),离哪个质心近,就划分到那个质心所属的集合。
4、把所有数据归好集合后,一共有k个集合。然后重新计算每个集合的质心。
5、如果新计算出来的质心和原来的质心之间的距离小于某一个设置的阈值(表示重新计算的质心的位置变化不大,趋于稳定,或者说收敛),我们可以认为聚类已经达到期望的结果,算法终止。
6、如果新质心和原质心距离变化很大,需要迭代3~5步骤。
1、原理比较简单,实现也是很容易,收敛速度快。
2、当结果簇是密集的,而簇与簇之间区别明显时, 它的效果较好。
3、主要需要调参的参数仅仅是簇数k。
1、K值需要预先给定,很多情况下K值的估计是非常困难的。
2、K-Means算法对初始选取的质心点是敏感的,不同的随机种子点得到的聚类结果完全不同 ,对结果影响很大。
3、对噪音和异常点比较的敏感。用来检测异常值。
4、采用迭代方法,可能只能得到局部的最优解,而无法得到全局的最优解。
def KMeans(k,data,bias):# 二维聚类
if k<2 or data==[] or data==[[]] or not isinstance(data,list) or len(data)<k:
return False
import random
center_points=random.sample(data, k)
while 1:
center_points_set=[[] for i in range(k)]
for i in range(len(data)):
for j in range(len(center_points)):
if j ==0:
dis=abs(data[i][0]-center_points[j][0])**2+abs(data[i][1]-center_points[j][1])**2
belong=j
elif abs(data[i][0]-center_points[j][0])**2+abs(data[i][1]-center_points[j][1])**2 <dis:
dis=abs(data[i][0]-center_points[j][0])**2+abs(data[i][1]-center_points[j][1])**2
belong=j
if j == len(center_points)-1:
center_points_set[belong].append(data[i])
new_center_points = []
for i in range(len(center_points_set)):
sum=0
for j in range(len(center_points_set[i])):
sum+=center_points_set[i][j]
new_center_points.append(sum/len(center_points_set))
done= True
for i in range(len(center_points)):
for j in range(len(new_center_points)):
if j==0:
dis=abs(new_center_points[j][0] - center_points[i][0]) ** 2 + abs(data[j][1] - center_points[i][1]) ** 2
elif abs(new_center_points[j][0] - center_points[i][0]) ** 2 + abs(data[j][1] - center_points[i][1]) ** 2<dis:
dis=abs(new_center_points[j][0] - center_points[i][0]) ** 2 + abs(data[j][1] - center_points[i][1]) ** 2
if j == len(new_center_points)-1:
if dis >bias**2:done=False
if done:return new_center_points