算法笔记:Kmeans聚类算法简介
Posted Espresso Macchiato
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法笔记:Kmeans聚类算法简介相关的知识,希望对你有一定的参考价值。
1. Kmeans算法简介
Kmeans算是非常经典的一个聚类算法了,早已经被写到教科书里面了,不过很不幸的是,最近干活遇到了这个,然后我发现我已经忘得差不多一干二净了……
所以这里就过来挖个坟,考个古,把这玩意拉出来复习一下。
如前所述,Kmeans算法是一个聚类算法,具体来说,我们输入一个包含 N N N个点的点集,我们的目的是要将这 N N N个点分为 K K K个簇,使得每个点到各自的簇的中心距离之和最小。
用公式来表达的话就是:
s = ∑ i = 1 N m i n j ∈ 1 , . . . , K ( d ( x i , u j ) ) s = \\sum_i=1^N \\mathopmin\\limits_j \\in \\1, ..., K\\(d(x_i, u_j)) s=i=1∑Nj∈1,...,Kmin(d(xi,uj))
要找到一组 u j u_j uj使得 s s s最大。
其中, d ( x , y ) d(x, y) d(x,y)表示 x , y x,y x,y两点间的距离,一般我们在这里使用欧氏距离。
2. Kmeans算法细节
Kmeans算法的核心思路是迭代。
首先,我们随机从 N N N个点当中选出 K K K个点作为簇的中心点。
然后,根据全部的 N N N个点到这 K K K个中心点之间的距离,我们就可以将这全部的 N N N个点进行分类,分配到这 K K K个簇当中。
而后,我们更新这 K K K个簇的中心,具体来说,我们取这 K K K个点的均值点作为这 K K K个簇的新的中心。
我们不断地重复上述两个步骤,直到达到迭代上限或者簇的中心点不再发生变化即可。
具体的,我们可以给出上述Kmeans算法的算法整理如下:
- step 1: 从 N N N个给定点当中随机 K K K个点作为 K K K个簇的中心点;
- step 2: 计算每一个点到这 K K K个簇的中心点之间的欧式距离,将其分配到最小的那个簇当中,从而对所有的点进行聚类;
- step 3: 对于2中得到的每一个簇,更新其中心点为所有点的均值,即 u = ∑ i x i n \\boldu = \\frac\\sum_i \\boldx_in u=n∑ixi;
- step 4: 重复上述2-3两步,直到迭代次数达到上限或者簇的中心不再发生变化。
而Kmeans的算法的优缺点因此也就比较明显:
- 优点
- 易实现,易debug
- 缺点
- 迭代非常耗时,对于大数据量尤其明显;
- 较依赖于初始化中心的选择,不同初始化中心点的选择会带来较大的结果差异;
3. Kmeans算法收敛性证明
现在,给出了kmeans聚类算法之后,我们来考察一下kmeans算法的收敛性,也就是说,为什么kmeans算法的迭代是有效的。
我们使用原始的kmeans算法进行说明,即是说,使用欧式距离来对两点间的距离进行描述,此时,前述提到的loss函数就可以表达为:
s = ∑ i = 1 N m i n j ∈ 1 , . . . , K ∣ ∣ x i , u j ∣ ∣ s = \\sum_i=1^N \\mathopmin\\limits_j \\in \\1, ..., K\\ ||x_i, u_j|| s=i=1∑Nj∈1,...,Kmin∣∣xi,uj∣∣
具体到第 k k k次迭代上,即有:
s k = ∑ i = 1 N m i n j ∣ ∣ x i , u j k ∣ ∣ s^k = \\sum_i=1^N \\mathopmin\\limits_j ||x_i, u_j^k|| sk=i=1∑Njmin∣∣xi,ujk∣∣
显然, s k s^k sk是一个大于0的数列,因此,我们只需要证明 s k s^k sk递减,那么数列 s k s^k sk必然收敛。
因此,我们只需要证明 s k + 1 ≤ s k s^k+1 \\leq s^k sk+1≤sk即可。
我们考察第 k k k次迭代,它分为两步:
- 对于上一次分类完成的簇,更新簇的中心从
u
k
u^k
uk到
u
k
+
1
u^k+1
uk+1;
s k + 1 ′ = ∑ i = 1 N ∣ ∣ x i , u j k + 1 ∣ ∣ s^k+1' = \\sum_i=1^N ||x_i, u_j^k+1|| sk+1′=i=1∑N∣∣xi,ujk+1∣∣ - 使用新的簇中心
u
k
+
1
u^k+1
uk+1对所有的点进行更新;
s k + 1 = ∑ i = 1 N m i n j ∣ ∣ x i , u j k + 1 ∣ ∣ s^k+1 = \\sum_i=1^N \\mathopmin\\limits_j ||x_i, u_j^k+1|| sk+1=i=1∑Njmin∣∣xi,ujk+1∣∣
其中,对于步骤二,显然有 s k + 1 ≤ s k + 1 ′ s^k+1 \\leq s^k+1' sk+1≤sk+1′。因此,我们只要说明步骤一当中的聚类中心变换之后获得的新的 s k + 1 ′ s^k+1' sk+1′小于等于 s k s^k sk即可。
而在这步骤一当中,由于簇的成员都没有发生改变,因此,我们要证明的问题也就是:
- 对一系列点 x 1 , . . . , x n i \\boldx_1, ..., \\boldx_n_i x1,...,xni, s = ∑ j = 1 n i ∣ ∣ x j − μ ∣ ∣ s = \\sum\\limits_j=1^n_i ||\\boldx_j - \\bold\\mu|| s=j=1∑ni∣∣xj−μ∣∣在 μ = 1 n i ∑ j = 1 n i x j \\bold\\mu = \\frac1n_i\\sum\\limits_j=1^n_i \\boldx_j μ=nKmeans聚类算法简介