Пользовательская модель NER SpaCy: ошибка обучения парсера зависимостей

Я пытался создать собственную модель NER, используя spacy. После построения модели для сущностей необходимо было обучить модель анализаторам зависимостей. Я пробовал следовать образцу кода, представленному на веб-сайте Spacy, приведенному ниже: https://spacy.io/usage/training#tagger-parser

Пример кода для обучающих данных, представленных на веб-сайте SpaCy:

TRAIN_DATA = [
(
    "They trade mortgage-backed securities.",
    {
        "heads": [1, 1, 4, 4, 5, 1, 1],
        "deps": ["nsubj", "ROOT", "compound", "punct", "nmod", "dobj", "punct"],
    },
)]

В этом примере кода для обучающих данных есть метка под названием «головы». Я не очень разбираюсь в том, что это такое и каково его значение в коде.

Я попытался запустить модель без метки «головы» в обучающих данных. Пример обучающих данных:

TRAIN_PARSER = ('Mr Manjunath who is in-charge of the motor at their Goa location.', {'deps': ['compound',    'ROOT',    'nsubj',    'relcl',    'prep',    'punct',    'pobj',    'prep',    'det',    'pobj',    'prep',    'poss', 'compound','pobj', 'punct']})

Когда я пытаюсь запустить модель без метки голов, указанной ниже:

from __future__ import unicode_literals, print_function

import plac
import random
from pathlib import Path
import spacy
from spacy.util import minibatch, compounding


# training data
TRAIN_DATA = TRAIN_PARSER


@plac.annotations(
model=("Model name. Defaults to blank 'en' model.", "option", "m", str),
output_dir=("Optional output directory", "option", "o", Path),
n_iter=("Number of training iterations", "option", "n", int),
)
def main(model='model1', output_dir='model2', n_iter=74):
"""Load the model, set up the pipeline and train the parser."""
if model is not None:
    nlp = spacy.load(model)  # load existing spaCy model
    print("Loaded model '%s'" % model)
else:
    nlp = spacy.blank("en")  # create blank Language class
    print("Created blank 'en' model")

# add the parser to the pipeline if it doesn't exist
# nlp.create_pipe works for built-ins that are registered with spaCy
if "parser" not in nlp.pipe_names:
    parser = nlp.create_pipe("parser")
    nlp.add_pipe(parser, first=True)
# otherwise, get it, so we can add labels to it
else:
    parser = nlp.get_pipe("parser")

# add labels to the parser
for _, annotations in TRAIN_DATA:
    for dep in annotations.get('deps', []):
        parser.add_label(dep)

# get names of other pipes to disable them during training
pipe_exceptions = ["parser", "trf_wordpiecer", "trf_tok2vec"]
other_pipes = [pipe for pipe in nlp.pipe_names if pipe not in pipe_exceptions]
with nlp.disable_pipes(*other_pipes):  # only train parser
    optimizer = nlp.begin_training()
    for itn in range(n_iter):
        random.shuffle(TRAIN_DATA)
        losses = {}
        # batch up the examples using spaCy's minibatch
        batches = minibatch(TRAIN_DATA, size=compounding(4.0, 32.0, 1.001))
        for batch in batches:
            texts, annotations = zip(*batch)
            nlp.update(texts, annotations, sgd=optimizer, losses=losses)
        print("Losses", losses)

# test the trained model
test_text = "I like securities."
doc = nlp(test_text)
print("Dependencies", [(t.text, t.dep_, t.head.text) for t in doc])

# save model to output directory
if output_dir is not None:
    output_dir = Path(output_dir)
    if not output_dir.exists():
        output_dir.mkdir()
    nlp.to_disk(output_dir)
    print("Saved model to", output_dir)

    # test the saved model
    print("Loading from", output_dir)
    nlp2 = spacy.load(output_dir)
    doc = nlp2(test_text)
    print("Dependencies", [(t.text, t.dep_, t.head.text) for t in doc])

    main(model='model1', output_dir='model2', n_iter=74)

Я получаю следующую ошибку:

IndexError: list index out of range

Может кто-нибудь объяснить мне, в чем именно заключается проблема и как я могу ее решить? Кроме того, как я могу создать метку «головы» для моих данных обучения?


person saarthak99    schedule 08.06.2020    source источник


Ответы (1)


Информация heads требуется для идентификации непосредственного «родителя» токена в дереве. Например, в

"I like London and Berlin.",
        {
            "heads": [1, 1, 1, 2, 2, 1],
            "deps": ["nsubj", "ROOT", "dobj", "cc", "conj", "punct"],
        },

слово I имеет начало в индексе 1, то есть слово like, и связано с ним зависимостью nsubj.

Дополнительную информацию об этой терминологии можно найти в документации spaCy: https://spacy.io/usage/linguistic-features#navigating

person Sofie VL    schedule 08.06.2020