k-means算法
简介
据说是机器学习中最简单的一种方法,属于非监督学习这一类。通俗一点讲,给机器一堆数据,告诉机器要分成多少种类别,然后机器就根据算法进行各种操作。
实现原理
需要我们确定变量k,即最终 的数据会有几种类别。
总共有k个中心坐标,一开始可以随机赋值,通过计算目标点坐标与所有中心坐标的距离,将其归类在距离较近的类别中。
之后根据类别中的目标点计算平均值重新得到中心坐标,再重复上面的工作。
距离公式
常用的距离公式如欧式距离,马氏距离,曼哈顿距离。
借助科学计算库可以帮我们节省一些时间。
from scipy.spatial.distance import pdist
pdist(np.array([dot[j], center[k]]), 'euclidean')#欧氏距离
小小示例
最后总是在两种分类中来回跳转,是程序写错了么。
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial.distance import pdist
dimension = 2
# 生成多个随机点,范围[0,10)
dot_num = 100
dot = np.random.rand(dot_num,dimension)*10
# 生成多个随机中心点,范围[0,10)
center_num = 4
center = np.random.rand(center_num,dimension)*10
# 循环迭代
times = 50
for i in range(times):
plt.clf()
# 数据映射
belong = np.zeros([dot_num])
# 计算随机点与中心点的距离,将其归属于距离近的中心点
dist = np.zeros([dot_num,center_num])
for j in range(dot_num):
for k in range(center_num):
dist[j][k] = pdist(np.array([dot[j], center[k]]), 'euclidean')
belong[j] = np.argmax(dist[j])
# 绘图
for j in range(center_num):
temp_dot = []
for k in range(dot_num):
if(belong[k] == j):
temp_dot.append(dot[k])
# 根据随机点求取均值,得出新的中心点
if(len(temp_dot) != 0):
temp_dot = np.array(temp_dot)
plt.scatter(temp_dot[:,0],temp_dot[:,1])
for k in range(dimension):
center[j][k] = np.sum(temp_dot[:,k])/len(temp_dot)
else:
center[j] = np.zeros([dimension])
# print(center)
plt.pause(1)
# 满足迭代次数或中心点不再改变,结束命令
说明
上述代码为动态实时更新画板内容,其中的关键代码如下
import matplotlib.pyplot as plt
for i in range(5):
# 清除画布
plt.clf()
# 绘制散点
plt.scatter(temp_dot[:,0],temp_dot[:,1])
# 暂停间隔
plt.pause(1)