В примере сценария , предоставленном spaCy для обучения компонента EntityLinker
, пользовательский объект EntityRuler
инициализируется и добавляется в конвейер
# Add a custom component to recognize "Russ Cochran" as an entity for the example training data.
# Note that in a realistic application, an actual NER algorithm should be used instead.
ruler = EntityRuler(nlp)
patterns = [{"label": "PERSON", "pattern": [{"LOWER": "russ"}, {"LOWER": "cochran"}]}]
ruler.add_patterns(patterns)
nlp.add_pipe(ruler)
Мне интересно, как бы вы добавили вместо этого свой собственный обученный модуль EntityRecognizer
. До сих пор я пытался модифицировать скрипт следующим образом:
@plac.annotations(
kb_path=("Path to the knowledge base", "positional", None, Path),
vocab_path=("Path to the vocab for the kb", "positional", None, Path),
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(kb_path, vocab_path=None, model=None, output_dir=None, n_iter=50):
"""Create a blank model with the specified vocab, set up the pipeline and train the entity linker.
The `vocab` should be the one used during creation of the KB."""
random.seed(0)
if model is not None:
nlp = spacy.load(model) # load existing spaCy model
print("Loaded model '%s'" % model)
else:
vocab = Vocab().from_disk(vocab_path)
# create blank Language class with correct vocab
nlp = spacy.blank("en", vocab=vocab)
nlp.vocab.vectors.name = "spacy_pretrained_vectors"
print("Created blank 'en' model with vocab from '%s'" % vocab_path)
# Add a sentencizer component. Alternatively, add a dependency parser for higher accuracy.
nlp.add_pipe(nlp.create_pipe('sentencizer'))
# Add a custom component to recognize "Russ Cochran" as an entity for the example training data.
# Note that in a realistic application, an actual NER algorithm should be used instead.
ruler = EntityRuler(nlp)
patterns = [{"label": "PERSON", "pattern": [{"LOWER": "russ"}, {"LOWER": "cochran"}]}]
ruler.add_patterns(patterns)
nlp.add_pipe(ruler)
и вызывать скрипт с:
python train_entity_linker.py ./tmp/kb ./tmp/vocab -m en_core_web_lg -o ./tmp -n 1
, поскольку en_core_web_lg
имеет обученного EntityLinker
в своем конвейере. Обратите внимание, что я создал объект базы знаний с помощью:
python pretrain_kb.py -m en_core_web_lg -n 1 -o ./tmp
Однако я получаю следующую ошибку:
File "train_entity_linker.py", line 103, in main
kb_ids = nlp.get_pipe("entity_linker").kb.get_entity_strings()
File "kb.pyx", line 101, in spacy.kb.KnowledgeBase.get_entity_strings
File "strings.pyx", line 136, in spacy.strings.StringStore.__getitem__
KeyError: "[E018] Can't retrieve string for hash '8150086140315095098'. This usually refers to an issue with the `Vocab` or `StringStore`."
Кто-то может объяснить, почему этот подход не работает, и какой правильный подход был бы для добавления и обучения компонента EntityLinker
в обученную модель с EntityRecognizer
уже в ее конвейере?