Можно ли улучшить результаты сходства spaCy с пользовательскими именованными объектами? - PullRequest
1 голос
/ 29 мая 2020

Я обнаружил, что подобие 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

Будем признательны за любые подсказки!

Ответы [ 2 ]

0 голосов
/ 16 июля 2020

Я обнаружил, что мое решение содержится в этом руководстве: Классификация текста в Python Использование spaCy , которое генерирует матрицу BoW для текстовых данных spaCy с помощью SciKit-Learn CountVectorizer .

Я избегал руководств по анализу тональности из-за бинарной классификации, так как мне нужна поддержка нескольких категорий. Хитрость заключалась в том, чтобы установить multi_class = 'auto' в линейной модели LogisticRegression и использовать average = 'micro' для оценки точности и точности отзыва, так что все мои текстовые данные, как и сущности, использовались:

classifier = LogisticRegression(solver='lbfgs', multi_class='auto')

и ...

print("Logistic Regression Accuracy:",metrics.accuracy_score(y_test, predicted))
print("Logistic Regression Precision:",metrics.precision_score(y_test, predicted,average='micro'))
print("Logistic Regression Recall:",metrics.recall_score(y_test, predicted,average='micro'))

Надеюсь, это поможет кому-то сэкономить время!

0 голосов
/ 30 мая 2020

Doc.similarity использует только векторы слов, а не любые другие аннотации. Из Do c API :

Оценка по умолчанию - косинусное сходство с использованием среднего числа векторов слов.

...