没有循环的Python Spacy相似性



我试图允许用户输入一个搜索词来查找与他们的搜索匹配的前5篇文章。我正在比较各种方法(gensim-word2vec、doc2vec和最近邻居等(的结果/性能。

我已经成功地创建了代码来利用Spacy中的标准相似性函数,然而,当它在一个庞大的文档列表中循环并将相似性分数附加到pandas-df时,它花费了太长时间。

有没有一种方法可以在没有循环和pandas附加的情况下返回前5个最相似的文档?原因是,与其他方法相比,此方法返回最明智的前5个文档(单词嵌入的乐趣!(

#load relevant libraries
import pandas as pd
import numpy as np
import spacy
#load spacy model
nlp=spacy.load('Z:\en_core_web_lg-2.0.0')
#
#Get Doc Corpus
dfCorpus = pd.read_csv('z:DocumentCorpus.csv', delimiter=',')
##get top 5 using spacy similarity function 
SearchStringCosine = nlp(input('Enter search term:'))
computed_similarities = []
for i in dfCorpus.CorpusInput_Unqiue:
doc=nlp(i)
computed_similarities.append((i, SearchStringCosine.similarity(doc)))
computed_similarities = sorted(computed_similarities, key=lambda item: -item[1])
computed_similarities = pd.DataFrame(computed_similarities,columns=   ['CorpusInput_Unique','Score'])
print(computed_similarities[:5]) 

余弦相似性(Spacy中的.similarity函数(是一个简单的线性代数运算,可以有效地并行化。您需要计算cos(x,y) = x⋅y / (|x||y|),其中是内积运算符。

对于给定的y,你可以做的不是在不同的x上循环,而是让x是一个矩阵,并执行一个简单的向量矩阵乘积。让x是文档向量的矩阵(维度Nx300-N是文档的数量,300是特征的数量(,y是比较向量:

vector_norms = np.array([np.sqrt(np.sum(np.square(v))) for v in X])
X = (X.T / vector_norms).T
similarities = np.matmul(X, y) 
# ... perform index sorting as usual

如果需要更高的效率,这可以写在GPU加速的线性代数库上。

对于其他正在寻找解决方案的人来说,我发现最好的方法是在应用spacy vector nlp((后对我的文件进行pickle,然后在引用doc_list时循环几乎立即工作!

dfCorpusDescr = dfCorpus.fieldname
doc_list={i: nlp(i) for i in dfCorpus}
with open("filename.pickle", 'wb') as pfile:
pickle.dump(doc_list, pfile, protocol=pickle.HIGHEST_PROTOCOL)

最新更新