Python 没有循环的 Spacy 相似性?

Python Spacy similarity without loop?

我正在尝试让用户输入搜索词以查找与他们的搜索匹配的前 5 篇文章。我正在比较各种方法(gensim word2vec、doc2vec、最近邻等)的结果/性能。

我已经成功地创建了代码来利用 Spacy 中的标准相似度函数,但是,当它循环遍历大量文档列表并将相似度分数附加到 pandas df 时,它花费的时间太长。

有没有一种方法可以 return 最相似的前 5 个文档而不使用循环和 pandas 追加?原因是这个方法 return 与其他方法相比最明智的前 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 我的文件 post,然后在引用 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)