Spacy 相似性警告:“基于空向量评估 Doc.similarity。”

Posted

技术标签:

【中文标题】Spacy 相似性警告:“基于空向量评估 Doc.similarity。”【英文标题】:Spacy similarity warning : "Evaluating Doc.similarity based on empty vectors." 【发布时间】:2019-09-19 03:00:38 【问题描述】:

我正在尝试使用常见问题解答数据集进行数据增强。我用Wordnet检查与Spacy的相似性,用最相似的词来改变单词,特别是名词。我使用多个 for 循环来遍历我的数据集。

import spacy
import nltk
from nltk.corpus import wordnet as wn
import pandas as pd

nlp = spacy.load('en_core_web_md')
nltk.download('wordnet')
questions = pd.read_csv("FAQ.csv")

list_questions = []
for question in questions.values:
    list_questions.append(nlp(question[0]))

for question in list_questions: 
    for token in question:
        treshold = 0.5
        if token.pos_ == 'NOUN':
            wordnet_syn = wn.synsets(str(token), pos=wn.NOUN)  
            for syn in wordnet_syn:
                for lemma in syn.lemmas():
                    similar_word = nlp(lemma.name())
                    if similar_word.similarity(token) != 1. and similar_word.similarity(token) > treshold:
                        good_word = similar_word
                        treshold = token.similarity(similar_word)

但是,以下警告被打印了好几次,我不明白为什么:

UserWarning:[W008] 基于空向量评估 Doc.similarity。

是我的similar_word.similarity(token) 造成了问题,但我不明白为什么。 我的 list_questions 的形式是:

list_questions = [Do you have a paper or other written explanation to introduce your model's details?, Where is the BERT code come from?, How large is a sentence vector?]

我需要检查令牌以及循环中的similar_word,例如,我仍然在这里得到错误:

tokens = nlp(u'dog cat unknownword')
similar_word = nlp(u'rabbit')

if(similar_word):
    for token in tokens:
        if (token):
            print(token.text, similar_word.similarity(token))

【问题讨论】:

【参考方案1】:

similar_word 不是有效的spacy 文档时,您会收到该错误消息。例如。这是一个最小的可重现示例:

import spacy

nlp = spacy.load('en_core_web_md')  # make sure to use larger model!
tokens = nlp(u'dog cat')
#similar_word = nlp(u'rabbit')
similar_word = nlp(u'')

for token in tokens:
  print(token.text, similar_word.similarity(token))

如果您将'' 更改为'rabbit',它可以正常工作。 (与狗相比,猫与兔子的相似性显然只是一小部分!)

更新:正如您所指出的,未知词也会触发警告;它们将是有效的 spacy 对象,但没有任何词向量。)

因此,一种解决方法是在调用 similarity() 之前检查 similar_word 是否有效,包括具有有效的词向量:

import spacy

nlp = spacy.load('en_core_web_md')  # make sure to use larger model!
tokens = nlp(u'dog cat')
similar_word = nlp(u'')

if(similar_word and similar_word.vector_norm):
  for token in tokens:
    if(token and token.vector_norm):
      print(token.text, similar_word.similarity(token))

替代方法:

您可以隐藏特定的警告。是W008。我相信在运行脚本之前设置一个环境变量SPACY_WARNING_IGNORE=W008 会做到这一点。 (未测试。)

(见source code)


顺便说一句,similarity() 可能会导致一些 CPU 负载,因此值得将其存储在一个变量中,而不是像现在这样计算三次。 (有些人可能会认为这是过早的优化,但我认为它也可能使代码更具可读性。)

【讨论】:

感谢您的回答,但我仍然收到错误消息。我还需要检查token。我用你的例子编辑了我的帖子,向你展示了错误。 @Jonor 你说得对(我试过了,但我用的废话似乎确实存在于 web_md 模型中!!)在研究了源代码后(github.com/explosion/spaCy/blob/…)我更新了我的回答。 @DarrenCook 如何抑制错误。我也面临同样的问题。建议在哪里进行更改。我可以找到代码errors.py(链接在这里:github.com/explosion/spaCy/blob/...)但不确定在哪里设置“SPACY_WARNING_IGNORE=W008”。我正在使用窗口 10,IDE:spyder,Spacy 2.2.5。如果您能告诉我如何以及在何处设置环境变量“SPACY_WARNING_IGNORE=W008”,那就太好了 @RidhimaKumar 请参阅docs.python.org/3/library/os.html#os.environ 我认为您需要在导入 spacy 之前执行此操作。或者,为了在脚本之外设置它,我搜索了“windows python 如何设置环境变量”并找到了各种答案。 @RidhimaKumar 我得到的 Google 最热门的点击之一是这个 *** 页面:***.com/questions/5971312/…(这就是我进入该手册页的原因 :-))(PS 如果不清楚,那么是的,我认为这一切都可以从 python 脚本中完成。不过,我没有亲自尝试过。)【参考方案2】:

我通过在运行文件中使用此代码设置环境变量来抑制 W008 警告。

import os
app = Flask(__name__)

app.config['SPACY_WARNING_IGNORE'] = "W008"
os.environ["SPACY_WARNING_IGNORE"] = "W008"

if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000)

【讨论】:

从 spacy 2.3 开始,您应该使用 python 中的标准警告模块来过滤掉警告:warnings.filterwarnings("ignore", message=r"\[W008\]", category=UserWarning)。如迁移指南中所述:spacy.io/usage/v2-3

以上是关于Spacy 相似性警告:“基于空向量评估 Doc.similarity。”的主要内容,如果未能解决你的问题,请参考以下文章

迭代spacy标记

存储和加载包含词向量的 spaCy 文档

句子相似性模型没有捕捉到相反的句子

如何抓取语义相似的句子

python中的相似词分组

Android 中的 Spacy 版本错误使用 Chaquopy 和 nlp = spacy.load("en_core_web_sm") 错误