Я обнаружил, что подобие spaCy неплохо справляется со сравнением моих документов с использованием "en_core_web_lg" из коробки.
Я хотел бы улучшить отношения в некоторых областях и подумал, что добавление пользовательских меток NER в модель поможет, но мои результаты до и после не показывают улучшений, хотя я смог создать тест набор настраиваемых сущностей.
Теперь мне интересно, была ли моя теория полностью ошибочной или я просто что-то упустил в моем конвейере?
Если я ошибался, как лучше всего улучшить результаты? Кажется, что-то вроде нестандартной маркировки должно помочь.
Вот пример того, что я тестировал до сих пор:
import spacy
from spacy.pipeline import EntityRuler
from spacy.tokens import Doc
from spacy.gold import GoldParse
nlp = spacy.load("en_core_web_lg")
docA = nlp("Add fractions with like denominators.")
docB = nlp("What does one-third plus one-third equal?")
sim_before = docA.similarity(docB)
print(sim_before)
0,5949629181460099
^^ Не так уж плохо, но я хотел бы видеть в этом примере результаты ближе к 0,85.
Итак, я использую EntityRuler и добавляю несколько шаблонов, чтобы попытаться укрепить отношения:
ruler = EntityRuler(nlp)
patterns = [
{"label": "ADDITION", "pattern": "Add"},
{"label": "ADDITION", "pattern": "plus"},
{"label": "FRACTION", "pattern": "one-third"},
{"label": "FRACTION", "pattern": "fractions"},
{"label": "FRACTION", "pattern": "denominators"},
]
ruler.add_patterns(patterns)
nlp.add_pipe(ruler, before='ner')
print(nlp.pipe_names)
['tagger', 'parser', 'entity_ruler', 'ner']
Добавление GoldParse кажется важным, поэтому я добавлен следующий и обновленный NER:
doc1 = Doc(nlp.vocab, [u'What', u'does', u'one-third', u'plus', u'one-third', u'equal'])
gold1 = GoldParse(doc1, [u'0', u'0', u'U-FRACTION', u'U-ADDITION', u'U-FRACTION', u'O'])
doc2 = Doc(nlp.vocab, [u'Add', u'fractions', u'with', u'like', u'denominators'])
gold2 = GoldParse(doc2, [u'U-ADDITION', u'U-FRACTION', u'O', u'O', u'U-FRACTION'])
ner = nlp.get_pipe("ner")
losses = {}
optimizer = nlp.begin_training()
ner.update([doc1, doc2], [gold1, gold2], losses=losses, sgd=optimizer)
{'ner': 0,0}
Вы можете видеть, что мои настраиваемые объекты работают, но результаты теста показывают нулевое улучшение:
test1 = nlp("Add fractions with like denominators.")
test2 = nlp("What does one-third plus one-third equal?")
print([(ent.text, ent.label_) for ent in test1.ents])
print([(ent.text, ent.label_) for ent in test2.ents])
sim = test1.similarity(test2)
print(sim)
[('Добавить', 'ДОБАВЛЕНИЕ'), ('дроби', 'ДОЛЯ'), ('знаменатели', ' ФРАКЦИЯ ')]
[(' одна треть ',' ДОЛЯ '), (' плюс ',' ДОБАВЛЕНИЕ '), (' одна треть ',' ДОЛЯ ')]
0,5949629181460099
Будем признательны за любые подсказки!