#python #spacy
Вопрос:
Использование
Я создаю программу для аннотирования предложения из абзаца, содержащего конкретные слова, для быстрого анализа контракта, но я замечаю, что в аннотации не выделены правильные слова. Пожалуйста, смотрите данные обучения ниже в коде, а данные тестирования ниже.
Я ожидал бы, что мой код идентифицируется как
«Mrпродает продукт, который он гарантирует не менее чем на один год», когда он находит термин «Гарантия». Минимальные условия оплаты, приемлемые для нашей фирмы, составляют 90 дней», когда он видит условия оплаты на основе подготовленных данных. Однако вывод кода:
Однако на выходе получается
Приведенный ниже маркетинг вообще не согласуется с «Условиями оплаты»
WORK_OF_ART — MrX
Маркетинг-Мистер продает продукт, на который он гарантирует по крайней мере один год, и надеется, что он получит оплату за продукт в течение 70 дней.
Маркетинг-MrB не разрешается делиться любым логотипом, который он может использовать на этапе проекта, с другими клиентами в качестве рекламного товара.
#Данные тестирования, импортированные с помощью Doc2x.
«MrB ожидает, что MrX возьмет на себя ответственность за хранение клиентских данных на самом высоком уровне. CompanyA является филиалом компании CompanyB. MRAS продает продукт, на который он дает гарантию не менее чем на один год, и надеется, что он получит оплату за продукт в течение 70 дней. MrB не разрешается делиться любым логотипом, который он может использовать на этапе проекта, с другими клиентами в качестве рекламного товара».
#Код
import spacy
import random
from spacy.training import Example
import docx2txt
from spacy import displacy
import pandas as pd
import docx
#nlp = spacy.blank('en')
nlp = spacy.load('en_core_web_sm')
ner=nlp.get_pipe("ner")
if 'ner' not in nlp.pipe_names:
ner_pipe = nlp.create_pipe('ner')
nlp.add_pipe(ner_pipe, last=True)
else:
ner_pipe = nlp.get_pipe('ner')
TRAIN_DATA = [("The minimum payment terms acceptable to our firm are Net 90 days.",{"entities":[(0,62,"Payment Terms")]}),
("We do not allow anyone to share our logo for marketing purpose.",{"entities":[(0,63,"Marketing")]}),
("We expect that the firm will honor our warranty requirement of atleast one year.",{"entities":[(39,48,"Warranty")]})]
for _,annotations in TRAIN_DATA:
for entity in annotations['entities']:
ner.add_label(entity[2])
other_pipes = [pipe for pipe in nlp.pipe_names if pipe != 'ner']
with nlp.disable_pipes(*other_pipes): # only train NER
optimizer = nlp.create_optimizer()
for iteration in range(200):
random.shuffle(TRAIN_DATA)
for text, annotations in TRAIN_DATA:
doc = nlp.make_doc(text)
example = Example.from_dict(doc, annotations)
nlp.update([example],drop=0.3)
# test the trained model # add some dummy sentences with many NERs
test_text = docx2txt.process('C:/users/Siddk/Testing.docx')
doc = nlp(test_text)
for ent in doc.ents:
print(ent.label_, " -- ", ent.text)
Ответ №1:
В ваших тренировочных данных у вас есть три примера. Я предполагаю, что это пример переполнения стека, но на всякий случай: вы не можете обучить модель из трех примеров. Вам нужны по крайней мере сотни.
В более общем плане вы не можете использовать NER для пометки целых предложений, особенно пространных NER. Из документов:
Алгоритм, основанный на переходе, также предполагает, что наиболее важная информация о ваших сущностях будет близка к их начальным токенам. Если ваши объекты длинные и характеризуются маркерами посередине, компонент, скорее всего, не подойдет для вашей задачи.
Из ваших трех примеров в двух случаях вы помечали целые предложения. Модель не сможет этому научиться.
Есть пара вещей, которые вы можете сделать вместо этого. Один из них заключается в использовании текстового классификатора для предложений. Другой вариант-взглянуть на разделитель категорий, который скоро будет выпущен в качестве экспериментальной функции.
Я бы посоветовал вам использовать подход классификации, хотя — начало/концы промежутков на самом деле не важны в ваших примерах, похоже, вы просто хотите классифицировать предложения.
Комментарии:
1. Спасибо, что нашли время и силы ответить на мой вопрос. У меня нет сильного опыта программирования. Итак, по сути, я использую неправильную терминологию для своего варианта использования? Просто повторю, я хочу, чтобы моя модель идентифицировала все проблемное предложение, как только она найдет объекты, соответствующие обучающему набору. Мы надеемся, что этот процесс облегчит рецензенту проверку документов, когда будут выделены соответствующие объекты.
2. Это не проблема терминологии, это проблема подхода. Вы хотите идентифицировать предложения на основе ключевых слов, но вы пометили целые предложения — модель не может этому научиться. Вам следует либо пометить ключевые слова, а затем выбрать предложения, содержащие ключевые слова, в качестве шага последующей обработки, либо классифицировать предложения. Я рекомендую вам сначала попробовать использовать первый подход с сопоставителем на основе правил. spacy.io/usage/rule-based-matching
3. Спасибо, так как у меня есть общее представление о классификации NER. Только одно последнее замечание. Не могли бы вы предложить хороший инструмент для маркировки. Я использовал инструмент agate NER, но алгоритм, похоже, игнорирует его из-за ошибки токенизации. Я слышал о Doccano, но установка сложна. Вундеркинд стоит дорого. Инструмент аннотации Spacy не работает, так как он не идентифицирует объекты.