Стенфордские типизированные зависимости с использованием coreNLP в python - PullRequest
3 голосов
/ 10 июня 2019

В Руководство по зависимостям Стэнфорда они упоминают "типизированные зависимости Стэнфорда" и, в частности, тип "neg" - модификатор отрицания. Он также доступен при использовании синтаксического анализатора Stanford ++ для веб-сайта. например, предложение:

"Барак Обама не родился на Гавайях"

enter image description here

Парсер действительно находит нег (рожден, а не)

но когда я использую библиотеку stanfordnlp python, единственный анализатор зависимостей, который я могу получить, будет анализировать предложение следующим образом:

('Barack', '5', 'nsubj:pass')

('Obama', '1', 'flat')

('was', '5', 'aux:pass')

('not', '5', 'advmod')

('born', '0', 'root')

('in', '7', 'case')

('Hawaii', '5', 'obl')

и код, который его генерирует:

import stanfordnlp
stanfordnlp.download('en')  
nlp = stanfordnlp.Pipeline()
doc = nlp("Barack Obama was not born in Hawaii")
a  = doc.sentences[0]
a.print_dependencies()

Есть ли способ получить результаты, аналогичные расширенному анализатору зависимостей или любому другому анализатору Стэнфорда, который приводит к типизированным зависимостям, которые дадут мне модификатор отрицания?

Ответы [ 2 ]

2 голосов
/ 17 июня 2019

Следует отметить, что библиотека python stanfordnlp - это не просто оболочка Python для StanfordCoreNLP.

1.Разница StanfordNLP / CoreNLP

Как сказано в репозитории Github stanfordnlp :

Официальная библиотека Python NLP группы Stanford NLP.Он содержит пакеты для запуска нашего последнего полностью нейронного конвейера из Shared Task CoNLL 2018 и для доступа к серверу Java Stanford CoreNLP.

Stanfordnlp содержит новый набор моделей нейронных сетей, обученных на общей CONLL 2018задача.Онлайн-анализатор основан на Java-библиотеке CoreNLP 3.9.2.Это два разных конвейера и наборы моделей, как объяснено здесь .

Ваш код обращается только к их нейронному конвейеру, обученному на данных CONLL 2018.Это объясняет различия, которые вы видели по сравнению с онлайн-версией.По сути, это две разные модели.

Я считаю, что путаница заключается в том, что оба репозитория принадлежат пользователю с именем stanfordnlp (это название команды).Не обманывайтесь между java stanfordnlp / CoreNLP и питоном stanfordnlp / stanfordnlp.

Что касается вашей проблемы с "neg", то, похоже, в python libabry stanfordnlp они решили рассмотреть отрицание с помощью аннотации advmod.По крайней мере, это то, с чем я столкнулся для нескольких примеров предложений.

2.Использование CoreNLP через пакет stanfordnlp

Однако вы все равно можете получить доступ к CoreNLP через пакет stanfordnlp.Это требует еще нескольких шагов, хотя.Ссылаясь на репозиторий Github,

Существует несколько начальных шагов настройки.

  • Загрузите Stanford CoreNLP и модели для языка, который вы хотите использовать. (вы можете скачать CoreNLP и языковые модели здесь)
  • Поместите jar-файлы моделей в папку дистрибутива
  • Сообщите коду Python, где находится Stanford CoreNLP: export CORENLP_HOME =/ path / to / stanford-corenlp-full-2018-10-05

Как только это будет сделано, вы можете запустить клиента с кодом, который можно найти в demo :

from stanfordnlp.server import CoreNLPClient 

with CoreNLPClient(annotators=['tokenize','ssplit','pos','depparse'], timeout=60000, memory='16G') as client:
    # submit the request to the server
    ann = client.annotate(text)

    # get the first sentence
    sentence = ann.sentence[0]

    # get the dependency parse of the first sentence
    print('---')
    print('dependency parse of first sentence')
    dependency_parse = sentence.basicDependencies
    print(dependency_parse)

    #get the tokens of the first sentence
    #note that 1 token is 1 node in the parse tree, nodes start at 1
    print('---')
    print('Tokens of first sentence')
    for token in sentence.token :
        print(token)

Поэтому ваше предложение будет проанализировано, если вы укажете аннотатор depparse (а также обязательные аннотаторы tokenize, ssplit и pos).Читая демо, кажется, что мы можем получить доступ только к базовым зависимостям.Мне не удалось заставить работать зависимости Enhanced ++ через stanfordnlp.

Но отрицания все равно будут появляться, если вы используете basicDependencies!

Вот вывод, который я получил с помощью stanfordnlp и вашего примера предложения.Это объект DependencyGraph, не очень красивый, но, к сожалению, это всегда тот случай, когда мы используем очень глубокие инструменты CoreNLP.Вы увидите, что между узлами 4 и 5 («не» и «рожденный») есть и край «нег».

node {
  sentenceIndex: 0
  index: 1
}
node {
  sentenceIndex: 0
  index: 2
}
node {
  sentenceIndex: 0
  index: 3
}
node {
  sentenceIndex: 0
  index: 4
}
node {
  sentenceIndex: 0
  index: 5
}
node {
  sentenceIndex: 0
  index: 6
}
node {
  sentenceIndex: 0
  index: 7
}
node {
  sentenceIndex: 0
  index: 8
}
edge {
  source: 2
  target: 1
  dep: "compound"
  isExtra: false
  sourceCopy: 0
  targetCopy: 0
  language: UniversalEnglish
}
edge {
  source: 5
  target: 2
  dep: "nsubjpass"
  isExtra: false
  sourceCopy: 0
  targetCopy: 0
  language: UniversalEnglish
}
edge {
  source: 5
  target: 3
  dep: "auxpass"
  isExtra: false
  sourceCopy: 0
  targetCopy: 0
  language: UniversalEnglish
}
edge {
  source: 5
  target: 4
  dep: "neg"
  isExtra: false
  sourceCopy: 0
  targetCopy: 0
  language: UniversalEnglish
}
edge {
  source: 5
  target: 7
  dep: "nmod"
  isExtra: false
  sourceCopy: 0
  targetCopy: 0
  language: UniversalEnglish
}
edge {
  source: 5
  target: 8
  dep: "punct"
  isExtra: false
  sourceCopy: 0
  targetCopy: 0
  language: UniversalEnglish
}
edge {
  source: 7
  target: 6
  dep: "case"
  isExtra: false
  sourceCopy: 0
  targetCopy: 0
  language: UniversalEnglish
}
root: 5

---
Tokens of first sentence
word: "Barack"
pos: "NNP"
value: "Barack"
before: ""
after: " "
originalText: "Barack"
beginChar: 0
endChar: 6
tokenBeginIndex: 0
tokenEndIndex: 1
hasXmlContext: false
isNewline: false

word: "Obama"
pos: "NNP"
value: "Obama"
before: " "
after: " "
originalText: "Obama"
beginChar: 7
endChar: 12
tokenBeginIndex: 1
tokenEndIndex: 2
hasXmlContext: false
isNewline: false

word: "was"
pos: "VBD"
value: "was"
before: " "
after: " "
originalText: "was"
beginChar: 13
endChar: 16
tokenBeginIndex: 2
tokenEndIndex: 3
hasXmlContext: false
isNewline: false

word: "not"
pos: "RB"
value: "not"
before: " "
after: " "
originalText: "not"
beginChar: 17
endChar: 20
tokenBeginIndex: 3
tokenEndIndex: 4
hasXmlContext: false
isNewline: false

word: "born"
pos: "VBN"
value: "born"
before: " "
after: " "
originalText: "born"
beginChar: 21
endChar: 25
tokenBeginIndex: 4
tokenEndIndex: 5
hasXmlContext: false
isNewline: false

word: "in"
pos: "IN"
value: "in"
before: " "
after: " "
originalText: "in"
beginChar: 26
endChar: 28
tokenBeginIndex: 5
tokenEndIndex: 6
hasXmlContext: false
isNewline: false

word: "Hawaii"
pos: "NNP"
value: "Hawaii"
before: " "
after: ""
originalText: "Hawaii"
beginChar: 29
endChar: 35
tokenBeginIndex: 6
tokenEndIndex: 7
hasXmlContext: false
isNewline: false

word: "."
pos: "."
value: "."
before: ""
after: ""
originalText: "."
beginChar: 35
endChar: 36
tokenBeginIndex: 7
tokenEndIndex: 8
hasXmlContext: false
isNewline: false

2.Использование CoreNLP через пакет NLTK

Я не буду вдаваться в подробности этого, но есть также решение для доступа к серверу CoreNLP через библиотеку NLTK, если ничего не помогает.Он выводит отрицания, но требует немного больше работы для запуска серверов.Подробности на этой странице

РЕДАКТИРОВАТЬ

Я подумал, что мог бы также поделиться с вами кодом, чтобы получить DependencyGraph в хороший список 'зависимости, аргумента1, аргумента2' вформа, похожая на ту, что выводит stanfordnlp.

from stanfordnlp.server import CoreNLPClient

text = "Barack Obama was not born in Hawaii."

# set up the client
with CoreNLPClient(annotators=['tokenize','ssplit','pos','depparse'], timeout=60000, memory='16G') as client:
    # submit the request to the server
    ann = client.annotate(text)

    # get the first sentence
    sentence = ann.sentence[0]

    # get the dependency parse of the first sentence
    dependency_parse = sentence.basicDependencies

    #print(dir(sentence.token[0])) #to find all the attributes and methods of a Token object
    #print(dir(dependency_parse)) #to find all the attributes and methods of a DependencyGraph object
    #print(dir(dependency_parse.edge))

    #get a dictionary associating each token/node with its label
    token_dict = {}
    for i in range(0, len(sentence.token)) :
        token_dict[sentence.token[i].tokenEndIndex] = sentence.token[i].word

    #get a list of the dependencies with the words they connect
    list_dep=[]
    for i in range(0, len(dependency_parse.edge)):

        source_node = dependency_parse.edge[i].source
        source_name = token_dict[source_node]

        target_node = dependency_parse.edge[i].target
        target_name = token_dict[target_node]

        dep = dependency_parse.edge[i].dep

        list_dep.append((dep, 
            str(source_node)+'-'+source_name, 
            str(target_node)+'-'+target_name))
    print(list_dep)

Он выводит следующее

[('compound', '2-Obama', '1-Barack'), ('nsubjpass', '5-born', '2-Obama'), ('auxpass', '5-born', '3-was'), ('neg', '5-born', '4-not'), ('nmod', '5-born', '7-Hawaii'), ('punct', '5-born', '8-.'), ('case', '7-Hawaii', '6-in')]
0 голосов
/ 12 июня 2019

Я полагаю, что существует несоответствие между моделью, которая использовалась для создания зависимостей для документации, и моделью, доступной в сети, отсюда и разница. Я бы поднял вопрос с stanfordnlp сопровождающими библиотек напрямую через GitHub Issues .

...