本文共 2993 字,大约阅读时间需要 9 分钟。
该文从简单的数据角度讲解基于k-means和基于numpy实现k-means代码。
k-means是什么,它的做什么的,它与先前所说的聚类有什么关系。
上一篇文章已经详解了聚类,那么基础应该已经没有什么问题了,k-means其实就是用中文来说的话就是k均值聚类,它属于聚类中的"基于原型的聚类"
基于原型的聚类:假设聚类结构能通过一组原型刻画,通常情况下,算法先对原型进行初始化,继而对原型进行不断的更新迭代。而不同的更新方式和不同的求解将产生不同的算法。
其中:官方定义:给定样本集D={x1,x2,…,xn};所谓k均值算法,是求得针对聚类所得簇划分C={C1,C2…,Ck}最小化的平方误差,如下
那么μi就可以看为是x集合也就是Ci的均值向量。直观的来看,E在一定程度上刻画了簇内的所有样本围绕簇均值向量的紧密程度。E越小则,越紧密,意味着簇内相似度越高。我们只需要求最小E即可。
接下来我们解析官方这些概念和公式:
从概念入手,我们知道最后是要把数据集划分为K个簇,那么"均值"这个俩个字,也很容易理解,从公式入手,所谓的均值其实指的就是均值向量了。那么如果要实现该算法的话,我们只需要几步:从理论上来说,该方法,适用于所有的数据集,无论是有序属性还是无序属性,需要变更的仅仅是距离的算法问题罢了。
代码如下(示例):
#基于numpy的K-means#coding:UTF-8#倒库import numpy as npimport random as rdimport matplotlib.pyplot as pltfrom math import *
class k_m(): #计算距离 返回欧氏距离 这里仅仅考虑到了有序属性 def __init__(self): self.color=['.b','.g','.r','.c','.m','.y','.k','.w'] self.cencolor=['*b','*g','*r','*c','*m','*y','*k','*w'] #0表示当前颜色的索引 self.now=0 def dist(x,y): return sqrt(pow(x[0]-y[0],2)+pow(x[1]-y[1],2)) #crowd_count:簇的个数,也是定义K_means点的个数,传入x坐标和y坐标, def k_means(self,x,y,k): #获取含有k个随机属性的属性序列 k_list=[(x[i],y[i]) for i in rd.sample(range(len(x)),k)] #对属性排序,以便处理 k_list.sort() while 1: #crowds为簇列表,每一次遍历都要更新簇列表 crowds=[[] for i in range(k)] for i in range(len(x)): t_now=(x[i],y[i]) #计算到所有点的距离 存列表 接下来我们需要该点到所有质心的距离最近并且将其加入簇列表中 all_dist=[k_m.dist(k_list[j],t_now) for j in range(k)] min_dist=all_dist.index(min(all_dist)) #加入索引之中 crowds[min_dist].append(i) #进入质心的迭代 centroid_news_list=[] #从之前得到的簇中计算均值,重新确定质心并进行运算 for i in range(k): x_t=sum(x[j] for j in crowds[i])/len(crowds[i]) y_t=sum(y[j] for j in crowds[i])/len(crowds[i]) centroid_news_list.append((x_t,y_t)) centroid_news_list.sort() #绘图 plt.figure() plt.title('k={0:d} k-means'.format(k)) for i in range(k): #绘点 plt.plot([x[j] for j in crowds[i]],[y[j] for j in crowds[i]],self.color[self.now])# #绘质心 plt.plot(k_list[i][0],k_list[i][1],self.cencolor[self.now])# self.now+=1 plt.show() plt.close('all') if centroid_news_list==k_list: return crowds else: self.now=0 k_list=centroid_news_list
k-means本身作为原型聚类中最著名的划分聚类算法,以及最为广泛使用的划分聚类算法,其优秀程度自然是不言而喻。有兴趣的小伙伴可以尝试用无序属性的数据集,以及无序距离的计算处理复杂任务,比如物品的分类等等,实现也没有很难,但是十分有用。
转载地址:http://ukcki.baihongyu.com/