如何有效地计算数百万个字符串之间的余弦相似度

Posted

技术标签:

【中文标题】如何有效地计算数百万个字符串之间的余弦相似度【英文标题】:How to efficiently compute the cosine similarity between millions of strings [closed] 【发布时间】:2013-02-09 02:26:48 【问题描述】:

我需要计算列表中字符串之间的余弦相似度。例如,我有一个超过 1000 万个字符串的列表,每个字符串都必须确定其自身与列表中每个其他字符串之间的相似性。我可以用来高效快速地完成此类任务的最佳算法是什么?分治算法是否适用?

编辑

我想确定哪些字符串与给定字符串最相似,并且能够拥有与相似度相关的度量/分数。我认为我想做的事情与最初不知道集群数量的集群一致。

【问题讨论】:

根据您的问题的定义,余弦相似度计算的执行复杂度为 O(n²)。 @Xion345 是的,这么大的数据可以接受吗?我不认为是 您必须为此使用动态编程。见this链接 1000 万乘以 1000 万 = 1000 亿。如果余弦相似度的每次应用需要 50 微秒,那么您得到的最短时间约为 5000 万秒,也就是大约一年半。如果余弦相似度只需要 1 纳秒,您仍然需要 1000 秒。因此,即使使用动态编程,您也无法做太多事情。您应该找到一种方法来避免所有这些余弦相似度计算。 @Xion345 好吧,如果你很聪明,你可以节省计算 0*something。如果你利用稀疏性,它只是非稀疏部分的二次方。哪个更好。 【参考方案1】:

使用转置矩阵。这就是 Mahout 在 Hadoop 上为快速完成此类任务(或仅使用 Mahout)所做的。

本质上,以幼稚的方式计算余弦相似度是不好的。因为你最终会计算很多 0 * 的东西。相反,你最好在中工作,并且把所有的0都留在那里

【讨论】:

【参考方案2】:

你可以试试SimString。

它是一个用于近似字符串匹配的 C++ 库(带有 Python 或 Ruby 绑定)。

它声称可以在 1 毫秒内为包含 1300 万个字符串的数据库找到具有高余弦相似度的字符串。

所使用的算法描述为here 基于倒排列表的修剪。

【讨论】:

以上是关于如何有效地计算数百万个字符串之间的余弦相似度的主要内容,如果未能解决你的问题,请参考以下文章

R语言使用lsa包计算余弦相似度(Cosine Similarity)实战:两个向量的余弦相似度矩阵的余弦相度

如何使用python通过余弦相似度有效地检索前K相似文档?

余弦计算相似度理解以及计算

如何计算两个向量的余弦相似度?

Java根据余弦定理计算文本相似度

余弦相似度的应用