算法过程
假设我们要从散点数据集中找到 K K K个聚类,那么算法第一步就是随机出 K K K个随机点作为每个聚类的聚点。之后,遍历所有数据点,计算这些数据点与 K K K个聚点的距离,将其划分到与其最近的的聚点所在聚类中。划分完成后,我们再移动聚点,把聚点放在它所在聚类的平均点上(如果有个聚点没有任何的数据点归到它这类,那么我们可以直接删除或者再重新随机一个聚点)。划分数据点+移动聚点为一次循环,我们一直执行循环,直到聚点不再移动就表明我们找到了 K K K个聚类。
算法原理
为了表述方便,我们令
c
(
i
)
c^{(i)}
c(i)表示第
i
i
i个样本
x
(
i
)
x^{(i)}
x(i)被划分到的聚类索引,
μ
k
\mu_k
μk表示第
k
k
k个聚类的聚点,那么K均值算法的目的其实是最小化代价函数
J
(
c
(
1
)
,
⋯
,
c
(
m
)
,
μ
1
,
⋯
,
μ
K
)
=
1
m
∑
i
=
1
m
∣
∣
x
(
i
)
−
μ
c
(
i
)
∣
∣
2
J(c^{(1)},\cdots,c^{(m)},\mu_1,\cdots,\mu_K)=\frac{1}{m}\sum_{i=1}^m||x^{(i)}-\mu_{c^{(i)}}||^2
J(c(1),⋯,c(m),μ1,⋯,μK)=m1i=1∑m∣∣x(i)−μc(i)∣∣2
即让每个点到自己所在聚类聚点的距离平方之和最小。这不难理解,在算法过程中,第一步划分过程就是让每个点选择离自己最近的聚点,而第二部则是调整聚点使其与聚类里的其他点的距离平方之和最小。两步交错循环进行就是不断寻找最低点的过程。
规避局部最优解
如果初始聚点设置的不好,很可能会陷入局部最优解。一种推荐的初始化聚点的方法是在样本点中随机挑选
K
K
K个作为初始聚点。但有时候,算还是会落入局部最优解,比如下图下方两种情况,两个聚类被合并成了一个大聚类,而剩下的一个聚类又被切分成两个小聚类。
为了规避这样的局部最优解,我们可能需要多次随机初始化后运行K均值算法,从中选取代价函数值最低的模型。一般而言,对于
K
≤
10
K\le10
K≤10的问题,100次随机就可以找到一个较好的解。