MATLAB kMeans并不总是收敛于全局最小值

时间:2010-09-07 10:30:54

标签: matlab machine-learning cluster-analysis k-means

我在MATLAB中编写了一个k-Means clustering算法,我想我会针对kmeans(X,k)内置的MATLAB进行尝试。

然而,对于非常简单的四簇设置(见图),MATLAB kMeans并不总是收敛到最优解(左),而是(右)。

我写的那个并不总是这样做,但是内置函数不应该能够解决这么简单的问题,总能找到最佳解决方案吗?

alt text

5 个答案:

答案 0 :(得分:11)

正如@Alexandre C.所解释的那样,K-means算法取决于初始聚类质心位置,并且无法保证它会收敛到最优解。

您可以做的最好的事情是使用随机起点重复实验几次。

MATLAB的实现提供了这样一个选项:replicates,它重复聚类N次,并选择具有最低总簇内点到质心距离的聚类。 您还可以使用start选项控制如何选择初始质心。

此外,MATLAB提供了多种距离测量(Euclidean,Manhattan,Cosine等)的选择。一个简洁的选项emptyaction允许您控制在迭代期间集群丢失其所有已分配成员时发生的情况。

但真正的优势在于它采用了两阶段算法:通常的分配 - 重新计算迭代,然后是在线更新阶段。请务必阅读documentation page的算法部分以获取更多信息。

答案 1 :(得分:4)

k-means算法对集群中心的初始猜测非常敏感。您是否尝试使用相同初始质量中心的两个代码?

算法很简单,我怀疑你的实现和Matlab之间有很多差异。

答案 2 :(得分:3)

我不认为这是一个简单的问题。:)事实上,维基百科关于“k-means聚类”的文章给出了计算复杂性的相当悲观的画面。

如果你想摆脱随机重启(依赖于初始猜测),折衷就是“全局k均值”算法;论文和matlab代码可以在这里找到:http://lear.inrialpes.fr/~verbeek/software.php

答案 3 :(得分:2)

你可能经常会对任何特定的“k-means算法”(即Lloyd算法)出现的解决方案感到失望。那是因为Lloyd的算法经常陷入糟糕的局部最小值。

幸运的是,劳埃德只是解决k-means的一种方式。并且有一种方法几乎总能找到更好的局部最小值。

诀窍是一次更新一个数据点的群集分配。您可以通过保持分配给每个均值的点数n来有效地执行此操作。因此,您可以在删除点m后重新计算群集均值x,如下所示:

m_new = (n * m - x) / (n - 1)

使用以下内容将x添加到群集均值m

m_new = (n * m + x) / (n + 1)

当然因为它无法进行矢量化,所以在MATLAB中运行会有点痛苦,但在其他语言中也不会太糟糕。

如果您真的热衷于获得最佳的本地最小值,并且不介意使用基于示例的群集,则应该查看affinity propagation。 MATLAB实现可在Frey lab affinity propagation page上找到。

答案 4 :(得分:2)

虽然K-Means++在单次运行中无法解决问题,但在运行N次时往往会提供更好的结果(与运行原始K-Means算法N次相比)。