K-means聚类算法(python实现简单原理)

K-means聚类算法

具体步骤

步骤流程图

具体代码

import random
import matplotlib.pylab as plt
#产生随机50个点
#这里产生数据并保存数据,不然每次数据总变来变去的,要是代码写得不当,也不太方便查看
def producte_data(): 
    f = open("data.csv","w")
    for i in range(50):
        a = random.randint(1,10)
        b = random.randint(1,10)
        f.write(str(a)+','+str(b)+'\n')
    f.close()
def read_data(): #读取数据
    f = open("data.csv")
    lines = f.readlines()
    f.close()
    L = []
    for line in lines:
        line = line.strip('\n').split(',')
        l = [eval(i) for i in line]
        L.append(l)
    return L#所有点
def random_data(L,K):#随机产生中心点
    random.seed(250)
    C = []
    i = 0
    while i<K:
        c = random.choice(L)  #随机选择三个点
        i = i+1
        if c not in C: #如果产生一样的随机点
            C.append(c)
        else:
            i = i-1
    return C#中心点
def sort_data(L,C,n): #分类 
    dic = {} #[坐标,属于类]
    for line in L:
        D = []
        for i in range(len(C)):
            d = ((line[0]-C[i][0])**2+(line[1]-C[i][1])**2)**0.5
            D.append((d,tuple(C[i])))  #tuple(C[i])想作为字典的键,键不可变
        near = min(D) #选出最近的点
        if near[1] not in dic:
            dic[near[1]] = [line]
        else:
            value = dic[near[1]]  #点分类
            value.append(line)
            dic[near[1]] = value
    #算中心距离,寻找新的中心点
    new_L = []
    for i in dic.items():
        if n == 0:
            sx = 0
            sy = 0
            coun = 0
        else:
            
            sx = i[0][0]
            sy = i[0][1]
            coun = 1 #数这一类点的个数,方便再次产生新的中心点
        for j in i[1]:
            coun = coun+1
            sx = sx+j[0]
            sy = sy+j[1]
        sx = sx/coun
        sy = sy/coun   
        new_L.append([sx,sy])
    return new_L,dic  
def draw(dic):
    color = ['pink','blue','green','black','purple','yellow','lightgrey']
    i = 0
    for value in dic.items():
        c = color[i]
        plt.scatter(value[0][0], value[0][1], color=c,s=len(value[1])*10) #聚类中心的点
        for v in value[1]:
            plt.scatter(v[0], v[1], color=c)
        i = i+1
    plt.title("Sorting position")
    plt.show()
def draw_begin(L):#展示初始状态的点的分布
    for value in L:
        plt.scatter(value[0],value[1],color = 'black')
    plt.title("Starting position")
    plt.show() 
producte_data() #随机产生数据集
L = read_data()  #L为所有点
draw_begin(L)
K = eval(input("请输入想要将这些点分为类的个数:"))
C = random_data(L,K)#C为中心点
n = 0
new_L,dic = sort_data(L,C,n)
while(n<100): #限定条件1迭代次数为100
    for i in range(K):
        d = ((L[i][0]-new_L[i][0])**2+(L[i][1]-new_L[i][1])**2)**0.5 
        if d >1: #限定条件2 新的聚类中心和之间的聚类中心误差小于1
            n = n+1
            new_L,dic = sort_data(L,new_L,n)
        if d <1:
            n = 101
draw(dic)

效果图
在这里插入图片描述
K=3
在这里插入图片描述
K=5
在这里插入图片描述
因为数据是随机产生的,如果不保持数据文件,每次产生的效果都不同哦。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值