2

我在一个大型数据集上运行 kmeans,我总是收到以下错误:

Error using kmeans (line 145)
Some points have small relative magnitudes, making them effectively zero.
Either remove those points, or choose a distance other than 'cosine'.

Error in runkmeans (line 7)
[L, C]=kmeans(data, 10, 'Distance', 'cosine', 'EmptyAction', 'drop')

我的问题是,即使我向所有向量添加 1,我仍然会收到此错误。我希望它会通过,但显然仍然有太多的零(这就是导致它的原因,对吗?)。

我的问题是:什么条件使 Matlab 决定一个点具有“较小的相对大小”和“实际上为零”?

在将数据交给 Matlab 之前,我想使用 python 从我的数据集中删除所有这些点,因为我需要将我的结果与我在 python 中处理的黄金标准进行比较。

提前致谢!

编辑答案

下面给出了正确的答案,但如果有人通过谷歌找到这个问题,下面是如何从 python 中的矩阵中删除“有效零向量”。每行 (!) 都是一个数据点,因此如果您正在运行 kmeans,您需要在 python 或 Matlab 中转置:

def getxnorm(data):
        return np.sqrt(np.sum(data ** 2, axis=1))

def remove_zero_vector(data, startxnorm, excluded=[]):
        eps = 2.2204e-016
        xnorm = getxnorm(data)
        if np.min(xnorm) <= (eps * np.max(xnorm)):
                local_index=np.transpose(np.where(xnorm == np.min(xnorm)))[0][0]
                global_index=np.transpose(np.where(startxnorm == np.min(xnorm)))[0][0]
                data=np.delete(data, local_index, 0) # data with zero vector removed
                excluded.append(global_index) # add global index to list of excluded vectors
                return remove_zero_vector(data, startxnorm, excluded)
        else:
                return (data, excluded)

我敢肯定有一种更科学的方式来做到这一点,但它会做的:-)

4

2 回答 2

3

如果您正在使用这个 kmeans,那么引发错误的相关代码是:

case 'cosine'
    Xnorm = sqrt(sum(X.^2, 2));
    if any(min(Xnorm) <= eps * max(Xnorm))
        error(['Some points have small relative magnitudes, making them ', ...
               'effectively zero.\nEither remove those points, or choose a ', ...
               'distance other than ''cosine''.'], []);
    end

所以这是你的测试。如您所见,重要的是相对大小,因此在所有内容中添加一个只会使事情变得更糟(max(Xnorm)也变得更大)。一个好的解决方法可能是按常数缩放所有数据。

于 2012-05-09T02:49:21.663 回答
0

在您的另一个问题中,您的数据看起来是标量的。如果您的输入向量只有一个特征/维度,则它们之间的余弦距离将始终未定义(或为零),因为根据定义它们指向相同的方向(沿单轴)。余弦测量给出了两个向量之间的角度,如果向量可以指向不同的方向(即维度> 1),该角度只能是非零的。

于 2012-05-09T06:00:15.717 回答