算法笔记: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=1Nj1,...,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算法的算法整理如下:

  1. step 1: 从 N N N个给定点当中随机 K K K个点作为 K K K个簇的中心点;
  2. step 2: 计算每一个点到这 K K K个簇的中心点之间的欧式距离,将其分配到最小的那个簇当中,从而对所有的点进行聚类;
  3. step 3: 对于2中得到的每一个簇,更新其中心点为所有点的均值,即 u = ∑ i x i n \\boldu = \\frac\\sum_i \\boldx_in u=nixi
  4. step 4: 重复上述2-3两步,直到迭代次数达到上限或者簇的中心不再发生变化。

而Kmeans的算法的优缺点因此也就比较明显:

  1. 优点
    • 易实现,易debug
  2. 缺点
    • 迭代非常耗时,对于大数据量尤其明显;
    • 较依赖于初始化中心的选择,不同初始化中心点的选择会带来较大的结果差异;

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=1Nj1,...,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=1Njmin∣∣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+1sk即可。

我们考察第 k k k次迭代,它分为两步:

  1. 对于上一次分类完成的簇,更新簇的中心从 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=1N∣∣xi,ujk+1∣∣
  2. 使用新的簇中心 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=1Njmin∣∣xi,ujk+1∣∣

其中,对于步骤二,显然有 s k + 1 ≤ s k + 1 ′ s^k+1 \\leq s^k+1' sk+1sk+1。因此,我们只要说明步骤一当中的聚类中心变换之后获得的新的 s k + 1 ′ s^k+1' sk+1小于等于 s k s^k sk即可。

而在这步骤一当中,由于簇的成员都没有发生改变,因此,我们要证明的问题也就是: