python - 如何在 Spacy v3 中使用 BILUO 模式更新 NER 模型?
问题描述
我想在 sm NER spacy 模型中添加一些 PERSON 词汇。为此,我使用 BILUO 模式标记了取自 ProPublica API 的国会官员的姓名。我看过很多关于使用带实体格式的字典的帖子。但到目前为止,在 v3 中找不到任何使用 BILUO 模式的地方。我有我的数据作为元组列表。第一个值是字符串,第二个值是标记的实体。
data = [('Nanette Barragán', list(['B-PERSON', 'L-PERSON'])),
('Jack Bergman', list(['B-PERSON', 'L-PERSON'])),
('Andy Biggs', list(['B-PERSON', 'L-PERSON'])),
('Lisa Blunt Rochester', list(['B-PERSON', 'I-PERSON', 'L-PERSON'])),
('Anthony Brown', list(['B-PERSON', 'L-PERSON'])),
('Ted Budd', list(['B-PERSON', 'L-PERSON'])),
('Troy Balderson', list(['B-PERSON', 'L-PERSON'])),
('James Baird', list(['B-PERSON', 'L-PERSON'])),
('Tim Burchett', list(['B-PERSON', 'L-PERSON']))]
我想将这些名称添加到已加载的 NER 模型中。我一直在遵循以下步骤:我们如何使用 Spacy minibatch 和 GoldParse 使用 BILUO 标记方案训练 NER 模型?. 这指的是 v2,但是 v3 不再使用 GoldParse,如下面的 Spacy v3 文档中的文本所示:
The Language.update, Language.evaluate and
TrainablePipe.update methods now all take batches of Example
objects instead of Doc and GoldParse objects, or raw text and a
dictionary of annotations.
Example 的文档显示在这里:https ://spacy.io/api/example
下面是我更新的脚本
import spacy
from spacy import displacy
import en_core_web_sm
import random
from spacy.util import minibatch, compounding
from spacy.tokens import Doc
from spacy.training import Example
nlp = en_core_web_sm.load()
if 'ner' not in nlp.pipe_names:
nlp.add_pipe('ner', last=True)
else:
ner = nlp.get_pipe('ner')
ner.add_label('PERSON')
other_pipes = [pipe for pipe in nlp.pipe_names if pipe != 'ner']
with nlp.disable_pipes(*other_pipes): # only train NER
optimizer = nlp.create_optimizer()
tags = dict()
for itn in range(10):
print("Starting iteration " + str(itn))
random.shuffle(data)
losses = {}
batches = minibatch(data, size=compounding(4.0, 16.0, 1.001))
# type 2 with mini batch
for batch in batches:
texts, _ = zip(*batch)
golds = [Example(Doc(nlp.vocab, words = t), references = a) for t,a in batch]
nlp.update(
texts, # batch of texts
golds, # batch of annotations
drop=0.4, # dropout - make it harder to memorise data
losses=losses,
sgd=optimizer)
但是,我收到错误:
Starting iteration 0
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/var/folders/36/j_203fcj42q9bvnlt1sl3j640000gp/T/ipykernel_162/1201951981.py in <module>
14 for batch in batches:
15 texts, _ = zip(*batch)
---> 16 golds = [Example(Doc(nlp.vocab, words = t),references = a) for t,a in batch]
17 nlp.update(
18 texts, # batch of texts
/var/folders/36/j_203fcj42q9bvnlt1sl3j640000gp/T/ipykernel_162/1201951981.py in <listcomp>(.0)
14 for batch in batches:
15 texts, _ = zip(*batch)
---> 16 golds = [Example(Doc(nlp.vocab, words = t),references = a) for t,a in batch]
17 nlp.update(
18 texts, # batch of texts
~/.pyenv/versions/3.8.3/lib/python3.8/site-packages/spacy/training/example.pyx in spacy.training.example.Example.__init__()
TypeError: __init__() takes exactly 2 positional arguments (1 given)
我还尝试像在原始代码中一样替换下面的 Doc var,但仍然是同样的错误。
golds = [Example(nlp.make_doc(t),references = a) for t,a in batch]
我不知道如何克服这个错误。任何帮助是极大的赞赏!
解决方案
发生该错误是因为您将关键字参数传递references
给Example类构造函数,但构造函数采用两个位置参数和一个仅关键字参数alignment
. 也就是说,references
不是 Example 构造函数的关键字参数。
这应该可以解决该错误。
golds = [Example(Doc(nlp.vocab, words = t), a) for t, a in batch]
我不确定您发布的数据是否代表您的实际数据。如果是这样,在其上训练 NER 可能没有太大价值,因为它只是一个实体列表,周围没有上下文。在这种情况下,您最好使用像PhraseMatcher这样的基于规则的方法。
推荐阅读
- java - 如何在运行时实现“可重绘”ListView?
- javascript - Javascript按时间更改句子
- html - 在 Ruby 中使用 Nogokiri 解析 HTML
- r - 在循环中使用 Display() 和 as_image() 将图像添加到 flextable 不起作用
- wordpress - WordPress多站点文件未找到问题
- java - Java 应用程序的 WebSphere 8.5.5.14 上的编码问题 - XML 解析:第 1 行,字符 39,无法切换编码
- python-3.x - 如何修复“TypeError:必须是实数,而不是 str”错误?
- python - 我可以使用参数插入来指定 MySQL 查询的列名吗?
- python-3.x - 无法在 tkinter 的列表框中插入数据
- android - 如何对方法进行单元测试,当它在android中有处理程序时