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



我有数百万个文档(接近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)

加快速度的一种方法是确保不会同时计算两种方式的相似性。 您当前的伪代码会将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) / 2电话来compute_similarity。把它想象成一个握手问题;如果每个成员必须至少与其他成员进行比较("握手"(,那么下限是n * (n - 1) / 2。但我欢迎其他意见!

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

对于 100 亿个文档,您需要 500,000 亿次比较。不,你不能在 Python 中这样做。

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

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

实际上,我相信您需要计算文档的矩阵表示,并且只调用一次compute_similarity。这将在 X 矩阵中的所有特征行对上调用算法的矢量化实现(假设 sci-kit 学习的第一个参数(。你会对性能感到惊讶。如果在一次调用中计算此值的尝试超过了您的 RAM,您可以尝试分块。

最新更新