在 Spacy 中训练两个连续的 NER 管道

问题描述

我正在开展一个项目来训练分类器来识别文本中的引文。我们正在处理的引文往往非常混乱。以下是一些引用示例:

  • 参见 A 书第 3 章第 7 段
  • 见 A 册第 3 章第 7 段
  • 参见 A 册“某些章节标题”一章,第 7 段

我们已经确定了少数倾向于出现在这些引文中的实体。例如,“书名”、“章号”、“章名”、“段号”。

该项目有两个阶段:

  1. 文本中引用的二元分类
  2. 引文内引文实体的分类

Spacy(我们使用的是 v3)是否可以有两个连续的 NER 管道?我希望分类器首先标记引文,然后才标记每个引文中的实体。

我能够使用以下代码实例化具有两个 NER 管道的模型:

from spacy.lang.en import English
nlp = English()
nlp.add_pipe("ner",name="ner1",last=True)
ner1 = nlp.get_pipe("ner1")
ner1.add_label("Citation")
nlp.add_pipe("ner",name="ner2",last=True)
ner2 = nlp.get_pipe("ner2")
for label in ["Book Title","Chapter Number","Chapter Name","Paragraph Number"]:
    ner2.add_label(label)

我的问题是如何分别训练每个 NER 管道。通常,Spacy 需要以下形状的数据来训练 NER:

{
    "text": <TEXT>,"spans": [<LIST OF NAMED ENTITY SPANS>]
}

如何区分训练数据中每个管道的数据?

解决方法

这有几个部分。

  1. 您可以在一个 spaCy 管道中使用两个 NER 组件,但由于问题 2 和 3,这不会按照您希望的方式工作。
  2. Pipelines 在训练下游组件期间无法设置注释。这是一个正在解决的限制,应该很快得到解决。
  3. NER 注释不能重叠。这是一个设计决定,不会很快改变。它可以通过自定义组件解决,但需要额外的工作。

我希望分类器首先标记引文,然后才标记每个引文中的实体。

您实际上是否需要单独使用整个引文标签,还是出于某种原因将其设计为两阶段过程以提高性能?如果是后者,我就先尝试训练第二阶段的详细注释,看看你是否真的有问题;我怀疑一个两阶段的过程实际上会让事情变得更容易。

如果您确实需要整个“引文”,那么您可以将详细实体的链提取到单个跨度中,无需为此创建单独的模型。

我建议您仔细阅读文档中关于 Combining Models and Rules 的部分。它有一些示例,例如扩展个人姓名以包含先生或博士等头衔,或使用依赖项解析信息,这些示例似乎适用于您的问题。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...