【问题标题】:Python Spacy similarity without loop?没有循环的Python Spacy相似性?
【发布时间】:2019-01-10 03:01:11
【问题描述】:

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

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

有没有一种方法可以在没有循环和熊猫附加的情况下返回前 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]) 

【问题讨论】:

    标签: python python-3.x machine-learning similarity spacy


    【解决方案1】:

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

    您可以将x 设为矩阵并执行简单的向量矩阵乘积,而不是为给定的y 循环遍历不同的xs。让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 加速的线性代数库上。

    【讨论】:

    • 哇,感谢您的及时回复!我会试一试,让你知道我过得怎么样。再次感谢。
    • 我从来没有设法让它工作。尝试了很多变体,但尽管对我的语料库和搜索词进行了规范化,但始终无法使相似性调用起作用。
    • 到底是什么问题?
    • 在我可以找到的最新版本的代码中(串行删除不起作用的内容!)我收到错误“'list' object has no attribute 'T'”。文档语料库 (X) 是一个包含词向量的列表。 vector_norms = np.array([np.sqrt(np.sum(np.square(v))) for v in dfCorpusWV]) X = (dfCorpusWV.T / vector_norms).T
    • X = (X.T / vector_norms).T 上面的T是什么? X 的属性?然而它也被用作一个单独的乘数?
    【解决方案2】:

    对于其他正在寻找解决方案的人,我发现最好的方法是在应用 spacy 矢量 nlp() 后腌制我的文件,然后在引用 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)
    

    【讨论】:

      猜你喜欢
      • 2019-04-26
      • 1970-01-01
      • 2018-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-25
      相关资源
      最近更新 更多