现在的位置: 首页 > 综合 > 正文

一个K-means聚类算法的实现代码和分析

2013年12月10日 ⁄ 综合 ⁄ 共 8177字 ⁄ 字号 评论关闭

最近做聚类实验,实现了几个简单的聚类算法,其中基于最大最小的顺序聚类算法MBSAS就不贴了,受异常点影响很大,其实这个也很好理解,因为选最大距离进行分类(MBSAS先确定类,再根据类里的向量将剩下的样本分到某个类中)的时候,很容易就将异常点作为一个类分出去,那样在分2类的过程中,很明显会出现某个类占95%+,另一个类只有5%以下样本的情况,后者显然就是个异常点,这对我们的聚类是非常不利的,当然用来找异常点还是很有效的。

在实现K-mean算法的时候,也需要找初始点,如果采用最大最小的话还是会遇到这个问题,那么怎么解决这个问题呢?

我的想法是多次分类:如果某个初始点找到之后,第一次分类的结果有一个类的元素的数目特别小,那么就假定这个类的元素是噪声集的一部分,注意噪声集不等于噪声点,但是噪声点一定在噪声集中,而且最重要的是噪声集中的点都不适合作为初始点。然后第二次找初始点,再分类,再判断是否需要重新找,直到找到的所有按照初始点的第一次划分的集合的数目都不是特别小。

执行流程如下:

  1. 按照最大最小进行分类得到需要的n个初始点(噪声集的点不能被选作初始点)
  2. 按照这n个初始点对所有的元素进行分类,得到n个类,每个类有一些元素
  3. 如果这n个类中的某个类,假设为nk的元素的数目小于t,那么将nk中的元素都加到噪集当中
  4. 重复1 直到所有的类的元素的数目都大于等于t

那么这里又有一个问题:t是多少?

从直观的角度来想,t应该和样本数目N有关,样本数目越大,t越大,一个1000的样本的某个类有100个元素可能不是噪声,但是一个100000的样本的某个有100个元素的类则可能是噪声。同样,t还要和分类的数目C有关,C越大,t应该越小,1000个元素分为2个类,则一个含有50个元素的类就可能是噪声,但是如果把1000个元素分为10个类,则含有50个元素的类则不太可呢个是噪声,所以综合这两个因素,我设计了一个阈值函数:

 

t = N / C ^ 2

 

也就是说当N = 1000,C = 4 的时候, t = 1000/16 = 62,如果某个类小于62个元素,就认为是噪声集,关于这个函数,可以有很多种,比如t = N / (C * 4),这里面有什么倾向,读者可以自己思考,但是最终结果还是和数据相关。

 

补:

昨天老师公布了实验结果,我们组的成绩不错,尤其是分两类的情况,基本达到的最优值,但是八类的情况就不是那么好了,我想了想,是阈值函数的问题,因为上交的结果中使用的阈值函数是t = N / C ^ 3,C=8的时候,阈值失去了意义,所以一定程度上会受到噪声点的影响。

 

今天又想了想,觉得应该使用一个如下的函数:

t = N/(C * asym)   asym = 2,4,8....

这个函数中asym系数是不对乘系数,反应的是最小(数目)的类和最大的类的不对称比例,asym最小也应该为2,如果为1,那么就是均分,不现实,当为2的时候,1000个样本分两类,最小的类是250,如果觉得这个比例还是不够悬殊,可以另asym = 4,也就是最小的类为125,这个看上去就比较合适了,当然如果你比较极端,可以选择更大的不对称系数,但是注意,这里影响的只是对噪声点的判定,和最后的聚类结果的大小没有关系,也就是说如果asym = 8, N =1000,C = 2,那么以一个初始点M为中心的第一次划分的类的数目只要大于 1000/2/8 = 62,就不认为这个点是噪声,显然这看起来有些不合理,一般来说asym=4应该是一个比较好的情况。

 

完整的代码如下(阈值函数没有引入不对乘系数,读者请自己修改):

 

 

【上篇】
【下篇】

抱歉!评论已关闭.