Как выполнять анализ зависимостей в NLTK?
Просматривая книгу NLTK, не ясно, как генерировать дерево зависимостей из данного предложения.
В соответствующем разделе книги: подглава по грамматике зависимости приведен пример рисунка, но он не показывает, как разобрать предложение, чтобы придумать эти отношения - или, может быть, я упускаю что-то фундаментальное в НЛП?
РЕДАКТИРОВАТЬ: Я хочу что-то похожее на то, что делает Стэнфордский парсер: Учитывая предложение "Я выстрелил слоном во сне", он должен вернуть что-то вроде:
nsubj(shot-2, I-1)
det(elephant-4, an-3)
dobj(shot-2, elephant-4)
prep(shot-2, in-5)
poss(sleep-7, my-6)
pobj(in-5, sleep-7)
Ответы
Ответ 1
Мы можем использовать Stanford Parser из NLTK.
Требования
Вам нужно скачать две вещи с их сайта:
- Парсер Stanford CoreNLP.
- Модель языка для вашего желаемого языка (например, модель английского языка)
Предупреждение!
Убедитесь, что версия вашей языковой модели соответствует версии вашего анализатора Stanford CoreNLP!
Текущая версия CoreNLP по состоянию на 22 мая 2018 года - 3.9.1.
После загрузки двух файлов распакуйте zip файл в любое место.
Код Python
Далее загрузите модель и используйте ее через NLTK
from nltk.parse.stanford import StanfordDependencyParser
path_to_jar = 'path_to/stanford-parser-full-2014-08-27/stanford-parser.jar'
path_to_models_jar = 'path_to/stanford-parser-full-2014-08-27/stanford-parser-3.4.1-models.jar'
dependency_parser = StanfordDependencyParser(path_to_jar=path_to_jar, path_to_models_jar=path_to_models_jar)
result = dependency_parser.raw_parse('I shot an elephant in my sleep')
dep = result.next()
list(dep.triples())
Выход
Вывод последней строки:
[((u'shot', u'VBD'), u'nsubj', (u'I', u'PRP')),
((u'shot', u'VBD'), u'dobj', (u'elephant', u'NN')),
((u'elephant', u'NN'), u'det', (u'an', u'DT')),
((u'shot', u'VBD'), u'prep', (u'in', u'IN')),
((u'in', u'IN'), u'pobj', (u'sleep', u'NN')),
((u'sleep', u'NN'), u'poss', (u'my', u'PRP$'))]
Я думаю, что это то, что вы хотите.
Ответ 2
Я думаю, что вы могли бы использовать парсер на основе corpus, вместо того, чтобы предоставлять NLTK на основе грамматики.
Выполнение разбора зависимостей на основе corpus даже на небольшом количестве текста в Python не является идеальным по производительности. Поэтому в NLTK они предоставляют обертку для MaltParser, анализатор зависимостей на основе corpus.
Вы можете найти этот другой вопрос о представлении предложений RDF.
Ответ 3
Если вам нужна лучшая производительность, тогда spacy (https://spacy.io/) - лучший выбор. Использование очень просто:
import spacy
nlp = spacy.load('en')
sents = nlp(u'A woman is walking through the door.')
Вы получите дерево зависимостей в качестве выходных данных, и вы сможете очень легко найти любую нужную вам информацию. Вы также можете определить свои собственные конвейеры. Смотрите больше на их сайте.
https://spacy.io/docs/usage/
Ответ 4
Если вы хотите серьезно относиться к анализу зависимостей, не используйте NLTK, все алгоритмы устарели и медленны. Попробуйте что-то вроде этого: https://spacy.io/
Ответ 5
Использовать Stanford Parser от NLTK
1) Запустите сервер CoreNLP на локальном хосте
Загрузите Stanford CoreNLP здесь (а также файл модели для вашего языка). Сервер можно запустить, выполнив следующую команду (подробнее здесь)
# Run the server using all jars in the current directory (e.g., the CoreNLP home directory)
java -mx4g -cp "*" edu.stanford.nlp.pipeline.StanfordCoreNLPServer -port 9000 -timeout 15000
или с помощью NLTK API (сначала необходимо настроить переменную среды CORENLP_HOME
)
os.environ["CORENLP_HOME"] = "dir"
client = corenlp.CoreNLPClient()
# do something
client.stop()
2) Вызов парсера зависимостей из NLTK
>>> from nltk.parse.corenlp import CoreNLPDependencyParser
>>> dep_parser = CoreNLPDependencyParser(url='http://localhost:9000')
>>> parse, = dep_parser.raw_parse(
... 'The quick brown fox jumps over the lazy dog.'
... )
>>> print(parse.to_conll(4))
The DT 4 det
quick JJ 4 amod
brown JJ 4 amod
fox NN 5 nsubj
jumps VBZ 0 ROOT
over IN 9 case
the DT 9 det
lazy JJ 9 amod
dog NN 5 nmod
. . 5 punct
См. Подробную документацию здесь, также этот вопрос NLTK CoreNLPDependencyParser: Не удалось установить соединение.
Ответ 6
Из документации Stanford Parser: "зависимости можно получить с помощью нашего программного обеспечения [...] на деревьях фразовой структуры, используя класс EnglishGrammaticalStructure, доступный в пакете парсеров". http://nlp.stanford.edu/software/stanford-dependencies.shtml
В руководстве по зависимостям также упоминается: "Или наш инструмент преобразования может преобразовать
вывод других синтаксических анализаторов в представление Stanford Dependencies. http://nlp.stanford.edu/software/dependencies_manual.pdf
В настоящее время ни одна функциональность не реализована в NLTK.
Ответ 7
Немного опоздал на вечеринку, но я хотел добавить пример кода с SpaCy, который даст вам желаемый результат:
import spacy
nlp = spacy.load("en_core_web_sm")
doc = nlp("I shot an elephant in my sleep")
for token in doc:
print("{2}({3}-{6}, {0}-{5})".format(token.text, token.tag_, token.dep_, token.head.text, token.head.tag_, token.i+1, token.head.i+1))
А вот вывод, очень похожий на нужный вам вывод:
nsubj(shot-2, I-1)
ROOT(shot-2, shot-2)
det(elephant-4, an-3)
dobj(shot-2, elephant-4)
prep(shot-2, in-5)
poss(sleep-7, my-6)
pobj(in-5, sleep-7)
Надеюсь, это поможет!