本稿为初稿,后续可能还会修改;如果转载,请务必保留源地址,非常感谢!

博客园:http://www.cnblogs.com/data-miner/

其他:建设中…

当我们在谈论kmeans(2)

引言

  上一篇文章,对从1969年以来,与kmeans相关文章的数据进行了简单描述,并对其中某些数据趋势尝试分析。这属于对数据的整体情况的一个简要分析。

  本篇文章,则希望能通过简单介绍kmeans一路以来一些重要或者有意义的文章,进而能大概梳理出该算法的发展进程。

算法含有的问题

算法历程

1967年

  公认的k-means术语的最初使用是在"J. MacQueen, Some Methods for classification and Analysis of Multivariate Observations, 1967"。根据wiki的说法,k-means的算法还能追溯到更早的时候,然而这就不在本文的讨论范围内了。其中给出了最初的k-means定义,即

  1. An initial clustering is created by choosing k random centroids from the dataset.
  2. For each data point, calculate the distance from all centroids, and assign its

    membership to the nearest centroid.
  3. Recalculate the new cluster centroids by the average of all data points that are

    assigned to the clusters.
  4. Repeat step 2 and 3 until convergence.

1979年

  在"Hartigan, J. A.; Wong, M. A., "Algorithm AS 136: A K-Means Clustering Algorithm, 1979"中,作者提出了一种新的聚类算法,同时也提出了一种初始化聚类中心的办法:

  1. 该聚类算法不断将每个点分配到更优的类别,使损失函数持续减小;若损失函数不再减小,则停止迭代。本质是梯度下降,因此只能达到局部最优。
  2. 在初始化聚类中心时,先计算整体样本中心,然后根据样本点到中心的距离,由近至远均匀采样作为初试聚类中心。这样可以避免初次聚类后,某类为空的问题。

1984年

  在“Selim, Shokri Z., and Mohamed A. Ismail. "K-means-type algorithms: a generalized convergence theorem and characterization of local optimality." 1984”中,作者主要对k-means的一些性质进行了理论上的推导

  1. 根据最初k-means定义给出损失函数表达式P

  2. 给出等价的损失函数RP,并证明其是非凸的





  3. 给出k-means类型的聚类算法的思想(本质就是现在所说的EM算法的一种应用)



  4. 当距离定义为minkowski距离时,k-means可能无法收敛到局部最小值,即

  5. 当距离定义为二次距离时,k-means可以收敛到局部最小值,即

1995年

  在“Cheng, Yizong. "Mean shift, mode seeking, and clustering." 1995”中,作者对前人提出的Mean shift算法进行了扩展并研究了其性质,同时证明了k-means算法是Mean shift算法的特殊形式。这篇文章也奠定了Mean shift算法能被广泛使用的基础

  1. 给出原始Mean shift算法的定义,其实就是迭代去寻找某点最近的,且稳定的点,稳定可以理解该点邻域质心与中心一致;并把收敛到这个稳定点的所有点作为一类

  2. 在此基础上进行了扩展,加入了核函数和权重。由于Mean shift本质是迭代逼近密度局部最大的点,有了核函数,就可以自由定义这种密度的表达,因此适用性大大增强

  3. “maximum entropy”算法作者证明了k-means为其算法的特殊形式,本文作者又证明了“maximum entropy”算法为扩展的Mean shift的特殊形式,于是k-means即为Mean shift的特殊形式
  4. 作者尝试利用Mean shift进行聚类,而现在Mean shift也是一种常见的聚类算法之一
  5. 由于Mean shift可以逼近概率密度局部最大点,作者也尝试利用Mean shift来求解最优化问题
  6. 此外,作者还定义了很多相关概念,并进行了性质的说明与证明,此处不再赘述

  在“Chinrungrueng, C., and C. H. Sequin. "Optimal adaptive k-means algorithm with dynamic adjustment of learning rate. " 1995”中,作者对之前on-line的k-means算法进行了修改

  1. 先定义k-means的损失函数,即最小均方误差

  2. 接下来介绍以前的adaptive k-means算法,这种算法的思想跟梯度下降法差不多。跟传统梯度下降法一样,如果μ过小,则收敛时间慢;如果μ过大,则可能在最优点附近震荡。

  3. 接下来,作者将损失函数进行修改,即改成了加权的最小均方误差



  4. 然后作者引用文献的证明,表示“当类别数K很大,且样本的真实概率密度函数P平滑的假设下,使用k-means算法进行分割,每一个区域的方差是相同的”。于是,在这个前提下,即“每个类别的方差相同”的前提下,可以自适应计算learning rate μ。μ会在初期近似于1,而在接近最优时会趋于0,加快了搜索速度,同时避免步长太大在最优点附近震荡的情况。限于篇幅,μ的更新公式不再本文贴出,有兴趣的可以去文章中找。

1997年

  在“Chaudhuri, D., and B. B. Chaudhuri. "A novel multiseed nonhierarchical data clustering technique. " 1997”中,作者对传统k-means算法进行了改进。传统的k-means针对每一个类别选择一个聚类中心,但是对于非凸或长条状的类别,一个聚类中心并不是很好的选择(博主注:针对非凸与长条等数据,个人认为也可以在特征转换层面处理,但是这样就要求首先对数据有深入的分析,而且适用性比较差)。本文提出,一个类别可以包含多个聚类中心,使k-means在非凸情况下也能有较好的表现。

  1. 为了判断聚类的形状,作者提出可以通过找出边界点,然后根据边界点“最大最小距离比”来判断。当比值接近1时,说明形状是接近超球体的;当比值远大于1时,说明是长条或非凸的。为了求边界点,先求取所有候选边界点,的方式如下。本质就是如果一个点很少被别的点包围,则处于边界。



  2. 正式求取边界点:给定边界点数目m,边界点的求解公式如下,本质就是从所有候选边界点中找出m个最突出的作为边界点

  3. 接下来初始化聚类中心。本质还是认为密度较大的,即聚类中心。通过找到密度最大点,然后将它周围的球体区域内的点都认为暂时属于这个类,并从整体数据中删除。重复这个过程,就能得到所有的聚类中心。

  4. 初次聚类:根据最近邻,将每个点分配到相应的聚类中心。
  5. 为了让一个类别能出现多个聚类中心,作者增加了一步,即类别合并(本质是从上往下的层次聚类):即将所有聚类中心看做图的节点,边的权重即两个聚类中心的距离,然后对这幅图绘出最小生成树;在生成了树后,再重新计算每条边的权重,这时候权重被重新定义为一种”疏远度“;迭代剪断”疏远度“最大的边,直到剩下的类别数为K。整个流程被作者描述的相当复杂,如下





  6. 更新聚类中心:此步骤包含两个子步骤

    6.1 为数据重新分配类别。每个数据点的类别定义为,离它最近的聚类中心的类别。

    6.2 分别更新类内聚类中心。对每个类别,若有多个聚类中心,则按照标准kmeans的更新聚类中心方法重新计算聚类中心。
  7. 重复5~6步,直到达到一定迭代次数或者聚类中心稳定。

除了提出算法外,作者文中还提到几种初始化聚类中心的方法:

  1. 初步将数据分成K个区域,将每个区域中心作为初始聚类中心
  2. 计算出每个点的”密度“,认为”密度“较大的是聚类中心。先把”密度“最大的挑出作为第一个聚类中心,从剩下的点中找出密度最大,且离所有已有聚类中心大于一定距离的点作为下一个聚类中心,直到选择了K个
  3. 计算整体均值,作为第一个聚类中心。从剩下的点中顺序寻找,当遇到离所有已有聚类中心大于一定距离的点,则作为下一个聚类中心,直到选择了K个

1999年

  在Pelleg, et al. "Accelerating exact k -means algorithms with geometric reasoning." 1999.中,针对传统k-means算法计算复杂度高因此费时的情况,作者提出通过“kd树”来加速k-means算法。作者通过实验说明,加速后的算法比原始k-means算法快25~175倍。

  1. 首先,将数据用“kd树”这种结构存储。关于构造“kd树”的详细资料,可以参考本文的kd-trees部分。这里仅进行一些额外的补充说明,利用“kd树”存储后的图像也给出:

    • “kd树”其实就是一种二叉树
    • 树的每个节点代表一个矩形,存储着这个矩形中数据点的信息:,h(max),h(min),这两个向量用于描述这个矩形;矩形中数据点的数量
    • 树的每个非叶子节点还额外存储关于分裂成子树的信息:划分子树的值,此数值所在的维度
    • 树的根节点表示囊括所有数据的大矩形
    • 树的叶子节点存储具体的数据点信息,即该矩形中每个数据点的值
    • 树的深度是提前设定好的,并不一定要分裂到不可再分

  2. 在将数据用“kd树”存储后,利用树的性质,一般能比传统k-means更快找到每个点最近的聚类中心。详细的算法比较复杂,有兴趣的可以参考论文。这里给出几点说明帮助理解:

    • 比之传统k-means对每个样本点找最近邻聚类中心,“kd树”对其中的一个矩形找最近的聚类中心。对某个矩形(即树中某节点),若它平面中的每个点(区别于样本点)到某聚类中心的距离,比到其他聚类中心的距离都近,那么该矩形中所有样本点的最近邻聚类中心就能一次性确定下来了。
    • 由于并非树中所有矩形(即节点),都能找到满足以上条件的聚类中心。对于这些矩形,只能用传统办法求其中样本点的最近邻聚类中心
    • 因此,在最坏情况下,即树中每个矩形都不满足上述条件,“kd树”的k-means算法会比传统k-means更慢(因为还要构造树)。于是,“kd树”分裂的深度,是这个算法的一个重要参数

2000年

  在Pelleg, et al. "X-means: Extending K-means with Efficient Estimation of the Number of Clusters. Intelligent Data Engineering and Automated Learning" 2000.中,作者提出了一种改进的k-means算法,即X-means

  1. 作者先提出k-means聚类算法面临的三个主要问题,并表示X-means能解决前两个问题,并改善第三个问题

    • 计算量大
    • 聚类数量K需要提前设定
    • 只能收敛到局部最优
  2. 算法的整体思路如下,本质就是由上而下的d次聚类法:

    2.1 先设定K的范围[Kmin,Kmax], 令K=Kmin

    2.2 迭代2.3~2.4, 并令K=K∗2,直到K>Kmax

    2.3 执行传统K-means

    2.4 将每一个聚类中心分裂成两个,并检验性能是否提升,是则保留,否则放弃分裂

    文章截图如下

  3. 聚类中心分裂算法:

    3.1 对于其中一个聚类中心,首先将它分裂成两个,并让这两个点沿着相反的方向移动。移动的距离与这个区域大小成正比,移动的方向随机

    3.2 在父聚类中心的区域中,对这两个分裂后的聚类中心执行传统K-means算法

    3.3 利用 Bayesian information criterion (BIC)/Schwarz criterion计算得分,挑选得分较优秀的模型作为最终模型。BIC本质就是计算似然,但是为了克服过拟合,又增加对参数数量的惩罚项。详情可以参考wiki的BIC词条。文中的BIC定义如下。

  4. 本文作者与上文Pelleg, et al. "Accelerating exact k -means algorithms with geometric reasoning." 1999.作者是一样的,因此作者还提出能够用“kd树”来加速X-means算法。加速算法的细节不再赘述

当我们在谈论kmeans(2)的更多相关文章

  1. 当我们在谈论kmeans(1)

    本稿为初稿,后续可能还会修改:如果转载,请务必保留源地址,非常感谢! 博客园:http://www.cnblogs.com/data-miner/ 简书:建设中... 知乎:建设中... 当我们在谈论 ...

  2. 当我们在谈论kmeans(5)

    本系列意在长期连载分享,内容上可能也会有所删改: 因此如果转载,请务必保留源地址,非常感谢! 博客园:http://www.cnblogs.com/data-miner/(暂时公式显示有问题) 其他: ...

  3. 当我们在谈论kmeans(3)

        本系列意在长期连载分享,内容上可能也会有所删改: 因此如果转载,请务必保留源地址,非常感谢! 博客园:http://www.cnblogs.com/data-miner/(暂时公式显示有问题) ...

  4. K-Means 聚类算法

    K-Means 概念定义: K-Means 是一种基于距离的排他的聚类划分方法. 上面的 K-Means 描述中包含了几个概念: 聚类(Clustering):K-Means 是一种聚类分析(Clus ...

  5. 用scikit-learn学习K-Means聚类

    在K-Means聚类算法原理中,我们对K-Means的原理做了总结,本文我们就来讨论用scikit-learn来学习K-Means聚类.重点讲述如何选择合适的k值. 1. K-Means类概述 在sc ...

  6. K-Means聚类算法原理

    K-Means算法是无监督的聚类算法,它实现起来比较简单,聚类效果也不错,因此应用很广泛.K-Means算法有大量的变体,本文就从最传统的K-Means算法讲起,在其基础上讲述K-Means的优化变体 ...

  7. [Erlang 0117] 当我们谈论Erlang Maps时,我们谈论什么 Part 2

    声明:本文讨论的Erlang Maps是基于17.0-rc2,时间2014-3-4.后续Maps可能会出现语法或函数API上的有所调整,特此说明. 前情提要: [Erlang 0116] 当我们谈论E ...

  8. [Erlang 0116] 当我们谈论Erlang Maps时,我们谈论什么 Part 1

         Erlang 增加 Maps数据类型并不是很突然,因为这个提议已经进行了2~3年之久,只不过Joe Armstrong老爷子最近一篇文章Big changes to Erlang掀起不小了风 ...

  9. kmeans算法并行化的mpi程序

    用c语言写了kmeans算法的串行程序,再用mpi来写并行版的,貌似参照着串行版来写并行版,效果不是很赏心悦目~ 并行化思路: 使用主从模式.由一个节点充当主节点负责数据的划分与分配,其他节点完成本地 ...

随机推荐

  1. IIS访问共享文件详解

    前言 公司同事做了一个报表系统,需要做集群部署,本来是一件挺容易的事,但是部署过程中却遇到啦种种蛋疼问题. 问题1.我们的报表使用的是微软的水晶报表,需要上传报表的配置文件,然后水晶报表提供的控件来读 ...

  2. 【.net 深呼吸】记录WCF的通信消息

    前面老周给大伙伴们介绍了把跟踪信息写入日志文件的方法,今天咱们换个类似的话题来扯一下,对了,咱们就说说怎么把WCF的往来消息log下来吧. 尽管在现实生活中,我们不主张偷窥他人信息,不过,偷窥程序信息 ...

  3. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  4. JavaScript权威设计--JavaScript表达式与运算符,语句(简要学习笔记六)

    1.delete是一元操作符,用来删除对象属性或者元素. var a={ x:1, y:2 } delete a.x; //删除x属性 “x”in a //false:a对象中已经不存在x属性 ale ...

  5. <a>与文件下载-(下载一)

    <a>可直接下载xls,doc,rar,zip,exe,js文件(图片跟txt文件是直接打开的) <a href="wKioJlJolKeCIzkCADd3Wf7OPI42 ...

  6. Compile FreeCAD on Windows

    Compile FreeCAD on Windows eryar@163.com 1.Introduction FreeCAD是一个参数化的三维造型软件,主要用于任意大小的实际模型的设计.参数化的建模 ...

  7. join和split的区别

    join() 方法用于把数组中的所有元素放入一个字符串.元素是通过指定的分隔符进行分隔的. <script> var a=new Array(); a[0]="XHTML&quo ...

  8. owner:轻松管理java项目配置

    前段时间,一同事说在 github 上“活捉了”一个很有趣的开源项目,它是一个超轻量级的 jar 包,能够帮助你在 java 项目中摒弃样板式的 properties 配置代码,让你轻松自如地管理和使 ...

  9. ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理

    ServiceProvider最终提供的服务实例都是根据对应的ServiceDescriptor创建的,对于一个具体的ServiceDescriptor对象来说,如果它的ImplementationI ...

  10. linux内核调试技术之修改内核定时器来定位系统僵死问题

    1.简介 在内核调试中,会经常出现内核僵死的问题,也就是发生死循环,内核不能产生调度.导致内核失去响应.这种情况下我们可以采用修改系统内核中的系统时钟的中断来定位发生僵死的进程和函数名称.因为内核系统 ...