Python实现Sequential Leader Cluster算法,可视化
运行效果:
算法流程:
依次判断每个点,如果这个还没有簇的话,这个点自己成为一个类,如果已经有簇了,如果这个点到已有簇们的距离最小值足够小,就归为距离最小值的一簇,如果距离别的簇都很距离都不够小,那么设为新的一簇。
缺陷:
算法的进程不同会产生不一样的结果,如果A先进行分类,会自己成一类,然后B和A如果距离超过了阈值一点,B也会单独成为一类;如果A,B的距离不变,但是A,B中间插入了许多值,导致A类的平均值向着B靠拢,那么到B的时候AB就会在同一类中。
需要人工设定阈值。
优势:不需要迭代求解,时间复杂度大致为:点数*类别数
Python代码:
import matplotlib.pyplot as plt
import numpy as np
#随机生成大致是K个类别的点,用均匀分布生成中心点的位置,用高斯分布生成中心点周围的点
def generatorN(K):
center=[[np.random.rand(1)*20,np.random.rand(1)*20] for _ in range(K)]
_data=[]
for x, y in center:
_data.append([np.random.randn(100)+x ,np.random.randn(100)+y])
return _data
#画图
def draw_data(_groups):
#fig=plt.figure(dpi=180)
plt.title("画图")
for xys in _groups.values():
xs=[xy[0] for xy in xys]
ys=[xy[1] for xy in xys]
plt.scatter(xs,ys)
plt.show()
data=generatorN(5)
data=np.transpose(data,(0,2,1)).reshape((-1,2))
threshhold=5
results={}
for x,y in data:
min_distance=100000
for center_x,center_y in results.keys():
distance=(x-center_x)**2+(y-center_y)**2
if distance<min_distance:
min_distance=distance
min_x=center_x
min_y=center_y
if min_distance<=threshhold:
results[(min_x,min_y)].append([x,y])
sum_x=0
sum_y=0
len_values=len(results[(min_x,min_y)])
for x_,y_ in results[(min_x,min_y)]:
sum_x+=x_
sum_y+=y_
results[(sum_x/len_values,sum_y/len_values)]=results.pop((min_x,min_y))
else: #新建一簇的条件是这个点和其他簇的距离比阈值要大 or 还没有簇
results[(x,y)]=[[x,y]]
draw_data(results)
print("done")