聚类(Clustering)问题
在 无监督学习(Unsupervised Learning) 中,我们的数据没有附带任何标签。
假如我们有一系列数据,它是二维的。这一系列数据只有特征 x = [ x 1 , x 2 ] \boldsymbol{x}=[x_1,\; x_2] x=[x1,x2],却没有标签 y y y。
如下图所示:
不知道它们代表什么,但是可以看出来它们是一簇一簇的。
我们要把这组数据输入到一个算法中,找到一种结构,把图中的数据分成几簇(cluster)。
聚类算法可以帮你做这件事情。
K-Means
K-Means 算法是一种最常用的聚类算法。给算法一个无标签的数据集,然后它会把数据聚类成不同的组。
大致步骤如下:
- 选择 K K K 个随机的点,称为聚类中心(cluster centroids)。即 K K K 个中心点。
- 对于每一个数据,计算它到每个中心点的距离。这里有 K K K 个中心点,取距离最近的那个中心点,把数据分配到该类。
- 所有数据分配完后,计算每一个组的平均值,将该组的中心点移动到平均值的位置。
- 重复步骤 2-3,直到中心点不再变化。
下面以文章开头的图为例,讲讲聚类的过程。
首先随机选择
K
K
K 个中心点。这里
K
=
3
K=3
K=3,,用红、绿、蓝 3 种颜色表示:
然后根据距离,把数据分配到所属中心点:
对每个类的数据求平均值,得到新的中心点,移动中心点:
按照最近的中心点,重新分配数据:
继续迭代:
直到中心点不再移动,完成算法。
优化目标
假如数据集的样本个数为 m m m,设定了 K K K 个中心点。
我们用 μ 1 \boldsymbol{\mu}_1 μ1, μ 2 \boldsymbol{\mu}_2 μ2, ⋯ \cdots ⋯, μ K \boldsymbol{\mu}_K μK 表示各个聚类中心点。
用
c
1
c_1
c1,
c
2
c_2
c2,
⋯
\cdots
⋯,
c
m
c_m
cm 来存储与第
i
i
i 个样本最近的聚类中心的索引。
例如第
2
2
2 个样本与第
1
1
1 个中心点最近,则
c
2
=
1
c_2=1
c2=1。若第
i
i
i 个样本与第
2
2
2 个中心点最近,则
c
i
=
2
c_i=2
ci=2。
K-means 最小化问题,是要最小化所有的数据点与其所关联的聚类中心点之间的距离之和.
代价函数为:
J
(
c
1
,
…
,
c
m
,
μ
1
,
…
,
μ
K
)
=
1
m
∑
i
=
1
m
∥
x
i
−
μ
c
i
∥
2
J(c_1,\dots,c_m,\boldsymbol{\mu}_1,\dots,\boldsymbol{\mu}_K) = \frac{1}{m} \sum_{i=1}^{m} \| \boldsymbol{x}_{i} - \boldsymbol{\mu}_{c_i}\|^2
J(c1,…,cm,μ1,…,μK)=m1i=1∑m∥xi−μci∥2
其中 μ c i \boldsymbol{\mu}_{c_i} μci 表示与 x i \boldsymbol{x}_{i} xi 最近的聚类中心点。
优化的目标是找到 c 1 c_1 c1, c 2 c_2 c2, ⋯ \cdots ⋯, c m c_m cm 和 μ 1 \boldsymbol{\mu}_1 μ1, μ 2 \boldsymbol{\mu}_2 μ2, ⋯ \cdots ⋯, μ K \boldsymbol{\mu}_K μK , 使得代价函数最小: min c 1 , … , c m , μ 1 , … , μ K J ( c 1 , … , c m , μ 1 , … , μ K ) \min_{c_1,\dots,c_m,\boldsymbol{\mu}_1,\dots,\boldsymbol{\mu}_K} J(c_1,\dots,c_m,\boldsymbol{\mu}_1,\dots,\boldsymbol{\mu}_K) c1,…,cm,μ1,…,μKminJ(c1,…,cm,μ1,…,μK)
回顾上面讲的 K-means 步骤,循环步骤 2 和步骤 3,
其中步骤 2 是用于减小
c
i
c_i
ci 引起的代价;
步骤 3 是用于减小
μ
i
\boldsymbol{\mu}_i
μi 引起的代价。
随机初始化
在进行 K-means 算法之前,需要随机初始化各个聚类的中心点。
由于初始化的情况不同,可能会使算法停留在一个局部最小值:
解决这个问题的办法是,运行多几次 K-means 算法,每次都重新随机初始化。最后选择代价函数最小的那一次作为结果。
不过这种办法在 K K K 比较小( 2 ∼ 10 2\sim10 2∼10)的时候还行,如果 K K K 比较大,可能没有明显的改善。
K K K 值的选择
这一般根据你的问题来手动选择。
有一个叫做 “肘部法则” 的方法会经常用到。选择不同的 K K K 进行聚类,计算代价函数 J J J,得到这样的曲线:
这条曲线像人的手臂。刚开始的时候
J
J
J 会迅速下降,从某个地方开始(左边图的
K
=
3
K=3
K=3)下降速度变慢了。那么选择
K
=
3
K=3
K=3 就是一个合适的值。但是有时候这个节点不太明显,例如右边这个图。