Spacy相似度警告: "根据空向量评估Doc.similarity。"

8

我正在尝试使用常见问题解答数据集进行数据增强。我通过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 = [您是否有纸质或其他书面说明来介绍您模型的详细信息?BERT 代码来源是哪里?一个句子向量有多大?]

我需要在循环中检查 token,还要检查 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))
2个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
13

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就可以解决。 (未经测试。)

(请参见源代码


顺便说一句,similarity()可能会导致一些CPU负载,所以最好存储在变量中,而不是像您当前所做的那样计算三次。 (有些人可能会认为这是过早的优化,但我认为这也可以使代码更易读。)


1
谢谢您的回答,但我仍然遇到错误。我需要检查token。我已经编辑了我的帖子,并使用您的示例来显示错误。 - Jonor
@DarrenCook 如何抑制错误。我也遇到了同样的问题。建议在哪里进行更改。我能找到代码errors.py(链接在此处:github.com/explosion/spaCy/blob/…),但不确定在哪里设置“SPACY_WARNING_IGNORE=W008”。我正在使用window 10,IDE:spyder,Spacy 2.2.5。如果您能告诉我如何在哪里设置环境变量“SPACY_WARNING_IGNORE=W008”,那将是非常好的。 - Ridhima Kumar
2
@RidhimaKumar 请参阅https://docs.python.org/3/library/os.html#os.environ。我*认为*在导入spacy之前您需要这样做。或者,要在脚本外设置它,我谷歌搜索“windows python如何设置环境变量”,并找到了各种答案。 - Darren Cook
1
@RidhimaKumar 我在谷歌上搜索到的最热门结果之一是这个StackOverflow页面:https://dev59.com/DW025IYBdhLWcg3wfmLw(这也是我找到那个手册页面的原因 :-))(附注:如果不清楚,那么我认为所有操作都可以在Python脚本内完成。尽管如此,我个人并没有尝试过。) - Darren Cook
@DarrenCook 谢谢,我明白了。 - Ridhima Kumar
显示剩余2条评论

1
我已经通过在运行文件中使用以下代码设置环境变量来抑制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)

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,