Обучите существующий POS-тег в spaCy на моих собственных примерах обучения - PullRequest
2 голосов
/ 26 июня 2019

Я пытаюсь обучить существующий POS-тегер на своем собственном лексиконе, не начиная с нуля (я не хочу создавать «пустую модель»). В документации spaCy написано «Загрузите модель, с которой вы хотите выполнить статистику», а следующий шаг - «Добавьте карту тегов в теггер с помощью метода add_label». Однако, когда я пытаюсь загрузить маленькую английскую модель и добавить карту тегов, она выдает эту ошибку:

ValueError: [T003] Изменение размера предварительно обученных моделей Tagger в настоящее время не поддерживается.

Мне было интересно, как это можно исправить.

Я также видел Реализация пользовательского POS Tagger в Spacy поверх существующей английской модели: NLP - Python , но это предполагает, что мы создаем «пустую модель», что не то, что я хочу.

Кроме того, в документации spaCy не очень ясно, нужен ли нам словарь отображения (TAG_MAP), даже если наши теги обучающих примеров совпадают с тегами универсальных зависимостей. Какие-нибудь мысли?

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

TAG_MAP = {"noun": {"pos": "NOUN"}, "verb": {"pos": "VERB"}, "adj": {"pos": "ADJ"}, "adv": {"pos": "ADV"}}

TRAIN_DATA = [
    ('Afrotropical', {'tags': ['adj']}), ('Afrocentricity', {'tags': ['noun']}),
    ('Afrocentric', {'tags': ['adj']}), ('Afrocentrism', {'tags': ['noun']}),
    ('Anglomania', {'tags': ['noun']}), ('Anglocentric', {'tags': ['adj']}),
    ('apraxic', {'tags': ['adj']}), ('aglycosuric', {'tags': ['adj']}),
    ('asecretory', {'tags': ['adj']}), ('aleukaemic', {'tags': ['adj']}),
    ('agrin', {'tags': ['adj']}), ('Eurotransplant', {'tags': ['noun']}),
    ('Euromarket', {'tags': ['noun']}), ('Eurocentrism', {'tags': ['noun']}),
    ('adendritic', {'tags': ['adj']}), ('asynaptic', {'tags': ['adj']}),
    ('Asynapsis', {'tags': ['noun']}), ('ametabolic', {'tags': ['adj']})
]
@plac.annotations(
    lang=("ISO Code of language to use", "option", "l", str),
    output_dir=("Optional output directory", "option", "o", Path),
    n_iter=("Number of training iterations", "option", "n", int),
)
def main(lang="en", output_dir=None, n_iter=25):
    nlp = spacy.load('en_core_web_sm', disable=['ner', 'parser'])
    tagger = nlp.get_pipe('tagger')
    for tag, values in TAG_MAP.items():
        tagger.add_label(tag, values)
    nlp.vocab.vectors.name = 'spacy_pretrained_vectors'
    optimizer = nlp.begin_training()
    for i 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 Afrotropical apraxic blue eggs and Afrocentricity. A Eurotransplant is cool too. The agnathostomatous Euromarket and asypnapsis is even cooler. What about Eurocentrism?"
    doc = nlp(test_text)
    print("Tags", [(t.text, t.tag_, t.pos_) 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 save model
        print("Loading from", output_dir)
        nlp2 = spacy.load(output_dir)
        doc = nlp2(test_text)
        print("Tags", [(t.text, t.tag_, t.pos_) for t in doc])


if __name__ == "__main__":
    plac.call(main)

Ответы [ 2 ]

2 голосов
/ 26 июня 2019

Английская модель обучается на PTB-тегах , а не на UD-тегах.Карта тегов spacy дает вам довольно хорошее представление о соответствиях, но набор тегов PTB более детализирован, чем набор тегов UD:

https://github.com/explosion/spaCy/blob/master/spacy/lang/en/tag_map.py

Пропустить код, связанный с tag_map (PTB -> UD-отображение уже есть в модели), измените ваши теги в ваших данных на теги PTB (NN, NNS, JJ и т. Д.), И затем этот скрипт должен запуститься.(Конечно, вам все равно придется проверить, хорошо ли он работает.)

В общем, лучше приводить обучающие примеры с полными фразами или предложениями, так как именно это пространство будет помечать в реальном использовании, как ваштестовое предложение.

0 голосов
/ 01 июля 2019

Если вы намереваетесь создать свой собственный TAG_MAP, вам также следует отключить тег из модели.Таким образом, его обучение по оригинальным тегам не помешает новому обучению.

Это означает, что вам придется создать свое собственное, как в пустом примере, а затем добавить его в конвейер.Я делаю то же самое с моделью pt, вот соответствующий код:

nlp = spacy.load('pt_core_news_sm', disable=['parser', 'ner', 'tagger'])

tagger = nlp.create_pipe("tagger")
for tag, values in TAG_MAP_alternate.items():
    tagger.add_label(tag, values)
nlp.add_pipe(tagger)
...