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がポイントが「相対的な大きさが小さく」、「事実上ゼロである」と判断する条件は何ですか?

Python で処理するゴールド スタンダードと結果を比較する必要があるため、データを Matlab に渡す前に、Python を使用してデータセットからこれらすべてのポイントを削除したいと考えています。

前もって感謝します!

編集回答

正解は以下に示されていますが、誰かが Google でこの質問を見つけた場合に備えて、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

だからあなたのテストがあります。ご覧のとおり、重要なのは相対的なサイズなので、すべてに 1 を追加すると事態が悪化するだけです (max(Xnorm)も大きくなっています)。適切な修正は、すべてのデータを定数でスケーリングすることです。

于 2012-05-09T02:49:21.663 に答える
0

他の質問では、データがスカラーのように見えました。入力ベクトルに 1 つのフィーチャ/次元しかない場合、それらの間の余弦距離は常に未定義 (またはゼロ) になります。これは、定義により、それらが同じ方向 (単一の軸に沿って) を指しているためです。余弦測度は、2 つのベクトル間の角度を示します。これは、ベクトルが異なる方向 (つまり、次元 > 1) を指すことができる場合にのみゼロ以外になる可能性があります。

于 2012-05-09T06:00:15.717 に答える