Javascript Clusterfck度量

Javascript Clusterfck度量,javascript,similarity,trigonometry,euclidean-distance,Javascript,Similarity,Trigonometry,Euclidean Distance,因此,我正在将一个旧的数据可视化转换为一个新的平台,我对他们的社区排序功能有点着迷。在原始代码中,作者似乎使用了凝聚聚类和余弦相似性计算器。我认为在Javascript中实现这一点的最佳方法是使用clusterfck生成一棵树,使用我的自定义余弦相似性函数作为度量。对于我传递的每一组数据,树几乎正确地排序。(但由于项目规范,“几乎”还不够好)。我检查了我的算法,看起来一切正常,但当我使用余弦相似性和欧几里德距离比较我的结果时,我得到了相同的排序结果 这可能是什么原因造成的?我想我可能传递了一些错

因此,我正在将一个旧的数据可视化转换为一个新的平台,我对他们的社区排序功能有点着迷。在原始代码中,作者似乎使用了凝聚聚类和余弦相似性计算器。我认为在Javascript中实现这一点的最佳方法是使用clusterfck生成一棵树,使用我的自定义余弦相似性函数作为度量。对于我传递的每一组数据,树几乎正确地排序。(但由于项目规范,“几乎”还不够好)。我检查了我的算法,看起来一切正常,但当我使用余弦相似性和欧几里德距离比较我的结果时,我得到了相同的排序结果

这可能是什么原因造成的?我想我可能传递了一些错误的信息,clusterfck将欧几里得作为默认值传递。下面是我的一段代码。有人能证实吗?(还有,有没有更简单的方法来计算余弦相似性?我认为JS没有内置的点积)

clusters=clusterfck.hcluster(relationArray,clusterfck.cosSim2,clusterfck.SINGLE_LINKAGE);
后序(簇);
函数后序(t){
i++;
如果(t==null){
返回;
}否则{
后序(t.left);
邮购(右);
if(t.left==null&&t.right==null){
社区arr.push(t.canonical[0]);
}否则{
返回;
}
}
}
函数cosSim2(arr1,arr2){
var d1=0,
d2=0,
cos=0;
对于(变量i=0;i
我想这个答复对你来说太晚了。 但如果其他人偶然发现了这一点:

问题是调用
clusterfck.hcluster
,参数
clusterfck.cosSim2
作为距离度量。但由于实际距离函数只是
cosSim2
,因此可以使用未定义的距离函数有效地调用
clusterfck.hcluster
,而clusterfck使用默认的距离函数,即“欧几里德”

另外请注意,您的函数确实度量向量之间的相似性,而不是它们之间的距离。也就是说:余弦相似性越大,向量就越相似(即,它们之间的角度越小)

但是
clusterfck.hcluster
需要一个真正的距离度量。也就是说,相反的假设是正确的:距离度量值越大,向量的距离越远(即,向量的相似性越低)

使用函数调用
clusterfck.hcluster
会产生这样的效果,即将最不相似的项聚集在一起

您可以很容易地从余弦相似性函数导出距离函数,如下所示:

function cosDist(arr1, arr2) {
    return 1 - cosSim2(arr1, arr2);
}
这个新函数
cosDist
的值范围为0到2,相同的向量的距离为0(如预期),最远的(即不同的)向量的距离为2

另请注意: Wikipedia的文章指出,这个cosDist在数学意义上不是一个合适的距离度量(三角形不等式在这里通常不成立),但根据我的经验,当使用这个函数进行层次聚类时,这在实践中不是一个问题。而且这种方式经常被使用。
尽管如此,还是有一种方法可以从余弦推导出真正的距离度量,这在维基百科的同一篇文章中也提到过:

这不是一个真正的答案,但我可以问一下你的cosSim算法是如何工作的吗?我也读了一些关于余弦的书,听起来像是我需要的东西,但我还不知道如何使用它。我目前的文本比较算法太慢了,我似乎无法加快它,除非我把它分成不同的部分,所有这些部分都可以优化。
function cosDist(arr1, arr2) {
    return 1 - cosSim2(arr1, arr2);
}