计算数百万个文档之间的相似性度量

时间:2017-07-27 02:45:04

标签: python performance scalability similarity

我有数百万个文档(接近1亿),每个文档都有skillshobbiescertificationeducation等字段。我希望找到每个文档之间的相似性以及得分。

以下是数据示例。

skills  hobbies        certification    education
Java    fishing        PMP              MS
Python  reading novel  SCM              BS
C#      video game     PMP              B.Tech.
C++     fishing        PMP              MS

所以我想要的是第一行和所有其他行之间的相似性,第二行和所有其他行之间的相似性,依此类推。因此,应将每个文档与其他所有文档进行比较。得到相似度得分。

目的是我查询我的数据库以获取基于技能的人。除此之外,我现在想要的人虽然没有技能,但却与具有特定技能的人有所匹配。例如,如果我想获得具有JAVA技能的人的数据,第一行将再次显示,最后一行将显示为与第一行相同,基于相似度得分。

挑战:我的主要挑战是针对每个其他文档计算每个文档的一些相似性得分,如下面的伪代码所示。我怎么能更快地做到这一点?有没有任何不同的方法来执行此伪代码或是否有任何其他计算(硬件/算法)方法来更快地执行此操作?

document = all_document_in_db
For i in document:
   for j in document:
      if i != j :
        compute_similarity(i,j)

3 个答案:

答案 0 :(得分:3)

加快的一种方法是确保不以两种方式计算相似性。您当前的伪代码会将ij ji进行比较。而不是在整个文档上迭代j,迭代document[i+1:],即仅i之后的条目。这会将您compute_similarity的来电减少一半。

这种比较的最合适的数据结构是邻接矩阵。这将是n * n矩阵(n是您数据集中的成员数),其中matrix[i][j]是成员ij之间的相似度。您可以完全填充此矩阵,同时仅对j进行半迭代,只需同时为matrix[i][j]分配matrix[j][i]compute_similarity

除此之外,我想不出任何方法来加速这个过程;您需要至少n * (n - 1) / 2compute_similarity来电n * (n - 1) / 2。把它想象成握手问题;如果每个成员必须至少与其他成员进行一次比较('握手'),则下限为library(zoo) library(tseries) z <- zoo(rnorm(100), as.Date(1:100)) rollapplyr(z, 20, adf.test) 。但我欢迎其他投入!

答案 1 :(得分:2)

我认为你想要的是某种聚类算法。您可以将数据的每一行视为在多维空间中给出一个点。然后,您想要寻找附近的其他“点”。并非数据的所有维度都能产生良好的集群,因此您需要分析数据,以确定哪些维度对于生成集群具有重要意义,并通过映射到较低维度的数据来降低查找类似记录的复杂性。 scikit-learn有一些很好的用于维度分析和聚类的例程,以及一些帮助您确定应用于数据的例程的最佳文档。对于实际进行分析,我认为您可以通过AWS或Google AppEngine购买云时间。我相信两者都可以让您访问节点上可用的Anaconda(包括scikit-learn)的Hadoop集群。关于这些主题(群集,云计算)的详细说明超出了简单的答案。当你遇到另一个问题时卡住了。

答案 2 :(得分:1)

使用100万个文档,您需要500,000个比较。不,你不能用Python做到这一点。

最可行的解决方案(除了使用超级计算机)是用C / C ++计算相似性得分。

  1. 阅读整个数据库并列举每项技能,爱好,认证和教育。此操作需要一个线性时间,假设您的索引查找是“智能”并且需要一段时间。
  2. 创建一个包含四个数字字段的C / C ++ struct:技能,爱好,认证和教育。
  3. 运行嵌套循环,逐字减去所有其他struct的{​​{1}},并使用位级算术来评估相似度。
  4. 将结果保存到文件中,并在必要时将其提供给Python程序。