代码之家  ›  专栏  ›  技术社区  ›  Tom

如何在Python中使用spacy加速计算句子相似度?

  •  0
  • Tom  · 技术社区  · 2 年前

    我有以下代码,它包含2个句子并返回相似性:

    nlp = spacy.load("en_core_web_md/en_core_web_md-3.2.0")
    
    def get_categories_nlp_sim(cat_1, cat_2):
    
        if (cat_1 != cat_1) or (cat_2 != cat_2):
            s = np.nan
        else:
            doc1 = nlp(cat_1)
            doc2 = nlp(cat_2)
    
            s = doc1.similarity(doc2)
    
        return s
    

    因此,这似乎给出了合理的结果,但当在大约1M行的for循环中使用它时,它的使用速度太慢了。

    关于如何加快速度有什么想法吗?或者另一个NLP库可以更快地完成同样的事情?

    谢谢

    0 回复  |  直到 2 年前
        1
  •  3
  •   ewz93    2 年前

    如果你真的有1米长的行,并将它们成对进行比较,你会得到天文数字的比较。SpaCys nlp() 除了相似性所需的东西之外,还做了很多事情。

    什么SpaCys similarity() 所做的就是使用处理后的文档向量并计算余弦相似度(文档向量=单词向量的平均值),检查 source code

    因此,对你来说,复制这么多对的相似性可能最有效的方法是使用Gensims预训练的word2vec模型来获得整个语料库中每个唯一令牌的语义令牌表示向量,然后对每一行计算其中标记的向量的平均值,然后一旦你有了这1m的文档向量作为numpy数组,你就可以使用numpy或scipy来计算余弦相似性,这比纯Python快得多。

    也可以看看这个与你的问题类似的帖子: Efficient way for Computing the Similarity of Multiple Documents using Spacy

    我不确定你的代码中的主要目标是什么,但我很确定,计算每个成对的相似性不是必需的,或者至少不是实现该目标的最佳方式,所以请分享更多关于你需要这种方法的上下文。

        2
  •  3
  •   Tom    2 年前

    在浏览了答案和其他相关线索之后 Efficient way for Computing the Similarity of Multiple Documents using Spacy ,我设法大大加快了速度。

    我现在使用以下代码:

    nlp = spacy.load(en_core_web_md, exclude=["tagger", "parser", "senter", "attribute_ruler", "lemmatizer", "ner"])
    
    processed_docs_1 = nlp.pipe(texts_1)
    processed_docs_2 = nlp.pipe(texts_2)
    
    for _ in range(len(texts_1)):
    
        doc_1 = next(processed_docs_1)
        doc_2 = next(processed_docs_2)
    
        s = doc_1.similarity(doc_2)
    

    其中texts_1和texts_2具有相同的长度,由要比较的对组成(例如。 texts_1[i] 具有 texts_2[i] )。

    在空间负载中添加“排除”导致大约2倍的速度提高。 使用 nlp.pipe 与呼叫相反 nlp 在环路内,速度提高了约10倍。综合起来,我的速度提高了约20倍。