Разрешение анафоры в Стэнфорде-НЛП с использованием Python
Я пытаюсь сделать разрешение анафоры, и для этого ниже мой код.
Сначала я перехожу к папке, где я скачал Стэнфордский модуль. Затем я запускаю команду в командной строке для инициализации модуля NANP Стэнфорда
java -mx4g -cp "*;stanford-corenlp-full-2017-06-09/*" edu.stanford.nlp.pipeline.StanfordCoreNLPServer -port 9000 -timeout 15000
После этого я выполняю код ниже в Python
from pycorenlp import StanfordCoreNLP
nlp = StanfordCoreNLP('http://localhost:9000')
Я хочу изменить предложение Tom is a smart boy. He know a lot of thing.
в Tom is a smart boy. Tom know a lot of thing.
и нет никаких учебных пособий или какой-либо помощи в Python.
Все, что я могу сделать, это комментировать ниже код в Python
разрешение по контрольной точке
output = nlp.annotate(sentence, properties={'annotators':'dcoref','outputFormat':'json','ner.useSUTime':'false'})
и разбор для coref
coreferences = output['corefs']
я получаю ниже JSON
coreferences
{u'1': [{u'animacy': u'ANIMATE',
u'endIndex': 2,
u'gender': u'MALE',
u'headIndex': 1,
u'id': 1,
u'isRepresentativeMention': True,
u'number': u'SINGULAR',
u'position': [1, 1],
u'sentNum': 1,
u'startIndex': 1,
u'text': u'Tom',
u'type': u'PROPER'},
{u'animacy': u'ANIMATE',
u'endIndex': 6,
u'gender': u'MALE',
u'headIndex': 5,
u'id': 2,
u'isRepresentativeMention': False,
u'number': u'SINGULAR',
u'position': [1, 2],
u'sentNum': 1,
u'startIndex': 3,
u'text': u'a smart boy',
u'type': u'NOMINAL'},
{u'animacy': u'ANIMATE',
u'endIndex': 2,
u'gender': u'MALE',
u'headIndex': 1,
u'id': 3,
u'isRepresentativeMention': False,
u'number': u'SINGULAR',
u'position': [2, 1],
u'sentNum': 2,
u'startIndex': 1,
u'text': u'He',
u'type': u'PRONOMINAL'}],
u'4': [{u'animacy': u'INANIMATE',
u'endIndex': 7,
u'gender': u'NEUTRAL',
u'headIndex': 4,
u'id': 4,
u'isRepresentativeMention': True,
u'number': u'SINGULAR',
u'position': [2, 2],
u'sentNum': 2,
u'startIndex': 3,
u'text': u'a lot of thing',
u'type': u'NOMINAL'}]}
Любая помощь в этом?
2 ответа
Вот одно из возможных решений, которое использует выходные данные структуры данных CoreNLP. Вся информация предоставлена. Это не предназначено как полное решение, и расширения, вероятно, требуются для решения всех ситуаций, но это хорошая отправная точка.
from pycorenlp import StanfordCoreNLP
nlp = StanfordCoreNLP('http://localhost:9000')
def resolve(corenlp_output):
""" Transfer the word form of the antecedent to its associated pronominal anaphor(s) """
for coref in corenlp_output['corefs']:
mentions = corenlp_output['corefs'][coref]
antecedent = mentions[0] # the antecedent is the first mention in the coreference chain
for j in range(1, len(mentions)):
mention = mentions[j]
if mention['type'] == 'PRONOMINAL':
# get the attributes of the target mention in the corresponding sentence
target_sentence = mention['sentNum']
target_token = mention['startIndex'] - 1
# transfer the antecedent's word form to the appropriate token in the sentence
corenlp_output['sentences'][target_sentence - 1]['tokens'][target_token]['word'] = antecedent['text']
def print_resolved(corenlp_output):
""" Print the "resolved" output """
possessives = ['hers', 'his', 'their', 'theirs']
for sentence in corenlp_output['sentences']:
for token in sentence['tokens']:
output_word = token['word']
# check lemmas as well as tags for possessive pronouns in case of tagging errors
if token['lemma'] in possessives or token['pos'] == 'PRP$':
output_word += "'s" # add the possessive morpheme
output_word += token['after']
print(output_word, end='')
text = "Tom and Jane are good friends. They are cool. He knows a lot of things and so does she. His car is red, but " \
"hers is blue. It is older than hers. The big cat ate its dinner."
output = nlp.annotate(text, properties= {'annotators':'dcoref','outputFormat':'json','ner.useSUTime':'false'})
resolve(output)
print('Original:', text)
print('Resolved: ', end='')
print_resolved(output)
Это дает следующий вывод:
Original: Tom and Jane are good friends. They are cool. He knows a lot of things and so does she. His car is red, but hers is blue. It is older than hers. The big cat ate his dinner.
Resolved: Tom and Jane are good friends. Tom and Jane are cool. Tom knows a lot of things and so does Jane. Tom's car is red, but Jane's is blue. His car is older than Jane's. The big cat ate The big cat's dinner.
Как вы можете видеть, это решение не имеет дело с исправлением случая, когда местоимение имеет предшествующее предложению предложение (название-случай) ("большой кот" вместо "большой кот" в последнем предложении). Это зависит от категории антецедента - обычные существительные антецеденты нуждаются в нижнем регистре, в то время как собственные антецеденты не будут. Может потребоваться некоторая другая специальная обработка (как для притяжений в моем тестовом предложении). Это также предполагает, что вы не захотите повторно использовать исходные выходные токены, так как они модифицируются этим кодом. Обходным путем будет создание копии исходной структуры данных или создание нового атрибута и изменение print_resolved
функционировать соответственно. Исправление любых ошибок разрешения - также другая проблема!
У меня была похожая проблема. Я решил это с помощью нейронного coref после попытки сделать с core nlp. Вы можете легко выполнить работу через нейронный coref, используя следующий код:
Пространство импорта
nlp = spacy.load ('en_coref_md')
doc = nlp (код города u'Phone будет действителен только при соблюдении всех перечисленных ниже условий. Его нельзя оставлять пустым. Он должен быть числовым. Он не может быть меньше 200. Минимальное количество цифр должно быть 3. ')
печать (док._.coref_clusters)
печать (док._.coref_resolved)
Вывод вышеприведенного кода: [Телефонный код города: [Телефонный код города, Это, Это, Это]]
Телефонный код города будет действителен только при соблюдении всех перечисленных ниже условий. Код города не может быть пустым. Код города должен быть числовым. Код города не может быть меньше 200. Минимальное количество цифр должно быть 3.
Для этого вам нужно иметь просторность, наряду с английскими моделями, которые могут быть en_coref_md или en_coref_lg или en_coref_sm. Вы можете сослаться на следующую ссылку для лучшего объяснения:
from stanfordnlp.server import CoreNLPClient
from nltk import tokenize
client = CoreNLPClient(annotators=['tokenize','ssplit', 'pos', 'lemma', 'ner', 'parse', 'coref'], memory='4G', endpoint='http://localhost:9001')
def pronoun_resolution(text):
ann = client.annotate(text)
modified_text = tokenize.sent_tokenize(text)
for coref in ann.corefChain:
antecedent = []
for mention in coref.mention:
phrase = []
for i in range(mention.beginIndex, mention.endIndex):
phrase.append(ann.sentence[mention.sentenceIndex].token[i].word)
if antecedent == []:
antecedent = ' '.join(word for word in phrase)
else:
anaphor = ' '.join(word for word in phrase)
modified_text[mention.sentenceIndex] = modified_text[mention.sentenceIndex].replace(anaphor, antecedent)
modified_text = ' '.join(modified_text)
return modified_text
text = 'Tom is a smart boy. He knows a lot of things.'
pronoun_resolution(text)
Вывод: "Том - умный мальчик. Том много чего знает ".