首页 > 解决方案 > 如何将词汇特征分配给 spaCy 中新的不可分析的标记?

问题描述

我正在使用 spaCy 2.3 版。我有一个不完全正则表达式扫描仪,它可以识别我不想进一步分析的文本范围。我在管道的开头添加了一个管道,就在标记器之后,它使用文档重新标记器将这些跨度变成单个标记。我希望管道的其余部分将这些标记视为专有名词。这样做的正确方法是什么?我在 retokenizer.merge() 的调用中设置了 POS 和 TAG 属性,这些设置在生成的句子解析中仍然存在,但是这些标记的依赖信息让我怀疑我的设置是否产生了预期的影响。有没有办法更新词汇表,以便 POS 标记器知道这些令牌的唯一 POS 选项是 PROPN?

提前致谢。

标签: spacy

解决方案


标注器和解析器是独立的(解析器不使用标签作为特征),所以修改标签不会影响依赖解析。

标注器不会覆盖任何现有的标签,所以如果一个标签已经设置,它不会修改它。(不过,现有的标签根本不会影响它的预测,所以周围的词被标记的方式与它们在其他情况下的方式相同。)

在 retokenizer 中设置 TAG 和 POS 是设置这些属性的好方法。如果您并不总是重新标记,并且您想根据标记文本的正则表达式设置 TAG 和/或 POS,那么最好的方法是在标记器之前添加一个自定义管道组件,用于设置标记某些词。

基于转换的解析算法无法轻松处理输入中的部分依赖关系,因此这里没有直接的解决方案。我可以想到一些可能会有所帮助的事情:

  • 解析器确实尊重预设的句子边界。如果您跳过的标记位于句子之间,您可以token.is_sent_start = True为该标记和以下标记设置,以便跳过的标记始终以自己的句子结尾。如果跳过的标记位于句子的中间,或者您希望将它们作为句子中的名词进行分析,那么这将无济于事。

  • 解析器确实使用了该token.norm功能,因此如果您将 retokenizer 中的NORM功能设置为非常类似于 PROPN 的东西,您可能有更好的机会获得预期的分析。例如,如果您使用提供的英语模型,例如en_core_web_sm,请使用您认为在 20 年前的美国报纸文本中经常出现的类似专有名词的词,因此如果跳过的标记应该像姓氏,请使用“Bush ”或“克林顿”。它不能保证更好的解析,但它可以提供帮助。

  • 如果您使用带有类似 向量的模型en_core_web_lg,您还可以将跳过的标记的向量设置为与相似词相同(首先检查相似词是否有向量)。这是如何告诉模型引用向量表中的同一行UNKNOWN_SKIPPEDas Bush

    1. 更简单的选项(在内部复制向量表中的向量):
    nlp.vocab.set_vector("UNKNOWN_SKIPPED", nlp.vocab["Bush"].vector)
    
    1. 不太优雅的版本不会在下面复制向量:
    nlp.vocab.vectors.add("UNKNOWN_SKIPPED", row=nlp.vocab["Bush"].rank)
    nlp.vocab["UNKNOWN_SKIPPED"].rank = nlp.vocab["Bush"].rank
    

    (第二行只需要让它适用于当前加载的模型。如果在第一行之后将其保存为自定义模型nlp.to_disk()并重新加载,则只需要第一行。)

  • 如果您只有一小部分跳过的标记,您可以使用一些包含这些标记的示例来更新解析器,但这可能很难在不影响解析器在其他情况下的准确性的情况下做好。

和向量的NORM修改也会影响标注器,所以如果你选择好,你可能会得到非常接近你想要的结果。


推荐阅读