K-Means(聚类)---无监督学习

1、介绍

聚类分析是在数据中发现数据对象之间的关系,将数据进行分组,组内的相似性越大,组间的差别越大,则聚类效果越好。

2、原理

对于给定的样本集,按照样本之间的距离大小,将样本集划分为K个簇。让簇内的点尽量紧密的连在一起,而让簇间的距离尽量的大。

如果用数据表达式表示,假设簇划分为(C1,C2,...Ck),则我们的目标是最小化平方误差E:

K-Means(聚类)---无监督学习K-Means(聚类)---无监督学习K-Means(聚类)---无监督学习K-Means(聚类)---无监督学习K-Means(聚类)---无监督学习

    其中
μi
是簇Ci的均值向量,有时也称为质心,表达式为:

μi=1|Ci|xCix

K表示将数据集(N个)分为K类,质心的个数也是K个。求所有样本到每个质心的距离(共有K组N维距离向量),并标记每个样本的类别为和该样本距离最小的质心的类别(选取该质心对应的距离向量中最小的元素即样本到该质心之间的距离最小,每个质心选取的样本个数不确定?)。得到所有样本点的第一轮迭代后的类别(K类)。然后对这K类中的每一类进行求解新的质心(每类中样本求平均得到),再求所有样本到新质心之间的距离,选取每个质心类别样本,再求解新的质心。。。。。如此循环直至所分的K类的样本类别不在改变。

K取2:

K-Means(聚类)---无监督学习

3、K-Means算法流程

1)对于K-Means算法,首先要注意的是k值的选择,一般来说,我们会根据对数据的先验经验选择一个合适的k值,如果没有什么先验知识,则可以通过交叉验证选择一个合适的k值。

2)在确定了k的个数后,我们需要选择k个初始化的质心

{

常见的方法是随机的选取初始质心,但是这样簇的质量常常很差。


(1)多次运行,每次使用一组不同的随机初始质心,然后选取具有最小SSE(误差的平方和)的簇集。这种策略简单,但是效果可能不好,这取决于数据集和寻找的簇的个数。

(2)取一个样本,并使用层次聚类技术对它聚类。从层次聚类中提取K个簇,并用这些簇的质心作为初始质心。该方法通常很有效,但仅对下列情况有效:样本相对较小;K相对于样本大小较小。

(3)取所有点的质心作为第一个点。然后,对于每个后继初始质心,选择离已经选取过的初始质心最远的点。使用这种方法,确保了选择的初始质心不仅是随机的,而且是散开的。但是,这种方法可能选中离群点。


k个初始化的质心的位置选择对最后的聚类结果和运行时间都有很大的影响,因此需要选择合适的k个质心,最好这些质心不能太近。

输入是样本集D={x1,x2,...xm},聚类的簇树k,最大迭代次数N

    输出是簇划分C={C1,C2,...Ck}

K-Means(聚类)---无监督学习

4、计算

距离度量:

 常用的距离度量方法包括:欧几里得距离和余弦相似度。欧几里得距离度量会受指标不同单位刻度的影响,所以一般需要先进行标准化,同时距离越大,个体间差异越大;空间向量余弦夹角的相似度度量不会受指标刻度的影响,余弦值落于区间[-1,1],值越大,差异越小。


质心计算:

考虑欧几里得距离的数据,使用误差平方和(Sum of the Squared Error,SSE)作为聚类的目标函数,两次运行K均值产生的两个不同的簇集,我们更喜欢SSE最小的那个。

K-Means(聚类)---无监督学习

k表示k个聚类中心,ci表示第几个中心,dist表示的是欧几里得距离。 
这里有一个问题就是为什么,我们更新质心是让所有的点的平均值,这里就是SSE所决定的。

K-Means(聚类)---无监督学习

5、算法终止条件


 一般是目标函数达到最优或者达到最大的迭代次数即可终止。对于不同的距离度量,目标函数往往不同。当采用欧式距离时,目标函数一般为最小化对象到其簇质心的距离的平方和;当采用余弦相似度时,目标函数一般为最大化对象到其簇质心的余弦相似度和。

  空聚类的处理

  如果所有的点在指派步骤都未分配到某个簇,就会得到空簇。如果这种情况发生,则需要某种策略来选择一个替补质心,否则的话,平方误差将会偏大。

  (1)选择一个距离当前任何质心最远的点。这将消除当前对总平方误差影响最大的点。

  (2)从具有最大SSE的簇中选择一个替补的质心,这将分裂簇并降低聚类的总SSE。如果有多个空簇,则该过程重复多次。


6、适用范围及缺陷

  K-Menas算法试图找到使平方误差准则函数最小的簇。当潜在的簇形状是凸面的,簇与簇之间区别较明显,且簇大小相近时,其聚类结果较理想。对于处理大数据集合,该算法非常高效,且伸缩性较好。

  但该算法除了要事先确定簇数K和对初始聚类中心敏感外,经常以局部最优结束,同时对“噪声”和孤立点敏感,并且该方法不适于发现非凸面形状的簇或大小差别很大的簇。

  克服缺点的方法:使用尽量多的数据;使用中位数代替均值来克服outlier的问题。

7、代码

{

k-means算法C++实现:k-means.rar

编译出现:assert 未定义的引用,k-means.cpp包含目录添加

#include <assert.h>

GitHub代码:https://github.com/luxiaoxun/KMeans-GMM-HMM

python代码实现

http://blog.****.net/u013266697/article/details/52832215


参考:

K-Means聚类算法:

https://www.cnblogs.com/ahu-lichang/p/7161613.html


K-Means优化:

http://www.cnblogs.com/pinard/p/6164214.html


深入理解K-Means算法:

http://blog.****.net/taoyanqi8932/article/details/53727841


K-Means、K-Means++、KNN比较:

http://blog.****.net/loadstar_kun/article/details/39450615