Пассивный голос обычно является хорошим индикатором направления отношений.
Вы можете извлечь из контекста между двумя сущностями паттерн, который начинается с глагола, а затем обнаруживать присутствие илиотсутствие пассивного голоса.
Какой-то простой код для проверки концепции (на самом деле это может быть намного проще, если использовать RegexpParser из NLTK)
from nltk import pos_tag
from nltk import word_tokenize
from nltk.stem.wordnet import WordNetLemmatizer
lmtzr = WordNetLemmatizer()
aux_verbs = ['be']
def detect_passive_voice(pattern):
passive_voice = False
if len(pattern) >= 3:
if pattern[0][1].startswith('V'):
verb = lmtzr.lemmatize(pattern[0][0], 'v')
if verb in aux_verbs:
if (pattern[1][1] == 'VBN' or pattern[1][1] == 'VBD') and pattern[-1][0] == 'by':
passive_voice = True
# past verb + by
elif (pattern[-2][1] == 'VBN' or pattern[-2][1] == 'VBD') and pattern[-1][0] == 'by':
passive_voice = True
# past verb + by
elif (pattern[-2][1] == 'VBN' or pattern[-2][1] == 'VBD') and pattern[-1][0] == 'by':
passive_voice = True
# past verb + by
elif len(pattern) >= 2:
if (pattern[-2][1] == 'VBN' or pattern[-2][1] == 'VBD') and pattern[-1][0] == 'by':
passive_voice = True
return passive_voice
Запуск нескольких примеров:
In [4]: tokens = word_tokenize("was bought by")
...: tags = pos_tag(tokens)
...: detect_passive_voice(tags)
Out[4]: True
In [5]: tokens = word_tokenize("mailed the letter")
...: tags = pos_tag(tokens)
...: detect_passive_voice(tags)
Out[5]: False
In [7]: tokens = word_tokenize("was mailed by")
...: tags = pos_tag(tokens)
...: detect_passive_voice(tags)
Out[7]: True
Вы можете добавить больше вспомогательных глаголов, а также учесть существование промежуточных наречий или прилагательных.