K-Means算法是无监督的聚类算法,它实现起来比较简单,聚类效果也不错,所以应用很普遍。K-Means算法有大量的变体,本文就从最传统的K-Means算法讲起,在其基础上讲述K-Means的优化变体方法。包括初始化优化K-Means++, 距离计算优化elkan K-Means算法和大数据状况下的优化Mini Batch K-Means算法。算法
K-Means算法的思想很简单,对于给定的样本集,按照样本之间的距离大小,将样本集划分为K个簇。让簇内的点尽可能紧密的连在一块儿,而让簇间的距离尽可能的大。微信
若是用数据表达式表示,假设簇划分为\((C_1,C_2,...C_k)\),则咱们的目标是最小化平方偏差E:
\[ E = \sum\limits_{i=1}^k\sum\limits_{x \in C_i} ||x-\mu_i||_2^2 \]学习
其中\(\mu_i\)是簇\(C_i\)的均值向量,有时也称为质心,表达式为:
\[ \mu_i = \frac{1}{|C_i|}\sum\limits_{x \in C_i}x \]测试
若是咱们想直接求上式的最小值并不容易,这是一个NP难的问题,所以只能采用启发式的迭代方法。大数据
K-Means采用的启发式方式很简单,用下面一组图就能够形象的描述。优化
上图a表达了初始的数据集,假设k=2。在图b中,咱们随机选择了两个k类所对应的类别质心,即图中的红色质心和蓝色质心,而后分别求样本中全部点到这两个质心的距离,并标记每一个样本的类别为和该样本距离最小的质心的类别,如图c所示,通过计算样本和红色质心和蓝色质心的距离,咱们获得了全部样本点的第一轮迭代后的类别。此时咱们对咱们当前标记为红色和蓝色的点分别求其新的质心,如图4所示,新的红色质心和蓝色质心的位置已经发生了变更。图e和图f重复了咱们在图c和图d的过程,即将全部点的类别标记为距离最近的质心的类别并求新的质心。最终咱们获得的两个类别如图f。spa
固然在实际K-Mean算法中,咱们通常会屡次运行图c和图d,才能达到最终的比较优的类别。3d
在上一节咱们对K-Means的原理作了初步的探讨,这里咱们对K-Means的算法作一个总结。rest
首先咱们看看K-Means算法的一些要点。blog
1)对于K-Means算法,首先要注意的是k值的选择,通常来讲,咱们会根据对数据的先验经验选择一个合适的k值,若是没有什么先验知识,则能够经过交叉验证选择一个合适的k值。
2)在肯定了k的个数后,咱们须要选择k个初始化的质心,就像上图b中的随机质心。因为咱们是启发式方法,k个初始化的质心的位置选择对最后的聚类结果和运行时间都有很大的影响,所以须要选择合适的k个质心,最好这些质心不能太近。
好了,如今咱们来总结下传统的K-Means算法流程。
输入是样本集\(D=\{x_1,x_2,...x_m\}\),聚类的簇树k,最大迭代次数N
输出是簇划分\(C=\{C_1,C_2,...C_k\}\)
1) 从数据集D中随机选择k个样本做为初始的k个质心向量: \(\{\mu_1,\mu_2,...,\mu_k\}\)
2)对于n=1,2,...,N
a) 将簇划分C初始化为\(C_t = \varnothing \;\; t =1,2...k\)
b) 对于i=1,2...m,计算样本\(x_i\)和各个质心向量\(\mu_j(j=1,2,...k)\)的距离:\(d_{ij} = ||x_i - \mu_j||_2^2\),将\(x_i\)标记最小的为\(d_{ij}\)所对应的类别\(\lambda_i\)。此时更新\(C_{\lambda_i} = C_{\lambda_i} \cup \{x_i\}\)
c) 对于j=1,2,...,k,对\(C_j\)中全部的样本点从新计算新的质心\(\mu_j = \frac{1}{|C_j|}\sum\limits_{x \in C_j}x\)
e) 若是全部的k个质心向量都没有发生变化,则转到步骤3)
3) 输出簇划分\(C=\{C_1,C_2,...C_k\}\)
在上节咱们提到,k个初始化的质心的位置选择对最后的聚类结果和运行时间都有很大的影响,所以须要选择合适的k个质心。若是仅仅是彻底随机的选择,有可能致使算法收敛很慢。K-Means++算法就是对K-Means随机初始化质心的方法的优化。
K-Means++的对于初始化质心的优化策略也很简单,以下:
a) 从输入的数据点集合中随机选择一个点做为第一个聚类中心\(\mu_1\)
b) 对于数据集中的每个点\(x_i\),计算它与已选择的聚类中心中最近聚类中心的距离\(D(x_i) = arg\;min||x_i- \mu_r||_2^2\;\;r=1,2,...k_{selected}\)
c) 选择一个新的数据点做为新的聚类中心,选择的原则是:\(D(x)\)较大的点,被选取做为聚类中心的几率较大
d) 重复b和c直到选择出k个聚类质心
e) 利用这k个质心来做为初始化质心去运行标准的K-Means算法
在传统的K-Means算法中,咱们在每轮迭代时,要计算全部的样本点到全部的质心的距离,这样会比较的耗时。那么,对于距离的计算有没有可以简化的地方呢?elkan K-Means算法就是从这块入手加以改进。它的目标是减小没必要要的距离的计算。那么哪些距离不须要计算呢?
elkan K-Means利用了两边之和大于等于第三边,以及两边之差小于第三边的三角形性质,来减小距离的计算。
第一种规律是对于一个样本点\(x\)和两个质心\(\mu_{j_1}, \mu_{j_2}\)。若是咱们预先计算出了这两个质心之间的距离\(D(j_1,j_2)\),则若是计算发现\(2D(x,j_1) \leq D(j_1,j_2)\),咱们当即就能够知道\(D(x,j_1) \leq D(x, j_2)\)。此时咱们不须要再计算\(D(x, j_2)\),也就是说省了一步距离计算。
第二种规律是对于一个样本点\(x\)和两个质心\(\mu_{j_1}, \mu_{j_2}\)。咱们能够获得\(D(x,j_2) \geq max\{0, D(x,j_1) - D(j_1,j_2)\}\)。这个从三角形的性质也很容易获得。
利用上边的两个规律,elkan K-Means比起传统的K-Means迭代速度有很大的提升。可是若是咱们的样本的特征是稀疏的,有缺失值的话,这个方法就不使用了,此时某些距离没法计算,则不能使用该算法。
在统的K-Means算法中,要计算全部的样本点到全部的质心的距离。若是样本量很是大,好比达到10万以上,特征有100以上,此时用传统的K-Means算法很是的耗时,就算加上elkan K-Means优化也依旧。在大数据时代,这样的场景愈来愈多。此时Mini Batch K-Means应运而生。
顾名思义,Mini Batch,也就是用样本集中的一部分的样原本作传统的K-Means,这样能够避免样本量太大时的计算难题,算法收敛速度大大加快。固然此时的代价就是咱们的聚类的精确度也会有一些下降。通常来讲这个下降的幅度在能够接受的范围以内。
在Mini Batch K-Means中,咱们会选择一个合适的批样本大小batch size,咱们仅仅用batch size个样原本作K-Means聚类。那么这batch size个样本怎么来的?通常是经过无放回的随机采样获得的。
为了增长算法的准确性,咱们通常会多跑几回Mini Batch K-Means算法,用获得不一样的随机采样集来获得聚类簇,选择其中最优的聚类簇。
初学者很容易把K-Means和KNN搞混,二者其实差异仍是很大的。
K-Means是无监督学习的聚类算法,没有样本输出;而KNN是监督学习的分类算法,有对应的类别输出。KNN基本不须要训练,对测试集里面的点,只须要找到在训练集中最近的k个点,用这最近的k个点的类别来决定测试点的类别。而K-Means则有明显的训练过程,找到k个类别的最佳质心,从而决定样本的簇类别。
固然,二者也有一些类似点,两个算法都包含一个过程,即找出和某一个点最近的点。二者都利用了最近邻(nearest neighbors)的思想。
K-Means是个简单实用的聚类算法,这里对K-Means的优缺点作一个总结。
K-Means的主要优势有:
1)原理比较简单,实现也是很容易,收敛速度快。
2)聚类效果较优。
3)算法的可解释度比较强。
4)主要须要调参的参数仅仅是簇数k。
K-Means的主要缺点有:
1)K值的选取很差把握
2)对于不是凸的数据集比较难收敛
3)若是各隐含类别的数据不平衡,好比各隐含类别的数据量严重失衡,或者各隐含类别的方差不一样,则聚类效果不佳。
4) 采用迭代方法,获得的结果只是局部最优。
5) 对噪音和异常点比较的敏感。
(欢迎转载,转载请注明出处。欢迎沟通交流: 微信:nickchen121)