SDUWH2019-2020寒假python实训--Chp5.1

# kmeans 算法
import numpy as np

def my_kmeans(input_data, k=3):
    # pass  # 空语句,仅仅作为占位, 删除或不删都行
    # input_data = [[1, 5], [2, 4], [4, 1], [5, 0], [7, 6], [6, 7]]
    # print(input_data[0][0])
    input_data_np = np.array(input_data)
    # print(input_data_np[0, 0])
    # print(input_data_np - 1)  # np.array 访问使用slice方式
    # 1、选择类中心
    # print(np.random.randint(1,5,(2,4)))
    # print(input_data_np.shape)  # (6, 2)
    # index_cls = np.random.randint(0,input_data_np.shape[0],3)
    # print(np.linspace(0,6,3))
    # print(index_cls)
    index_cls = []
    while index_cls.__len__() < k:
        n = np.random.randint(0, input_data_np.shape[0], 1)
        if not n in index_cls:
            index_cls.append(n[0])
    # print(index_cls)

    point_cls = input_data_np[np.array(index_cls)]
    # print(point_cls)
    # 初始化样本点类别
    tag_samples = [-1 for i in range(input_data_np.shape[0])]
    # print(tag_samples)
    while True:
        # 2. 更新样本点类别
        # 通过计算样本点到聚类中的使用欧式距离的平方(x1-x2)^2 + (y1-y2)^2
        # print((input_data_np-np.array([1,1]))**2)
        # print(np.sum((input_data_np-np.array([1,1]))**2, axis=1))  # axis=0 行的方向  1: 列的方向
        dis_cls = np.array([list(np.sum((input_data_np - i) ** 2, axis=1)) for i in point_cls])
        # for i in point_cls:
        #     dis_cls.append(np.sum((input_data_np - i) ** 2, axis=1))
        # print(dis_cls)
        # 3. 计算样本点新类别
        # 选取每一列上的最小值的索引,作为这个样本点的类别
        new_tag_samples = np.argmin(dis_cls, axis=0)
        # print(new_tag_samples)
        # 4. 计算新类中心
        # 计算新的类别中心
        # print(input_data_np[new_tag_samples == 0])
        # print(np.average(input_data_np[new_tag_samples == 0], axis=0))
        new_point_cls = np.array([list(np.average(input_data_np[new_tag_samples == i], axis=0)) for i in range(k)])
        # print(new_point_cls)
        # 5. 计算新类中心的样本类别,做判断,如果类别发生了变化,计算更新类别,如果不变化了,那么就停止
        # 可以比较两个类的中心是否满足一定条件,(一般算和小与一定的值,不建议使用相等判断)
        sum_cls_point_dis = np.sum((new_point_cls - point_cls) ** 2)
        # print(sum_cls_point_dis)
        # 可以比较样本的类别变化,如果样本类别没有变化了,那就停止
        if sum_cls_point_dis < 0.05:
            break
        else:
            point_cls = new_point_cls
    # print(new_point_cls)
    # print(new_tag_samples)
    return new_point_cls,new_tag_samples

# 测试封装好的函数
input_data = [[1, 5], [2, 4], [4, 1], [5, 0], [7, 6], [6, 7]]
#使用散点图显示出来
x = np.array(input_data)[:,0]
y = np.array(input_data)[:,1]
import matplotlib.pyplot as plt
# plt.scatter(x,y)
# plt.scatter(x-1,y-1)
# plt.show()

cls_point, tag_samples = my_kmeans(input_data,3)
print(input_data)
print(cls_point)
print(tag_samples)
for i in range(3):
    plt.scatter(x[tag_samples==i],y[tag_samples==i])

plt.show()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KingoKing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值