K-means Algorithm
在监督学习中,有标签信息协助机器学习同类样本之间存在的共性,在预测时只需判定给定样本与哪个类别的训练样本最相似即可。在非监督学习中,不再有标签信息的指导,遇到一维或二维数据的划分问题,人用肉眼就很容易完成,可机器就傻眼了,图(1)描述得很形象。
但处理高维度的数据,人脑也无能为力了,最终还是得设计算法让机器来完成。如何将所有样本分成若干个类簇(cluster),并且每个类簇中的样本具有更高的相似度,这就是聚类分析算法的终极目标。这里以最经典的K-means算法为切入点进行说明。 K-means算法的目标是将\(m\)个样本组成的集合\(X=\{x^{(1)},x^{(2)},\cdots,x^{(m)}|x^{(i)}\in\mathbb{R}^n\}\)划分成\(k\)个类簇(\(k\leq m\)),其准则函数形式如下: \begin{equation} J(c,\mu)=\sum_{i=1}^m\|x^{(i)}-\mu_c^{(i)}\|^2 \end{equation} 其中\(c\)为样本的类簇分配情况,\(\mu\)为类簇中心点,\(\mu_c^{(i)}\)为样本\(x^{(i)}\)对应的类簇中心。准则函数计算的是所有样本点与其对应的类簇中心的距离平方和。使准则函数最小的类簇划分极为最优的聚类。K-means算法描述请下图。
算法的内层循环完成两个工作:一是将每个样本划分到与其最近的类簇中心;二是将属于同一个类簇的样本均值作为新的类簇中心。算法的终止条件可以有三种:1)准则函数值的变化小于一个阈值;2)类簇中心在一定范围内不再变化;3)达到指定的迭代次数\(T\)。K-means的执行步骤如图(2)所示:(a)随机初始化的样本点;(b)随机设置类簇中心;(c)给样本点分配与之最近的类簇中心;(d)类簇中心更新为类簇中所有样本的均值;重复(c)和(d)直到收敛。
这里的准则函数不是凸函数,找到全局最优解是不可能的,但是能保证它收敛到局部最优解,分析如下:
- 更新样本\(x^{(i)}\)所属的类簇时,总是选择与其最近的类簇中心,所以\(\|x^{(i)}-\mu_c^{(i)}\|^2\)在每次迭代过程都是非递增的,那么能保证准则函数\(J\)也是非递增的;
- 类簇中心被更新为类簇中所有样本的均值也能保证\(J\)非递增。准则函数对类簇中心求偏导,并令偏导为0即可求得类簇中心的更新规则 \begin{equation} \begin{array}{rl} \frac{\partial J}{\partial \mu_j}&=\frac{\partial}{\partial\mu_j}\sum_{i=1}^m 1\{c^{(i)}=j\}\|x^{(i)}-\mu_c^{(i)}\|^2\\ &=2\sum_{i=1}^m 1\{c^{(i)}=j\}\left(\mu_c^{(i)}-x^{(i)}\right)=0\\ &\Rightarrow \mu_j=\frac{\sum_{i=1}^m1\{c^{(i)}=j\}x^{(i)}}{\sum_{i=1}^m1\{c^{(i)}=j\}} \end{array} \end{equation}
图(3)左侧是在随机生成的四组服从高斯分布的数据上跑完K-means后的聚类结果;右侧则为每次迭代过程中准则函数值的变化曲线图,经过16次迭代后算法就收敛了,这也从实验角度验证了算法的收敛性。因为给定的不同类簇的数据间分得比较开,最后的聚类分析结果堪称完美。由于这次随机初始化的类簇中心情况很糟糕,算法经过16次迭代后才收敛,一般在8次以内就稳定了。
如果样本有多个属性,而且属性不在同一个定义域内,则有必要对样本数据进行预处理,防止某些值很大的属性在计算距离时占主导优势。最常用的就是标准化处理,使得每个属性均值为0,方差为1。 K-means算法对类簇中心的初始化非常敏感,如图(4)所示,我在图中示意性标出了6个可能的初始点,算法会收敛到对应的6个局部最优解,然而只有第2个才是全局最优解。为了避免陷入很差的局部最优解(如第1个局部最优解),常用的策略就是多跑几次K-means,每次都将类簇中心随机初始化,最后选取使准则函数最小的聚类情况。
聚类的最终目的是使同一个类簇中的数据尽可能相似,而不同类簇间的样本彼此离得越远越好。如果我们在初始化类簇中心的时候就遵循这条原则,则可以大大减少收敛所需的迭代次数。下面给出了类簇中心初始化的算法(2)描述,该算法的时间复杂度为\(O(m^2+km)\)。我们可以想象到,该初始化算法实际上是从样本分布的最边缘开始选取类簇中心的,以避免类簇中心被初始化到数据较为密集的地方,大大降低算法收敛需要的迭代次数。有收获必然也要付出代价,这是永恒的真理,这么做是否值还得视情况而定。
在标准的K-means算法中,每个样本点都要和更新后的类簇中心计算距离欧氏距离,如果样本维度较高的话,算法的时间复杂度会非常高。有些大牛们提出用三角不等式或树形结构等对K-means进行加速的算法,以减少不必要的距离计算。建议参考2003年Elkan发表在ICML上的论文《Using the triangle inequality to accelerate k-means》,以及《A generalized optimization of the k-d tree for fast nearest neighbour search》。开源项目VLFeat中就使用了k-d树加速K-means。 在批量版本K-means算法中,我们用所有数据一次性更新类簇中心。但遇到需要在线处理的应用时,处理时间是关键,另外一个挑战就是数据的动态输入,因此有必要为K-means设计一个在线算法。在时间允许的范围内,我们可以一次值处理一条数据,也可以等收集到几条数据后一起处理。在前面证明K-means算法的收敛性过程中,我们求出了准则函数对类簇中心\(\mu_j\)的偏导,我们很容易将其改造成利用随机梯度下降的online版本算法(3),其中学习率参数\(\alpha\)应该随处理数据的增多而逐渐减小。
K-means算法的一大特点是每个样本只能被硬性分配(hard assignment)到一个类簇中,这种方法不一定是最合理的。但聚类本身就是一个具有不确定性的问题,如图(5)所示,实际情况中的类簇很可能存在重叠的情况,那么重叠的部分的归属就颇具争议了;给定一个新样本,正好它与所有类簇中心的聚类是相等的,我们又该怎么办?如果我们采用概率的方法,像高斯混合模型(Gauss Mixture Model,GMM)那样给出样本属于每个类簇的概率值,能从一定程度上反映聚类的不确定性就更合理了。
下面介绍K-means算法的两个简单应用:图像分割和数据压缩。图像分割的目标是将图像划分成若个区域,每个区域内有相似的视觉效果。K-means用于图像分割,实际上就是将图像中的所有像素点当成样本点,将相似的像素点尽可能划分到同一个类簇中,最后就形成了\(k\)个区域,在展示分割情况时以类簇中心代替该类簇中的所有样本。如图(6)所示,我选择了经典的Lena图像和一只小鸟图像进行分割,每次聚类的中心数目\(k\)从左到右依次为\(3,6,12\),最右侧围原图。Lena图像的颜色种类较少,所有$k=3$时的效果也还行;但是小鸟图像颜色复杂很多,直到\(k=12\)时图像的分割效果才略微令人满意。图像分割其实是个相当有难度的问题,K-means算法在这个领域还是太弱了...
数据压缩分为无损压缩和有损压缩两大类,无损压缩要求数据还原后要和元素数据一模一样,而有损压缩可以容忍重构数据与元素数据存在一定程度的偏差。K-means算法用于数据压缩只能是有损压缩了,\(k\)越小数据失真越厉害。主要思想是在\(N\)个样本集合中用于K-means算法得到\(k\)个类簇中心和\(N\)个类簇的分配情况,最终我们只需存储类簇中心和每个样本的类簇分配情况即可。假设每个样本的存储空间为\(a\)字节,则\(k\)各类簇中心需要的存储空间为\(ka\)字节,类簇分配情况耗费存储空间为\(N\lceil\log_2 k\rceil\)字节,压缩比为\(Na/\left(ka+N\lceil\log_2 k\rceil\right)\)。
整个K-means实验的Matlab代码在这里下载!
K-means Algorithm的更多相关文章
- KNN 与 K - Means 算法比较
KNN K-Means 1.分类算法 聚类算法 2.监督学习 非监督学习 3.数据类型:喂给它的数据集是带label的数据,已经是完全正确的数据 喂给它的数据集是无label的数据,是杂乱无章的,经过 ...
- 软件——机器学习与Python,聚类,K——means
K-means是一种聚类算法: 这里运用k-means进行31个城市的分类 城市的数据保存在city.txt文件中,内容如下: BJ,2959.19,730.79,749.41,513.34,467. ...
- 机器学习:weka中添加自己的分类和聚类算法
不管是实验室研究机器学习算法或是公司研发,都有需要自己改进算法的时候,下面就说说怎么在weka里增加改进的机器学习算法. 一 添加分类算法的流程 1 编写的分类器必须继承 Classifier或是Cl ...
- [C2P3] Andrew Ng - Machine Learning
##Advice for Applying Machine Learning Applying machine learning in practice is not always straightf ...
- Andrew Ng机器学习公开课笔记 -- Mixtures of Gaussians and the EM algorithm
网易公开课,第12,13课 notes,7a, 7b,8 从这章开始,介绍无监督的算法 对于无监督,当然首先想到k means, 最典型也最简单,有需要直接看7a的讲义 Mixtures of G ...
- 快速查找无序数组中的第K大数?
1.题目分析: 查找无序数组中的第K大数,直观感觉便是先排好序再找到下标为K-1的元素,时间复杂度O(NlgN).在此,我们想探索是否存在时间复杂度 < O(NlgN),而且近似等于O(N)的高 ...
- 网络费用流-最小k路径覆盖
多校联赛第一场(hdu4862) Jump Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- numpy.ones_like(a, dtype=None, order='K', subok=True)返回和原矩阵一样形状的1矩阵
Return an array of ones with the same shape and type as a given array. Parameters: a : array_like Th ...
- 当我们在谈论kmeans(2)
本稿为初稿,后续可能还会修改:如果转载,请务必保留源地址,非常感谢! 博客园:http://www.cnblogs.com/data-miner/ 其他:建设中- 当我们在谈论kmeans(2 ...
- scikit-learn包的学习资料
http://scikit-learn.org/stable/modules/clustering.html#k-means http://my.oschina.net/u/175377/blog/8 ...
随机推荐
- TortoiseHg简单的入门使用说明
参考资料: 互普的 TortoiseHg使用说明_百度文库 Mercurial(Hg)基本操作 - Tim Gong - 博客园 Mercurial与TortoiseHg使用入门教程(转) - mee ...
- MVC & MVVM
什么是MVC,什么是MVVM? 面向过程 --> 面向对象 --> MVC --> MV* 面向过程: 开发人员按照需求逻辑顺序开发代码逻辑,主要思维模式在于如何实现.先细节,后整体 ...
- 2016 Multi-University Training Contest 5 1012 World is Exploding 树状数组+离线化
http://acm.hdu.edu.cn/showproblem.php?pid=5792 1012 World is Exploding 题意:选四个数,满足a<b and A[a]< ...
- mybatis系列-10-一对一查询
10.1 需求 查询订单信息,关联查询创建订单的用户信息 10.2 resultType 10.2.1 sql语句 确定查询的主表:订单表 确定查询的关联表:用户表 关联查询 ...
- C++多态分析(polymorphisn)
前言 借着这次学校的生产实习来回顾下C++的多态,这里讨论下C++的多态以及实现原理.我都是在QT下使用C++的,就直接在QT下进行演示了 多态介绍 面向对象语言中最核心的几个理念就是:封装.继承.多 ...
- work_8
1.把程序编译通过, 跑起来. 读懂程序,在你觉得比较难懂的地方加上一些注释,这样大家就能比较容易地了解这些程序在干什么. 把正确的 playPrev(GoMove) 的方法给实现了. 如果大家不会下 ...
- HDU 5792 World is Exploding (树状数组)
World is Exploding 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5792 Description Given a sequence ...
- php-fpm占用系统资源分析
故障检测 1.别的先不管,先top看一下cpu.ram.swap哪个比较紧张. 由上图分析,可以看出共有602个进程,其中有601个进程休眠了.这好像有点不对劲,内核进程也就80个左右,加上memca ...
- 了解discuz!
discuz!是什么 discuz!是由comsenz出品的,一款使用php编写,以MySQL作为数据存储的社区建站产品,是由戴志康大学时期创始开发,2001年6月发布,如今已被200万网站用做社区建 ...
- HDU 3664 Permutation Counting (DP)
题意:给一个 n,求在 n 的所有排列中,恰好有 k 个数a[i] > i 的个数. 析:很明显是DP,搞了好久才搞出来,觉得自己DP,实在是太low了,思路是这样的. dp[i][j]表示 i ...