python手写K-means实现二维聚类

2022-07-25,,

欢迎来到海小皮的CSDN博客
今天人工智能的实验,简单学习了K-means的二维聚类,在这里介绍给大家,注释非常详细哦!
1、思路介绍
这个方法理解起来不是特别的难,首先我来介绍一下基本思路,我以比较通俗易懂的比喻来讲解:
(1)现在往地面上撒了一把豆子(随机散布),每个豆子有自己的二维坐标(两个维度的变量)
(2)首先随机选K个豆子作为初始的代表人物(初始中心点),他们代表了各自的团体(聚类子集)
(3)每个豆子都计算自己到各个代表人物间的距离,加入距离自己最近的代表人物的团队,得到初始聚类
(4)计算每一个聚类子集的中心点,选出新的代表人物(新的中心点)
(5)重复(3)(4)步,直到聚类不再发生变化

2、代码参考

import numpy as np
import random as rd
import matplotlib.pyplot as plt

# 测试数据
TEST = [(1,7),(2,6),(3,5),(8,1.5),(7,2.5),(1,1),(9,6),(3,8),(0.5,4),(5,3.2),(2,2),(4,3),(5,4),(4,2),(5,3),(2,1)]
# 药品数据
Yao_list = [(1,1),(2,2),(4,3),(5,4)]

# 获取初始聚类点
def get_init_center(raw_data,k):
    return rd.sample(raw_data,k)

# 计算距离
def cal_distance(x,y):
    return np.linalg.norm(np.array(x)-np.array(y))

# 分簇
def divid_cluster(center,raw_data):
    cluster = [] # 创建聚类的集合
    # 创建聚类的子集 数量等于中心点数
    for i in range(len(center)):
        cluster.append([])
    dis = 0.0 # 初始化距离
    # 取出每一个点进行距离判断
    for node in raw_data:
        dis_min = float('inf') # 重新初始化距离最小值
        flag = -1 # 重新初始化位置标志位
        # 与每一个center计算距离 找到最短
        for item in center:
            dis = cal_distance(node,item)
            if(dis < dis_min):
                dis_min = dis # 更新最小值
                flag += 1
        
        # 将node添加到对应的聚类子集
        if flag != -1 :
            cluster[flag].append(node)
    return cluster

# 计算新的中心点
def cal_new_cnter(cluster_son):
    x_sum ,y_sum =0,0#初始化
    for node in cluster_son:
        x_sum += node[0]
        y_sum += node[1]
    # 创建tuple
    re_center = (x_sum/len(cluster_son),y_sum/len(cluster_son))
    return re_center

# 开始
K = 2 # 聚类的集合数
Raw_data = TEST # 选取二维数据集合
Linit_stop = 5000
# 随机选择 k个点作为初始中心点
init_center = get_init_center(Raw_data,K)

print('init centers',init_center)

# 进行聚类初始化
init_cluster =  divid_cluster(init_center,Raw_data)

print('init clusters',init_cluster)

old_cluster = init_cluster
new_cluster = []
count = 0
while True:
    count += 1
    new_centers = []
    # 计算新的聚类子集中心点
    for item in old_cluster:
        temp_center = cal_new_cnter(item) # 计算子集中心点
        new_centers.append(temp_center) # 放入新的中心点集合
    print(count,'new centers',new_centers)

    # 根据新的中心点进行迭代
    new_cluster = divid_cluster(new_centers,Raw_data)
    print(count,'new cluster',new_cluster)

    if new_cluster == old_cluster:
        break
    else:
        old_cluster = new_cluster

    if count == Linit_stop:
        break

# 画图
x = []
y = []
count = 0
for item in old_cluster:
    x = []
    y = []
    count += 1
    for node in item:
        x.append(node[0])
        y.append(node[1])
    if count == 1:
        # 聚类
        plt.scatter(x,y,s=5,c='b')
        # 中心
        plt.scatter(new_centers[0][0],new_centers[0][1],s=50,c='y')
    elif count == 2:
        # 聚类
        plt.scatter(x,y,s=20,c='r')
        # 中心
        plt.scatter(new_centers[1][0],new_centers[1][1],s=50,c='g')

plt.show()

因为初始中心点是随机选择的,所以每次的聚类结果基本上是不同的,所以你运行的结果未必和我的相同
TEST的运行结果
药品分类数据的运行结果
欢迎互相交流,初次学习,多多指教!
如果有帮助麻烦点个赞再走蛤!

本文地址:https://blog.csdn.net/weixin_42464904/article/details/111939506

《python手写K-means实现二维聚类.doc》

下载本文的Word格式文档,以方便收藏与打印。