《机器学习实战》——第十章 K-MEANS算法 学习总结

1、K-means聚类

       聚类是一种无监督的学习,它将相似的对象归到同一簇中。聚类的方法几乎可以应用所有对象,簇内的对象越相似,聚类的效果就越好。K-means算法中的k表示的是聚类为k个簇,means代表取每一个聚类中数据值的均值作为该簇的中心,或者称为质心,即用每一个的类的质心对该簇进行描述。

        聚类和分类最大的不同在于,分类的目标是事先已知的,而聚类则不一样,聚类事先不知道目标变量是什么,类别没有像分类那样被预先定义出来,所以,聚类有时也叫无监督学习。聚类分析试图将相似的对象归入同一簇,将不相似的对象归为不同簇,那么,显然需要一种合适的相似度计算方法,我们已知的有很多相似度的计算方法,比如欧氏距离,余弦距离,汉明距离等。K-means算法虽然比较容易实现,但是其可能收敛到局部最优解,且在大规模数据集上收敛速度相对较慢。

2、K-means聚类算法流程

       首先,随机确定k个初始点的质心;然后将数据集中的每一个点分配到一个簇中,即为每一个点找到距其最近的质心,并将其分配给该质心所对应的簇;该步完成后,每一个簇的质心更新为该簇所有点的平均值。伪代码如下:

创建k个点作为起始质心,可以随机选择(位于数据边界内)
  当任意一个点的簇分配结果发生改变时
    对数据集中每一个点
        对每个质心
          计算质心与数据点之间的距离
        将数据点分配到距其最近的簇
    对每一个簇,计算簇中所有点的均值并将均值作为质心

       在算法中,相似度的计算方法默认的是欧氏距离计算,当然也可以使用其他相似度计算函数,比如余弦距离;算法中,k个类的初始化方式为随机初始化,并且初始化的质心必须在整个数据集的边界之内,这可以通过找到数据集每一维的最大值和最小值;然后最小值+取值范围*0到1的随机数,来确保随机点在数据边界之内。

       在实际的K-means算法中,采用计算质心-分配-重新计算质心的方式反复迭代,算法停止的条件是,当然数据集所有的点分配的距其最近的簇不在发生变化时,就停止分配,更新所有簇的质心后,返回k个类的质心(一般是向量的形式)组成的质心列表,以及存储各个数据点的分类结果和误差距离的平方的二维矩阵。之所以存储每个数据点距离其质心误差距离平方,是便于后续的算法预处理。因为K-means算法采取的是随机初始化k个簇的质心的方式,因此聚类效果又可能陷入局部最优解的情况,局部最优解虽然效果不错,但不如全局最优解的聚类效果更好。所以,后续会在算法结束后,采取相应的后处理,使算法跳出局部最优解,达到全局最优解,获得最好的聚类效果。

若算法已经陷入了局部最小值,如何才能够进一步提升K-means算法的效果呢?

       一种用于度量聚类效果的指标是SSE,即误差平方和, 为所有簇中的全部数据点到簇中心的误差距离的平方累加和。SSE的值如果越小,表示数据点越接近于它们的簇中心,即质心,聚类效果也越好。因为,对误差取平方后,就会更加重视那些远离中心的数据点。

由此,我们得出一种改善聚类效果的做法是降低SSE,那么如何在保持簇数目不变的情况下提高簇的质量呢?

       一种方法是:我们可以将具有最大SSE值得簇划分为两个簇(因为,SSE最大的簇一般情况下,意味着簇内的数据点距离簇中心较远),具体地,可以将最大簇包含的点过滤出来并在这些点上运行K-means算法,其中k设为2。同时,当把最大的簇分为两个簇之后,为了保证簇的数目是不变的,我们可以再合并两个簇。

扫描二维码关注公众号,回复: 169255 查看本文章

       一方面我们可以合并两个最近的质心所对应的簇,即计算所有质心之间的距离,合并质心距离最近的两个质心所对应的簇;另一方面,我们可以合并两个使得SSE增幅最小的簇,显然,合并两个簇之后SSE的值会有所上升,那么为了最好的聚类效果,应该尽可能使总的SSE值小,所以就选择合并两个簇后SSE涨幅最小的簇。具体地,就是计算合并任意两个簇之后的总得SSE,选取合并后最小的SSE对应的两个簇进行合并。这样,就可以满足簇的数目不变。

       在不改变k值的情况下,上述方法能够起到一定的作用,会使得聚类效果得到一定的改善。接下来要介绍的是一种克服算法收敛于局部最小值问题的K-means算法,即二分 k-均值算法。

3、二分 k-均值算法

       二分K-means算法首先将所有点作为一个簇,然后将簇一分为二。之后选择其中一个簇继续进行划分,选择哪一个簇取决于对其进行划分是否能够最大程度的降低SSE的值。上述划分过程不断重复,直至划分的簇的数目达到用户指定的值为止。伪代码如下:

将所有点看成一个簇
当簇数目小于k时
对于每一个簇
    计算总误差
    在给定的簇上面进行k-均值聚类(k=2)
    计算将该簇一分为二之后的总误差
选择使得总误差最小的簇进行划分

当然,也可以选择SSE最大的簇进行划分,直到簇数目达到用户指定的数目为止。在上述算法中,直到簇的数目达到k值,算法才会停止。在算法中通过将所有的簇进行划分,然后分别计算划分后所有簇的误差,选择使得总误差最小的那个簇进行划分。划分完成后,要更新簇的质心列表、数据点的分类结果及误差平方。

       具体地,假设划分的簇为m(m<k)个簇中的第i个簇,那么这个簇分成的两个簇后,其中一个取代该被划分的簇,成为第i个簇,并计算该簇的质心;此外,将划分得到的另外一个簇,作为一个新的簇,成为第m+1个簇,并计算该簇的质心。此外,算法中还存储了各个数据点的划分结果和误差平方,此时也应更新相应的存储信息。这样,重复该过程,直至簇个数达到k。通过上述算法,之前陷入局部最小值的的这些数据,经过二分K-means算法多次划分后,逐渐收敛到全局最小值,从而达到了令人满意的聚类效果。

猜你喜欢

转载自blog.csdn.net/wanty_chen/article/details/80200457