聚类算法——K-means(上)
2012-12-09 13:05
197 查看
聚类算法——K-means(上) - Moondark - 博客园
我们经常接触到的聚类分析,一般都是数值聚类,一种常见的做法是同时提取 N 种特征,将它们放在一起组成一个 N 维向量,从而得到一个从原始数据集合到 N 维向量空间的映射——你总是需要显式地或者隐式地完成这样一个过程,然后基于某种规则进行分类,在该规则下,同组分类具有最大的相似性。
假设我们提取到原始数据的集合为(x1, x2, …, xn),并且每个xi为d维的向量,K-means聚类的目的就是,在给定分类组数k(k ≤ n)值的条件下,将原始数据分成k类
S = {S1, S2, …, Sk},在数值模型上,即对以下表达式求最小值:
![](http://upload.wikimedia.org/wikipedia/en/math/9/c/f/9cfab53538dcb8dcc4ec80e3576abf0d.png)
这里μi 表示分类Si 的平均值。
那么在计算机编程中,其又是如何实现的呢?其算法步骤一般如下:
1、从D中随机取k个元素,作为k个簇的各自的中心。
2、分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇。
3、根据聚类结果,重新计算k个簇各自的中心,计算方法是取簇中所有元素各自维度的算术平均数。
4、将D中全部元素按照新的中心重新聚类。
5、重复第4步,直到聚类结果不再变化。
6、将结果输出。
用数学表达式来说,
设我们一共有 N 个数据点需要分为 K 个 cluster ,k-means 要做的就是最小化
![](http://blog.pluskid.org/latexrender/pictures/6d769d53cfc5e304cda806c84b310ec8.png)
这个函数,其中
![](http://blog.pluskid.org/latexrender/pictures/d891478cdb3de9adf8ef756eec74c03a.png)
在数据点 n 被归类到 cluster k 的时候为 1 ,否则为 0 。直接寻找
![](http://blog.pluskid.org/latexrender/pictures/d891478cdb3de9adf8ef756eec74c03a.png)
和
![](http://blog.pluskid.org/latexrender/pictures/c593ae692832e500a04c7f47900f689a.png)
来最小化
![](http://blog.pluskid.org/latexrender/pictures/ff44570aca8241914870afbc310cdb85.png)
并不容易,不过我们可以采取迭代的办法:先固定
![](http://blog.pluskid.org/latexrender/pictures/c593ae692832e500a04c7f47900f689a.png)
,选择最优的
![](http://blog.pluskid.org/latexrender/pictures/d891478cdb3de9adf8ef756eec74c03a.png)
,很容易看出,只要将数据点归类到离他最近的那个中心就能保证
![](http://blog.pluskid.org/latexrender/pictures/ff44570aca8241914870afbc310cdb85.png)
最小。下一步则固定
![](http://blog.pluskid.org/latexrender/pictures/d891478cdb3de9adf8ef756eec74c03a.png)
,再求最优的
![](http://blog.pluskid.org/latexrender/pictures/c593ae692832e500a04c7f47900f689a.png)
。将
![](http://blog.pluskid.org/latexrender/pictures/ff44570aca8241914870afbc310cdb85.png)
对
![](http://blog.pluskid.org/latexrender/pictures/c593ae692832e500a04c7f47900f689a.png)
求导并令导数等于零,很容易得到
![](http://blog.pluskid.org/latexrender/pictures/ff44570aca8241914870afbc310cdb85.png)
最小的时候
![](http://blog.pluskid.org/latexrender/pictures/c593ae692832e500a04c7f47900f689a.png)
应该满足:
![](http://blog.pluskid.org/latexrender/pictures/a0aa5b1fd15778697fc5f5c6f1c3f348.png)
亦即
![](http://blog.pluskid.org/latexrender/pictures/c593ae692832e500a04c7f47900f689a.png)
的值应当是所有 cluster k 中的数据点的平均值。由于每一次迭代都是取到
![](http://blog.pluskid.org/latexrender/pictures/ff44570aca8241914870afbc310cdb85.png)
的最小值,因此
![](http://blog.pluskid.org/latexrender/pictures/ff44570aca8241914870afbc310cdb85.png)
只会不断地减小(或者不变),而不会增加,这保证了 k-means 最终会到达一个极小值。虽然 k-means 并不能保证总是能得到全局最优解,但是对于这样的问题,像 k-means 这种复杂度的算法,这样的结果已经是很不错的了。
首先 3 个中心点被随机初始化,所有的数据点都还没有进行聚类,默认全部都标记为红色,如下图所示:
![](http://blog.pluskid.org/wp-content/uploads/2008/12/iter_00.png)
然后进入第一次迭代:按照初始的中心点位置为每个数据点着上颜色,重新计算 3 个中心点,结果如下图所示:
![](http://blog.pluskid.org/wp-content/uploads/2008/12/iter_01.png)
可以看到,由于初始的中心点是随机选的,这样得出来的结果并不是很好,接下来是下一次迭代的结果:
![](http://blog.pluskid.org/wp-content/uploads/2008/12/iter_02.png)
可以看到大致形状已经出来了。再经过两次迭代之后,基本上就收敛了,最终结果如下:
![](http://blog.pluskid.org/wp-content/uploads/2008/12/iter_04.png)
不过正如前面所说的那样 k-means 也并不是万能的,虽然许多时候都能收敛到一个比较好的结果,但是也有运气不好的时候会收敛到一个让人不满意的局部最优解,例如选用下面这几个初始中心点:
![](http://blog.pluskid.org/wp-content/uploads/2008/12/iter_00_bad.png)
最终会收敛到这样的结果:
![](http://blog.pluskid.org/wp-content/uploads/2008/12/iter_03_bad.png)
整体来讲,K-means算法的聚类思想比较简单明了,并且聚类效果也还算可以,算是一种简单高效应用广泛的 clustering 方法,接下来,我将讨论其代码实现过程。
聚类算法——K-means(上)
首先要来了解的一个概念就是聚类,简单地说就是把相似的东西分到一组,同 Classification (分类)不同,对于一个 classifier ,通常需要你告诉它“这个东西被分为某某类”这样一些例子,理想情况下,一个 classifier 会从它得到的训练集中进行“学习”,从而具备对未知数据进行分类的能力,这种提供训练数据的过程通常叫做 supervised learning (监督学习),而在聚类的时候,我们并不关心某一类是什么,我们需要实现的目标只是把相似的东西聚到一起,因此,一个聚类算法通常只需要知道如何计算相似 度就可以开始工作了,因此 clustering 通常并不需要使用训练数据进行学习,这在 Machine Learning 中被称作 unsupervised learning (无监督学习)。我们经常接触到的聚类分析,一般都是数值聚类,一种常见的做法是同时提取 N 种特征,将它们放在一起组成一个 N 维向量,从而得到一个从原始数据集合到 N 维向量空间的映射——你总是需要显式地或者隐式地完成这样一个过程,然后基于某种规则进行分类,在该规则下,同组分类具有最大的相似性。
假设我们提取到原始数据的集合为(x1, x2, …, xn),并且每个xi为d维的向量,K-means聚类的目的就是,在给定分类组数k(k ≤ n)值的条件下,将原始数据分成k类
S = {S1, S2, …, Sk},在数值模型上,即对以下表达式求最小值:
![](http://upload.wikimedia.org/wikipedia/en/math/9/c/f/9cfab53538dcb8dcc4ec80e3576abf0d.png)
这里μi 表示分类Si 的平均值。
那么在计算机编程中,其又是如何实现的呢?其算法步骤一般如下:
1、从D中随机取k个元素,作为k个簇的各自的中心。
2、分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇。
3、根据聚类结果,重新计算k个簇各自的中心,计算方法是取簇中所有元素各自维度的算术平均数。
4、将D中全部元素按照新的中心重新聚类。
5、重复第4步,直到聚类结果不再变化。
6、将结果输出。
用数学表达式来说,
设我们一共有 N 个数据点需要分为 K 个 cluster ,k-means 要做的就是最小化
![](http://blog.pluskid.org/latexrender/pictures/6d769d53cfc5e304cda806c84b310ec8.png)
这个函数,其中
![](http://blog.pluskid.org/latexrender/pictures/d891478cdb3de9adf8ef756eec74c03a.png)
在数据点 n 被归类到 cluster k 的时候为 1 ,否则为 0 。直接寻找
![](http://blog.pluskid.org/latexrender/pictures/d891478cdb3de9adf8ef756eec74c03a.png)
和
![](http://blog.pluskid.org/latexrender/pictures/c593ae692832e500a04c7f47900f689a.png)
来最小化
![](http://blog.pluskid.org/latexrender/pictures/ff44570aca8241914870afbc310cdb85.png)
并不容易,不过我们可以采取迭代的办法:先固定
![](http://blog.pluskid.org/latexrender/pictures/c593ae692832e500a04c7f47900f689a.png)
,选择最优的
![](http://blog.pluskid.org/latexrender/pictures/d891478cdb3de9adf8ef756eec74c03a.png)
,很容易看出,只要将数据点归类到离他最近的那个中心就能保证
![](http://blog.pluskid.org/latexrender/pictures/ff44570aca8241914870afbc310cdb85.png)
最小。下一步则固定
![](http://blog.pluskid.org/latexrender/pictures/d891478cdb3de9adf8ef756eec74c03a.png)
,再求最优的
![](http://blog.pluskid.org/latexrender/pictures/c593ae692832e500a04c7f47900f689a.png)
。将
![](http://blog.pluskid.org/latexrender/pictures/ff44570aca8241914870afbc310cdb85.png)
对
![](http://blog.pluskid.org/latexrender/pictures/c593ae692832e500a04c7f47900f689a.png)
求导并令导数等于零,很容易得到
![](http://blog.pluskid.org/latexrender/pictures/ff44570aca8241914870afbc310cdb85.png)
最小的时候
![](http://blog.pluskid.org/latexrender/pictures/c593ae692832e500a04c7f47900f689a.png)
应该满足:
![](http://blog.pluskid.org/latexrender/pictures/a0aa5b1fd15778697fc5f5c6f1c3f348.png)
亦即
![](http://blog.pluskid.org/latexrender/pictures/c593ae692832e500a04c7f47900f689a.png)
的值应当是所有 cluster k 中的数据点的平均值。由于每一次迭代都是取到
![](http://blog.pluskid.org/latexrender/pictures/ff44570aca8241914870afbc310cdb85.png)
的最小值,因此
![](http://blog.pluskid.org/latexrender/pictures/ff44570aca8241914870afbc310cdb85.png)
只会不断地减小(或者不变),而不会增加,这保证了 k-means 最终会到达一个极小值。虽然 k-means 并不能保证总是能得到全局最优解,但是对于这样的问题,像 k-means 这种复杂度的算法,这样的结果已经是很不错的了。
首先 3 个中心点被随机初始化,所有的数据点都还没有进行聚类,默认全部都标记为红色,如下图所示:
![](http://blog.pluskid.org/wp-content/uploads/2008/12/iter_00.png)
然后进入第一次迭代:按照初始的中心点位置为每个数据点着上颜色,重新计算 3 个中心点,结果如下图所示:
![](http://blog.pluskid.org/wp-content/uploads/2008/12/iter_01.png)
可以看到,由于初始的中心点是随机选的,这样得出来的结果并不是很好,接下来是下一次迭代的结果:
![](http://blog.pluskid.org/wp-content/uploads/2008/12/iter_02.png)
可以看到大致形状已经出来了。再经过两次迭代之后,基本上就收敛了,最终结果如下:
![](http://blog.pluskid.org/wp-content/uploads/2008/12/iter_04.png)
不过正如前面所说的那样 k-means 也并不是万能的,虽然许多时候都能收敛到一个比较好的结果,但是也有运气不好的时候会收敛到一个让人不满意的局部最优解,例如选用下面这几个初始中心点:
![](http://blog.pluskid.org/wp-content/uploads/2008/12/iter_00_bad.png)
最终会收敛到这样的结果:
![](http://blog.pluskid.org/wp-content/uploads/2008/12/iter_03_bad.png)
整体来讲,K-means算法的聚类思想比较简单明了,并且聚类效果也还算可以,算是一种简单高效应用广泛的 clustering 方法,接下来,我将讨论其代码实现过程。
相关文章推荐
- 聚类算法——K-means(上)
- 聚类算法——K-means(下)
- 聚类算法——K-means
- 【opencv、机器学习】聚类算法——K-means
- 经典聚类算法——K-means
- 聚类算法——K-means(上)
- 聚类算法——K-means(下)
- What IBGP Full Mesh really Means?
- 聚类算法之K-means
- PROC MEANS AND PROC SUMMARY
- Weka -- 聚类算法之K-means
- 基于SIFT+Kmeans+LDA的图片分类器的实现
- K-Means 算法
- K-Means 算法
- Maciej Pacula » k-means clustering example (Python)
- k-means & isodata 聚类方法
- 图像处理之Fuzzy C Means的聚合算法
- Machine Learning week 8 programming exercise K-means Clustering and Principal Component Analysis
- mahout 源码解析之聚类--K-Means,FuzzyKMeans
- Spark K-Means 算法实践之Java版