我有数百万个文档(接近1亿),每个文档都有skills
,hobbies
,certification
和education
等字段。我希望找到每个文档之间的相似性以及得分。
以下是数据示例。
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)
答案 0 :(得分:3)
加快的一种方法是确保不以两种方式计算相似性。您当前的伪代码会将i
与j
和 j
与i
进行比较。而不是在整个文档上迭代j
,迭代document[i+1:]
,即仅i
之后的条目。这会将您compute_similarity
的来电减少一半。
这种比较的最合适的数据结构是邻接矩阵。这将是n * n
矩阵(n
是您数据集中的成员数),其中matrix[i][j]
是成员i
和j
之间的相似度。您可以完全填充此矩阵,同时仅对j
进行半迭代,只需同时为matrix[i][j]
分配matrix[j][i]
和compute_similarity
。
除此之外,我想不出任何方法来加速这个过程;您需要至少n * (n - 1) / 2
次compute_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 ++计算相似性得分。
struct
:技能,爱好,认证和教育。struct
的{{1}},并使用位级算术来评估相似度。