KMEANS底层实现

# 导包
import numpy as np
import matplotlib.pyplot as plt
import copy
# 核心功能函数

# KMeans核心实现步骤:
#   0:设定质心, 只需要做一次
#   1、计算距离:即所有样本点到各质心的距离, 1行代码
#   2、计算极值:argmin ,1行代码
#   3、更新质心: 4行代码
#   4、重复1、2、3步,直到质心不在发生改变 , 2行

# 主函数
def main():
    # 加载数据,注意需要去掉标签值
    x = np.loadtxt('test.txt', encoding='utf-8')

    # 指定将数据集分成 k 个类别
    k = 4 # 指定质心数量

    # step:0,设定质心
    m, n = x.shape  # 数据集样本数m, 维度dim
    centers = np.zeros((k, n))  # 定义聚类中心存储矩阵
    # 根据设定的聚类中心数随机获取样本中的点作为初始聚类中心坐标
    for i in range(k):
        index = np.random.randint(0, m)  # 0-m之间均匀地产生一个随机整数作为索引index
        centers[i] = x[index]  # 将X中第index行赋值给centroid

    # 作用:KMeans核心实现代码
    """ ------ KMeans核心实现代码 开始 ------ """
    dist_t = np.array((np.sum((x - c) ** 2, axis=1)) ** 0.5 + 1 for c in centers)
    for i in range(600):
        # 备份一下质心数据
        # t_center = copy.deepcopy(centers)
        # t_center = copy.copy(centers) # 浅拷贝
        t_center = centers
        # step1:计算距离
        dist_list = [(np.sum((x - c) ** 2, axis=1)) ** 0.5 for c in centers]

        # step2: 计算极值
        #   注意,这里的 argmin 就是我们需要的 标签值 , 即 y 值
        argmin_dist = np.array(dist_list).argmin(axis=0)  # 得到标签值

        # step3: 更新质心
        centers = np.array([np.mean(x[argmin_dist == i, :], axis=0) for i in range(k)])

        #   step4:重复1、2、3步,直到质心不在发生改变 , 1行
        dist_list = np.array(dist_list)
        if dist_t.all() == dist_list.all():
            print(i)
            break
        else:
            dist_t = dist_list
    """ ^^^^^^ KMeans核心实现代码 结束 ^^^^^^ """

    print(f'质心坐标矩阵:\n {centers}  \n\n \b各样本点标签值:\n {argmin_dist}') # 最终的质心坐标
    mark = ['or', 'ob', 'og', 'ok', 'om', 'oy']
    for i in range(len(x)):
        plt.plot(x[i, 0], x[i, 1], mark[argmin_dist.flatten()[i]])
    ma = ['Dr', 'Db', 'Dg', 'Dk', 'Dm', 'Dy']
    for i in range(k):
        plt.plot(centers[i,0],centers[i,1],ma[i],markersize=10)
    plt.show()

# 主程序入口.
if __name__ == '__main__':
    main()

你可能感兴趣的:(kmeans,python)