K均值聚类
算法介绍:
K-Means算法思想简单,效果却很好,是最有名的聚类算法。
它的基本思想是:通过迭代寻找k个聚类的一种划分方案,使得用这k个聚类的均值来代表相应各类样本时所得的总体误差最小。
k-means算法的基础是最小误差平方和准则。其代价函数是:
式中,μc(i)表示第i个聚类的均值。我们希望代价函数最小,直观的来说,各类内的样本越相似,其与该类均值间的误差平方越小,对所有类
所得到的误差平方求和,即可验证分为k类时,各聚类是否是最优的。
聚类算法的步骤如下:
k-means算法实际上就是通过计算不同样本间的距离来判断他们的相近关系的,相近的就会放到同一个类别中去。
1.首先我们需要选择一个k值,也就是我们希望把数据分成多少类,这里k值的选择对结果的影响很大,Ng的课说的选择方法有两种一种是elbowmethod,简单的说就是根据聚类的结果和k的函数关系判断k为多少的时候效果最好。另一种则是根据具体的需求确定,比如说进行衬衫尺寸的聚类你可能就会考虑分成三类(L,M,S)等(初始化K个样本作为初始聚类中心)
2.然后我们需要选择最初的聚类点(或者叫质心),这里的选择一般是随机选择的,代码中的是在数据范围内随机选择,另一种是随机选择数据中的点。这些点的选择会很大程度上影响到最终的结果,也就是说运气不好的话就到局部最小值去了。这里有两种处理方法,一种是多次取均值,另一种则是后面的改进算法(bisectingK-means)(计算每个样本点到K个中心的距离,选择最近的中心作为其分类,直到所有样本点分类完毕)
3.终于我们开始进入正题了,接下来我们会把数据集中所有的点都计算下与这些质心的距离,把它们分到离它们质心最近的那一类中去。完成后我们则需要将每个簇算出平均值,用这个点作为新的质心。反复重复这两步,直到收敛我们就得到了最终的结果。(分别计算K个类中所有样本的质心,作为新的中心点,完成一轮迭代。)
通常的迭代结束条件为新的质心与之前的质心偏移值小于一个给定阈值。
1、随机选取 k个聚类质心点
2、重复下面过程直到收敛
对于每一个样例 i,计算其应该属于的类:
对于每一个类 j,重新计算该类的质心:
下面给一个简单的例子来加深理解:
如下图有4个样本点,坐标分别为A(-1,-1),B(1,-1),C(-1,1),D(1,1)。现在要将他们聚成2类,指定A、B作为初始聚类中心(聚类中心A0,B0),指定阈值0.1。K-Means迭代过程如下:
step 1.1:计算各样本距离聚类中心的距离:
样本A:d(A,A0) =0; d(A,B0) = 2;因此样本A属于A0所在类;
样本B:d(B,A0) =2; d(B,B0) = 0;因此样本B属于B0所在类;
样本C:d(C,A0) =2; d(C,B0) = 2.8;;因此样本C属于A0所在类;
样本C:d(D,A0) =2.8; d(D,B0) = 2;;因此样本C属于B0所在类;
step1.2:全部样本分类完毕,现在计算A0类(包含样本AC)和B0类(包含样本BD)的新的聚类中心:
A1 = (-1, 0); B1 = (1,0);
step1.3:计算聚类中心的偏移值是否满足终止条件:
|A1-A0| = |(-1,0)-(-1,-1)| = |(0,1)| = 1 >0.1,因此继续迭代。
此时的状态如下图所示:
step 2.1:计算各样本距离聚类中心的距离:
样本A:d(A,A1) =1; d(A,B1) = 2.2;因此样本A属于A1所在类;
样本B:d(B,A1) =2.2; d(B,B1) = 1;因此样本B属于B1所在类;
样本C:d(C,A1) =1; d(C,B1) = 2.2;;因此样本C属于A1所在类;
样本D:d(D,A1) =2.2; d(D,B1) = 1;;因此样本C属于B1所在类;
step2.2:全部样本分类完毕,现在计算A1类(包含样本AC)和B1类(包含样本BD)的新的聚类中心:
A2 = (-1, 0); B2 = (1,0);
step2.3:计算聚类中心的偏移值是否满足终止条件:
|A2-A1| = |B2-B1| = 0<0.1,因此迭代终止。
再举一个简单的例子来说明问题:
设有一组数据集x1=(2,1),x2=(1,3),x3=(6,7),x4=(4,7)
(1)选取聚类中心,该中心可以任意选取,也可以通过直方图进行选取,还可以通过取前2个值进行选取。我们选择两个聚类中心。
(2)计算每一个样本值到聚类中心的距离;并划分新的聚类中心;
算法分析
k-means算法比较简单,但也有几个比较大的缺点:
(1)k值的选择是用户指定的,不同的k得到的结果会有挺大的不同,如下图所示,左边是k=3的结果,这个就太稀疏了,蓝色的那个簇其实是可以再划分成两个簇的。而右图是k=5的结果,可以看到红色菱形和蓝色菱
形这两个簇应该是可以合并成一个簇的:
(2)对k个初始质心的选择比较敏感,容易陷入局部最小值。例如,我们上面的算法运行的时候,有可能会得到不同的结果,如下面这两种情
况。K-means也是收敛了,只是收敛到了局部最小值:
(3)存在局限性,如下面这种非球状的数据分布就搞不定了:
(4)数据库比较大的时候,收敛会比较慢。
k均值的算法代码介绍见我的上一篇博文:创建正态分布的点并用k均值算法聚类