Python实现Sequential Leader Cluster算法,可视化

运行效果: 

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")