预初始化spaCy Doc对象上运行依存句法解析器的异常问题咨询
错误原因
- spaCy预训练的依存句法解析器依赖
token.pos_(粗词性标签)作为输入特征,你手动构造Doc时仅传入了tags参数(对应细词性标签token.tag_),没有对应的粗词性标签。 - 你构造管道时排除了
attribute_ruler组件,这个组件的核心作用就是自动将细词性标签映射为粗词性标签,缺少该组件的情况下parser无法获取到需要的输入特征,导致解析结果完全异常。 - 你没有为Doc显式设置句子边界标记
sent_starts,parser无法正确识别句子边界,也会导致解析结果异常。 - 你之前加入spaCy的tagger得到全NN标签的原因是:spaCy的管道组件默认会覆盖你手动设置的标签属性,你如果要使用自有NLP系统输出的标签,不需要在管道中加入spaCy的tagger。
解决方案
方案1:使用自有NLP系统输出的标签
保留你已有的tokenizer、tagger、NER结果,仅调用spaCy的parser,代码示例如下:
import spacy from spacy.tokens import Doc # 加载模型时仅排除不需要的组件,保留attribute_ruler和parser nlp = spacy.load("en_core_web_sm", exclude=["lemmatizer", "ner", "tagger"]) # 填入自有NLP系统的输出结果 words = ["The","heating_temperature", "was", "found", "to", "be", "500", "C"] spaces = [True,True,True,True,True,True,True,False] tags = ["DT","NN","VBD","VBN","TO","VB","CD","NN"] ents = ["O","I-PARAMETER","O","O","O","O","I-VALUE","O"] # 补充设置句子边界,第一个词为句子开头 sent_starts = [True] + [None]*(len(words)-1) # 构造Doc对象 doc = Doc(nlp.vocab, words=words, spaces=spaces, tags=tags, ents=ents, sent_starts=sent_starts) # 先运行attribute_ruler生成parser需要的粗词性标签 doc = nlp.get_pipe("attribute_ruler")(doc) # 运行依存解析 doc = nlp.get_pipe("parser")(doc) # 输出解析结果验证 for token in doc: print(token.text, token.tag_, token.pos_, token.dep_, token.head.text)
方案2:使用spaCy自带的tagger
如果你不需要使用自有标签,直接用spaCy的tagger生成解析需要的词性标签,代码示例如下:
import spacy from spacy.tokens import Doc # 加载模型时仅排除不需要的组件 nlp = spacy.load("en_core_web_sm", exclude=["lemmatizer", "ner"]) words = ["The","heating_temperature", "was", "found", "to", "be", "500", "C"] spaces = [True,True,True,True,True,True,True,False] ents = ["O","I-PARAMETER","O","O","O","O","I-VALUE","O"] sent_starts = [True] + [None]*(len(words)-1) # 构造Doc时不传tags参数,交给spaCy的tagger预测 doc = Doc(nlp.vocab, words=words, spaces=spaces, ents=ents, sent_starts=sent_starts) # 直接运行整个管道 doc = nlp(doc) # 输出解析结果验证 for token in doc: print(token.text, token.tag_, token.pos_, token.dep_, token.head.text)
内容的提问来源于stack exchange,提问作者hunsvadis
相关产品推荐
相关产品推荐

