python - scikit kmeans 不准确的成本\惯性

标签 python numpy machine-learning scikit-learn k-means

我想获得 k 均值成本(scikit kmeans 中的惯性)。 只是提醒一下:

成本是每个点到最近簇的距离平方和。

我在 scikit('inertia') 的成本计算之间发现了一个奇怪的差异,
以及我自己计算成本的简单方法

请参阅以下示例:

p = np.random.rand(1000000,2)
from sklearn.cluster import KMeans
a = KMeans(n_clusters=3).fit(p)
print a.inertia_ , "****"

means = a.cluster_centers_
s = 0
for x in p:
    best = float("inf")
    for y in means:
        if np.linalg.norm(x-y)**2 < best:
            best = np.linalg.norm(x-y)**2
    s += best
print s, "*****"

我的运行输出是:

66178.4232156 ****
66173.7928716 *****

在我自己的数据集上,结果更显着(20% 的差异)。
这是 scikit 实现中的错误吗?

最佳答案

首先 - 这似乎不是一个错误(但肯定是丑陋的不一致)。这是为什么?您需要仔细研究代码实际在做什么。出于此一般目的,它从 _k_means.pyx

调用 cython 代码

(第 577-578 行)

    inertia = _k_means._assign_labels_array(
        X, x_squared_norms, centers, labels, distances=distances)

它所做的本质上就是你的代码,但是......在C中使用 double 。所以也许这只是一个数字问题?让我们测试您的代码,但现在具有清晰的集群结构(因此没有可能分配给许多中心的点 - 取决于数值精度)。

import numpy as np
from sklearn.metrics import euclidean_distances

p = np.random.rand(1000000,2)
p[:p.shape[0]/2, :] += 100 #I move half of points far away

from sklearn.cluster import KMeans
a = KMeans(n_clusters=2).fit(p) #changed to two clusters
print a.inertia_ , "****"

means = a.cluster_centers_
s = 0
for x in p:
    best = float("inf")
    for y in means:
        d = (x-y).T.dot(x-y)
        if d < best:
            best = d
    s += best
print s, "*****"

结果

166805.190832 ****
166805.190946 *****

有道理。因此,问题在于“边界附近”存在样本,这些样本可能根据算术精度分配给多个簇。不幸的是,我无法准确追踪差异来自何处。

有趣的事情是,实际上存在不一致,因为 inertia_ 字段填充了 Cython 代码,.score 调用 NumPy 1。因此,如果你打电话

print -a.score(p)

您将准确地得到您的惯性

关于python - scikit kmeans 不准确的成本\惯性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34755599/

相关文章:

python - 我如何对这个 Flask 应用程序进行单元测试?

python - 在 Python 中将名称列表拆分为字母字典

python - 如何检查连续相同的值和值的计数同时出现 pandas

scala - 从文本中高效提取 WikiData 实体

machine-learning - 机器学习与大数据

python - 用python加密/解密文件

python - Conda 骨架 pypi 因 pmdarima 而失败——AttributeError numpy disutils

numpy - 为什么矩阵乘法会根据它们的分组方式给出不同的结果?

python - 使用 matplotlib 和 np.linalg 绘制协方差矩阵的特征向量

tensorflow - tensorflow 中的reduce命令有什么用?