所以我正在将旧的数据可视化转换为新平台,我有点卡在他们的社区排序功能上。在原始代码中,作者似乎使用了带有余弦相似度计算器的凝聚聚类。我认为在 Javascript 中解决此问题的最佳方法是使用我的自定义余弦相似度函数作为指标,使用 clusterfck 制作一棵树。对于我传递的每组数据,树几乎正确地排序。(但由于项目规范,“几乎”还不够好)。我检查了我的算法,一切看起来都正确,但是当我使用余弦相似度和欧几里得距离比较我的结果时,我得到了相同的排序结果。
这可能是什么原因造成的?我想我可能错误地传递了一些东西,而 clusterfck 将欧几里得作为默认值传递。下面是我的一段代码。有人可以验证吗?(另外,有没有更简单的方法来计算余弦相似度?我认为 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;
}