矢量的余弦相似度,< O(n ^ 2)复杂度

时间:2010-07-27 18:04:52

标签: java algorithm information-retrieval

浏览过此网站是否存在类似问题,我发现了这一点:http://math.nist.gov/javanumerics/jama/并且:http://sujitpal.blogspot.com/2008/09/ir-math-with-java-similarity-measures.html

然而,似乎这些运行在O(n ^ 2)。我一直在做一些文档聚类,并注意到处理甚至小文档集时这种复杂程度是不可行的。给定点积,我们只需要两个向量中包含的向量项,就可以将向量放在树中,从而计算出具有n log n复杂度的点积,其中n是唯一项中最低的唯一项数。 2个文件中的1个。

我错过了什么吗?有没有一个java库可以做到这一点?

感谢

4 个答案:

答案 0 :(得分:2)

如果将矢量元素存储在哈希表中,那么查找只是log n,不是吗?循环遍历较小文档中的所有键,看看它们是否存在于较大的文档中。?

答案 1 :(得分:2)

Hashmap很好,但可能需要大量内存。

如果您的向量存储为按键排序的键值对,则向量乘法可以在O(n)中完成:您只需要在两个向量上并行迭代(例如在合并排序算法中使用相同的迭代) 。乘法的伪代码:

i = 0
j = 0
result = 0
while i < length(vec1) && j < length(vec2):
  if vec1[i].key == vec2[j].key:
    result = result + vec1[i].value * vec2[j].value
  else if vec1[i].key < vec2[j].key:
    i = i + 1
  else
    j = j + 1

答案 2 :(得分:0)

如果您只想向有大小为n的集合中的每个项目推荐有限项目(例如m项目),则复杂度不必为n ^ 2,而是m * n。由于m是常数,因此复杂性是线性的。

您可以查看项目simbase https://github.com/guokr/simbase,它是一个矢量相似性nosql数据库。

Simbase使用以下概念:

  • 矢量集:一组矢量
  • 基础:向量的基础,一个向量集中的向量具有相同的基础
  • 建议:具有相同基础的两个向量集之间的单向二元关系

答案 3 :(得分:0)

如果您计划使用余弦相似度作为查找类似文档集群的方法,您可能需要考虑查看locality-sensitive hashing,这是一种基于哈希的方法,专门为此而设计。直观地说,LSH以一种很可能的方式散列向量,将相似的元素放入同一个桶中,将远处的元素放入不同的桶中。 LSH方案使用余弦相似度作为其基础距离,因此要查找群集,您可以使用LSH将内容放入桶中,然后仅计算同一桶中元素的成对距离。在最坏的情况下,这将是二次方(如果所有内容都在同一个桶中),但更有可能的是,你的工作量会大幅下降。

希望这有帮助!