Я пытаюсь обучить существующий 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)