1

古いデータ ビジュアライゼーションを新しいプラットフォームに変換していますが、コミュニティの並べ替え機能に少し固執しています。元のコードでは、作成者がコサイン類似度計算機で凝集クラスタリングを使用しているようです。Javascript でこれにアプローチする最善の方法は、カスタム コサイン類似度関数をメトリックとして使用して、clusterfck でツリーを作成することだと考えました。ツリーは、渡すデータのセットごとにほぼ正しくソートされます。(ただし、プロジェクトの仕様上、「ほぼ」では十分ではありません)。アルゴリズムをチェックしたところ、すべてが正しく見えましたが、コサイン類似度とユークリッド距離を使用して結果を比較すると、同じ並べ替え結果が得られます。

何が原因でしょうか? 何かを間違って渡している可能性があり、clusterfck はデフォルトで euclidean を渡していると思います。以下は私のコードの一部です。誰かが確認できますか?(また、コサイン類似度を計算する簡単な方法はありますか? JS にはドット積が組み込まれているとは思いません)。

clusters = clusterfck.hcluster(relationArray, clusterfck.cosSim2, clusterfck.SINGLE_LINKAGE);
postOrder(clusters);
function postOrder(t) {
i++;
if (t == null) {
    return;
} else {
    postOrder(t.left);
    postOrder(t.right);
    if (t.left == null && t.right == null) {
        communityArr.push(t.canonical[0]);
    } else {
        return;
    }
}
}

function cosSim2(arr1, arr2) {
var d1 = 0,
    d2 = 0,
    cos = 0;
for(var i = 0; i < arr1.length; i++) {
    d1 += Math.pow(arr1[i], 2);
}

for(var j = 0; j < arr2.length; j++) {
    d2 += Math.pow(arr2[j], 2);
}

d1 = Math.sqrt(d1);
d2 = Math.sqrt(d2);

for(var j = 0; j < arr2.length; j++) {
    if (arr1[j] == null) {
        cos += 0;
    } else {
        cos += arr1[j] * arr2[j];
    }
}
var cosSimilarity = cos / (d1 * d2);
return cosSimilarity;
}
4

1 に答える 1

3

I suppose this response is too late for you. But in case somebody else stumbles across this:

The problem is that you call clusterfck.hcluster with the parameter clusterfck.cosSim2 as your distance measure. But as your real distance function is simply cosSim2, you effectively call clusterfck.hcluster with an undefined distance function, and clusterfck resorts to the default distance function which is "euclidean"...

Also please note that your function indeed measures the similarity between vectors, not their distance. That is: The greater the cosine similarity, the more similar the vectors (i.e., the smaller the angle between them).

But clusterfck.hcluster expects a genuine distance measure. That is, the opposite is supposed to be true: The greater the value of the distance measure, the more distant the vectors (i.e., the less similar the vectors).

Calling clusterfck.hcluster with your function will have the effect, that the least similar items are clustered together.

You can easily derive a distance function from your cosine similarity function as follows:

function cosDist(arr1, arr2) {
    return 1 - cosSim2(arr1, arr2);
}

This new function cosDist has values ranging from 0 to 2, identical vectors will have the distance 0 (as expected) and the most distant (i.e. dissimilar) ones will have the distance 2.

And another note: The Wikipedia article http://en.wikipedia.org/wiki/Cosine_similarity points out that this cosDist is not a proper distance metric in the mathematical sense (the triangle inequality does not generally hold here) but from my experience this is not a problem in practice when using this function for hierarchical clustering. And it is used that way often. Nevertheless there is a way to derive a genuine distance metric from cosine, also mentioned in the same Wikipedia article: https://en.wikipedia.org/wiki/Cosine_similarity#Angular_distance_and_similarity

于 2013-12-11T09:11:15.570 に答える