【问题标题】:How to use spacy train to add entities to an existing custom NER model? (Spacy v3.0)如何使用 spacy train 将实体添加到现有的自定义 NER 模型? (空间v3.0)
【发布时间】:2021-06-22 12:21:42
【问题描述】:

我目前正在实现一个自定义 NER 模型接口,用户可以在其中与前端应用程序交互以添加自定义实体来训练一个 spacy 模型。

我想使用 spacy train (CLI) 获取现有模型(自定义 NER 模型)并将用户指定的关键字和实体添加到该模型。 (而不是再次训练整个模型)。我在文档中的任何地方都找不到这个。

例如,假设我有一个模型已经针对 FOOD 的自定义实体进行了训练。 (比萨、意大利面、面包等……)。现在我想使用这个现有的模型,并使用可口可乐、百事可乐、果汁等关键字来训练一个名为 DRINKS 的新实体……使用 spacy train 命令进行 spacy v3.0。

我目前使用的spacy train 命令如下:

> python -m spacy train config.cfg --output ./output --paths.train ./train.spacy --paths.dev ./train.spacy

我使用以下方法加载模型进行预测:

> nlp1 = spacy.load(R".\output\model-best")

到目前为止,我正在为新实体手动训练模型。下面是在我的训练数据中查找关键字并输出训练数据的 JSON 格式(旧格式)的代码。

import re

keyword = ["outages","updates","negative star","worst"]
entity = ["PROBLEM","PROBLEM","COMPLAINT","COMPLAINT"]

train = []

for text in df.text:

    for n in range(0,len(keyword)):
    
        start_index = []
        end_index = []

        start_index = [m.start() for m in re.finditer(keyword[n], str(text))]

        if(start_index):

            end_index = [m+len(keyword[n]) for m in start_index]

            for i in range(0,len(start_index)):

                train.append((text,{"entities": [(start_index[i],end_index[i],entity[n])]}))

train

在此之后,我使用以下代码将我的 json 格式转换为 .spacy 格式。

from tqdm import tqdm
from spacy.tokens import DocBin

db = DocBin() # create a DocBin object

for text, annot in tqdm(train): # data in previous format
    doc = nlp.make_doc(text) # create doc object from text
    ents = []
    for start, end, label in annot["entities"]: # add character indexes
        span = doc.char_span(start, end, label=label, alignment_mode="contract")
        if span is None:
            print("Skipping entity")
        else:
            ents.append(span)
    doc.ents = ents # label the text with the ents
    db.add(doc)

db.to_disk("./train.spacy")

【问题讨论】:

    标签: python machine-learning nlp spacy named-entity-recognition


    【解决方案1】:

    我想使用 spacy train (CLI) 获取现有模型(自定义 NER 模型)并将用户指定的关键字和实体添加到该模型。 (而不是再次训练整个模型)。我在文档中的任何地方都找不到这个。

    您所描述的内容称为“在线学习”,默认的 spaCy 模型不支持它。大多数现代神经 NER 方法,甚至在 spaCy 之外,根本不支持它。

    您无法通过使用自定义训练循环来解决此问题。

    您的选择是使用基于规则的匹配,因此您只能明确匹配列表中的内容,或者即时重新训练模型。

    基于规则的匹配应该很容易设置,但有一个明显的问题是它无法学习列表中未明确显示的内容。

    动态训练东西听起来可能需要很长时间,但你可以很快训练一个小模型。您可以做的是在用户交互工作时为少量迭代训练一个小模型,在他们确认模型或多或少正常工作后,您可以将相同的训练数据用于具有更长训练的更大模型.

    【讨论】:

    • 是的,非常感谢!!我也花了很长时间才弄清楚这一点。我想我可以通过像 JSON 版本一样保存基于规则的匹配来解决它。很难避免灾难性的遗忘。我正在考虑一种解决方案,我可以从以前训练的实体中只挑选一个句子,并将它们与新的实体数据一起添加到新的训练数据中......这会有效吗?我的意思是,一个模型只用一个例子来排练以前的实体就足够了吗?
    • 谢谢。很难发现 spacy 无法实现“在线学习”。不过很棒的图书馆。
    • 但我认为带有优化器的 nlp.update() 函数可以进一步训练神经元,所以现在我很困惑......
    • 可以进一步训练模型,但有很多复杂性,因此不建议这样做。即使你最终这样做了,像这个问题一样一次添加一个例子也行不通。请参阅有关遗忘的常见问题解答。 github.com/explosion/spaCy/discussions/…
    猜你喜欢
    • 1970-01-01
    • 2021-04-21
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    • 2021-08-27
    • 2020-02-03
    相关资源
    最近更新 更多