# 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()
SDUWH2019-2020寒假python实训--Chp5.1
最新推荐文章于 2024-11-04 21:51:40 发布