如何优化发现相似之处?

时间:2014-04-16 17:04:39

标签: algorithm optimization cosine-similarity

我有一组30 000个由浮点数向量表示的文档。所有载体都有100个元素。通过在矢量之间使用余弦测量来比较它们,我可以找到两个文档的相似性。问题是找到最相似的文件需要花费很多时间。是否有任何算法可以帮助我加快这个速度?

修改

现在,我的代码只计算第一个和所有其他向量之间的余弦相似度。大约需要3秒钟。我想加快速度;)算法不一定要准确,但应该给完全搜索提供类似的结果。

每个向量的元素总和等于1.

start = time.time()

first = allVectors[0]
for vec in allVectors[1:]:
    cosine_measure(vec[1:], first[1:])

print str(time.time() - start)

3 个答案:

答案 0 :(得分:3)

locality sensitive hashing(LHS)会有帮助吗? 在LHS的情况下,散列函数以您选择的概率将相似的项目映射到彼此附近。据称它特别适用于高维相似性搜索/最近邻搜索/近似重复检测,并且在我看来,这正是您想要实现的目标。

另见How to understand Locality Sensitive Hashing?

答案 1 :(得分:2)

有一篇论文How to Approximate the Inner-product: Fast Dynamic Algorithms for Euclidean Similarity描述了如何快速逼近内积。如果这不够好或不够快,我建议建立一个包含所有文档的索引。类似于quadtree但基于geodesic grid的结构可能效果很好,请参阅Indexing the Sphere with the Hierarchical Triangular Mesh

更新:我完全忘记你正在处理100个维度。对高维数据建立索引为notoriously hard,我不确定对一个球体进行索引的概率是否会推广到100维。

答案 2 :(得分:2)

如果向量归一化,则余弦与欧几里德距离相关:||a - b||² = (a - b)² = ||a||² + ||b||² - 2 ||a|| ||b|| cos(t) = 1 + 1 - 2 cos(t)。所以你可以用欧几里得最近邻居来重铸你的问题。

一种很好的方法,如果是kD树,一种推广二进制搜索(http://en.wikipedia.org/wiki/K-d_tree)的空间数据结构。无论如何,kD树在高维度(你的情况)中是低效的,所以首选所谓的best-bin-first-search(http://en.wikipedia.org/wiki/Best-bin-first_search)。