scipy.cluster.kmeans 的结果不稳定

Posted

技术标签:

【中文标题】scipy.cluster.kmeans 的结果不稳定【英文标题】:unstable result from scipy.cluster.kmeans 【发布时间】:2013-12-07 02:16:09 【问题描述】:

以下代码在每次运行时给出不同的结果,同时使用 k 均值方法将数据聚类为 3 部分:

from numpy import array
from scipy.cluster.vq import kmeans,vq

data = array([1,1,1,1,1,1,3,3,3,3,3,3,7,7,7,7,7,7])
centroids = kmeans(data,3,100) #with 100 iterations
print (centroids)

获得的三个可能结果是:

(array([1, 3, 7]), 0.0)
(array([3, 7, 1]), 0.0)
(array([7, 3, 1]), 0.0)

其实计算出的k个均值的顺序是不一样的。但是,分配哪个 k 表示点属于哪个集群不是很不稳定吗?有什么想法吗??

【问题讨论】:

【参考方案1】:

来自the docs:

k_or_guess: int or ndarray

要生成的质心数。为每个质心分配一个代码,这也是质心在生成的code_book矩阵中的行索引。

通过随机选择观测值来选择初始 k 个质心

因此生成的簇顺序是随机的。如果您想对此进行更多控制,可以指定

或者,传递一个 k × N 数组指定初始 k 个质心

在一般情况下我不推荐后者,因为不同的起始集群[可能]导致不同的集群,并且预定义的初始质心可能导致次优解决方案。

在您的简单情况下,生成的聚类始终是相同的(最佳)模聚类顺序:

>>> centroids, _ = kmeans(data,3,100)
>>> idx, _  = vq(data, centroids)
>>> centroids, idx
array([1, 7, 3]), array([0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1])
>>> centroids, _ = kmeans(data,3,100)
>>> idx, _  = vq(data, centroids)
>>> centroids, idx
array([3, 7, 1]), array([2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1])

【讨论】:

显示生成的集群顺序在运行之间是相同的,这一点提供了丰富的信息。谢谢!【参考方案2】:

这是因为如果您将整数作为 k_or_guess 参数传递,k 个初始质心会从输入观测值集中随机选择(这称为 Forgy method)。

来自the docs:

k_or_guess : int 或 ndarray

要生成的质心数。一种 代码被分配给每个质心,这也是该质心的行索引 生成的 code_book 矩阵中的质心。

最初的 k 个质心 通过从观察中随机选择观察来选择 矩阵。或者,通过 N 数组传递 k 指定初始 k 质心。

试着给它一个猜测:

kmeans(data,np.array([1,3,7]),100)

# (array([1, 3, 7]), 0.0)
# (array([1, 3, 7]), 0.0)
# (array([1, 3, 7]), 0.0)

【讨论】:

以上是关于scipy.cluster.kmeans 的结果不稳定的主要内容,如果未能解决你的问题,请参考以下文章

C语言中如何在除法事结果不保留小数 并将这个结果带入下次运算

sql 左连接查询出来的求各结果不准确,被乘了2倍

用EL和JSTL显示查询结果显示不出来

使用结果缓存和不使用结果缓存来计时我的 php 函数

同样的字符串,通过MD5出来的结果怎么不一样

jQuery UI 自动完成 - 输入与结果集不匹配时不显示结果