kmeans算法代码实现

import matplotlib.pyplot as plt #画图用
import random
import copy
import operator #判断列表相等
k=2 #簇数量
data=[(1,2),(2,3),(2,4),(3,3),(10,16)]
def show(x):
    for j in x:
        plt.scatter([i[0] for i in j],[i[1] for i in j])#取第一列元素
   #plt.show()
    plt.savefig('zz.png')

# 1,随机选定K个值作为初始聚类中心
def chushi():
    core=[]
    data3=copy.deepcopy(data) #避免出现修改原数据的情况
    for i in range(k):
        el=random.choice(data3)
        data3.remove(el)#排除重复元素
        core.append(el)
    print("初始核心为",core)
   # print("数组为",data)
    return core
# 2,求每个样本与K个聚中心的距离,取最近的中心,作为该样本的标记中心
def setcu():
    p = [[] for j in range(k)]
    return p
def getjuli(x):
    p=setcu()

    for i in data:
        num = 0  # 数组号
        num1= 0
        juli = 1000  # 距离
        for j in x:

            len=pow(pow(i[0]-j[0],2)+pow(i[1]-j[1],2),0.5)
            len=round(len,2)
            print(len)
            num = num + 1
            if(len<juli):
                juli=len
                num1=num
        print("分组为",num1-1)
        p[num1-1].append(i)
    return p


# 3,求各个聚类簇的均值,得出k个新的中心点
def leijia(x):
    num=0
    x1=0
    y1=0
    re=[]
    if(x!=[]):
        for i in x:
            num=num+1
            x1=x1+i[0]
            y1=y1+i[1]
        x1=x1/num
        x1=round(x1,2)
        y1=y1/num
        y1=round(y1, 2)
        re.append(x1)
        re.append(y1)
        return re
    else:
        return []
# 如果与旧中心点一样,结束聚类过程

# 如果与旧中心点不一样,将新的中心点作为聚类中心重复第二步
#
# 确定K中心点个数的方法:1,经验法
#
# 2,手肘法,通过观察中心点K数量和簇内误方差SSE相关曲线,找到最低的一个点就是最佳的K值

if __name__ == '__main__':
    core=chushi();
    p=getjuli(core)
    print("第一组有",p[0])
    print("第二组有",p[1])
    print("聚类一次后,第一组核心",leijia(p[0]))
    print("聚类一次后,第二组核心",leijia(p[1]))
    num=1
    while(1):
        newcore=[]
        newcore.append(leijia(p[0]))
        newcore.append(leijia(p[1]))
        core=newcore
        print("——————————————————第",num,"次分类过程————————————————————————————————")
        num=num+1
        print("新聚类核心为",core)
        p = getjuli(core)
        print("间距为",leijia(p[0]))
        print("间距为",leijia(p[1]))
        print("第一组有", p[0])
        print("第二组有", p[1])
        if(operator.eq(core[0],leijia(p[0]))&operator.eq(core[1],leijia(p[1]))):
            break
    print("最终聚类核心为",core)
    data1=[]
    data1.append(p[0])
    data1.append(p[1])
    print(data1)
    show(data1)

运行结果:

 

 

 生成图片为:

 

posted @ 2022-09-09 17:38  凋零_(  阅读(102)  评论(0编辑  收藏  举报