假设我们提取到原始数据的集合为(x1, x2, …, xn),并且每个xi为d维的向量,K-means聚类的目的就是,在给定分类组数k(k ≤ n)值的条件下,将原始数据分成k类
S = {S1, S2, …, Sk},在数值模型上,即对以下表达式求最小值:
这里μi 表示分类Si 的平均值。
那么在计算机编程中,其又是如何实现的呢?其算法步骤一般如下:
1、从D中随机取k个元素,作为k个簇的各自的中心。
2、分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇。
3、根据聚类结果,重新计算k个簇各自的中心,计算方法是取簇中所有元素各自维度的算术平均数。
4、将D中全部元素按照新的中心重新聚类。
5、重复第4步,直到聚类结果不再变化。
6、将结果输出。
用数学表达式来说,
设我们一共有 N 个数据点需要分为 K 个 cluster ,k-means 要做的就是最小化
这个函数,其中 在数据点 n 被归类到 cluster k 的时候为 1 ,否则为 0 。直接寻找
和
来最小化
并不容易,不过我们可以采取迭代的办法:先固定
,选择最优的
,很容易看出,只要将数据点归类到离他最近的那个中心就能保证
最小。下一步则固定
,再求最优的
。将
对
求导并令导数等于零,很容易得到
最小的时候
应该满足:
亦即 的值应当是所有 cluster k 中的数据点的平均值。由于每一次迭代都是取到
的最小值,因此
只会不断地减小(或者不变),而不会增加,这保证了 k-means 最终会到达一个极小值。虽然 k-means 并不能保证总是能得到全局最优解,但是对于这样的问题,像 k-means 这种复杂度的算法,这样的结果已经是很不错的了。
通俗理解:
输入:
- k个聚类的中心点的位置;
- n个数据对象的位置;
输出:
将这n个数据对象划入这k个聚类中,即计算出这k个聚类所属的聚类。
计算过程:
1. 计算点p与这k个聚类的距离l1,l2,...,lk,并得到l1,l2,…,lk的最大值lm(设点p与聚类m的距离最近,值为lm)。
2. 将点p划入到聚类m,并重新计算聚类m的中心点位置。
3. 重复以上步骤,直到n个数据对象全部计算完成。
缺点:
1.k值的选择是用户指定的,不同的k得到的结果会有挺大的不同
2.对k个初始质心的选择比较敏感,容易陷入局部最小值
3.数据库比较大的时候,收敛会比较慢