Нахождение или нет, слово находится на пути зависимости двух объектов с spaCy

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

Например:

"Туманный гребень восстает из всплеска"

Я хочу перебрать каждое слово и сказать, находится ли он на пути зависимости между e1 и e2

Два важных замечания:

-Если вы пытаетесь мне помочь (во-первых, спасибо), не беспокойтесь о разметке xml с помощью и , мне действительно интересно узнать, находится ли слово на пути зависимости между любыми двумя заданными словами с помощью spaCy я забочусь о том, какие слова сам

- Поскольку я не являюсь экспертом по nlp, меня немного смущает значение "на пути зависимости", и я извиняюсь, если он недостаточно ясен (эти слова используются моим преподавателем)

заранее спасибо

2 ответа

Решение

Таким образом, мое решение было найдено с помощью этого поста

Есть ответ, посвященный spaCy

Моя реализация для нахождения пути зависимости между двумя словами в данном предложении:

import networkx as nx
import spacy
enter code here
doc = nlp("Ships carrying equipment for US troops are already waiting off the Turkish coast")

def shortest_dependency_path(doc, e1=None, e2=None):
    edges = []
    for token in doc:
        for child in token.children:
            edges.append(('{0}'.format(token),
                          '{0}'.format(child)))
    graph = nx.Graph(edges)
    try:
        shortest_path = nx.shortest_path(graph, source=e1, target=e2)
    except nx.NetworkXNoPath:
        shortest_path = []
    return shortest_path

print(shortest_dependency_path(doc,'Ships','troops'))

Выход:

['Ships', 'carrying', 'for', 'troops']

На самом деле он сначала строит неориентированный граф для предложения, где слова - это узлы, а зависимости между словами - это ребра, а затем находит кратчайший путь между двумя узлами.

Для своих нужд я просто проверяю каждое слово на сгенерированный путь зависимости (кратчайший путь)

Путь зависимости - это способ описания того, как предложения строятся в предложении. У SpaCy есть действительно хороший пример в их документах с предложением Apple is looking at buying U.K. startup for $1 billion.

Прошу прощения, что у меня нет хорошей визуализации, но поработайте над своим примером:

A misty ridge uprises from the surge.

В spaCy мы следуем их примеру, чтобы получить зависимости:

import spacy
nlp = spacy.load('en_core_web_lg')
doc = nlp("A misty ridge uprises from the surge.")
for chunk in doc.noun_chunks:
    print(chunk.text, chunk.root.text, chunk.root.dep_, chunk.root.head.text)

Это получит "пункты", которые составляют ваше предложение. Ваш вывод будет выглядеть так:

Text                  | root.text| root.dep_ | root.head.text
A misty ridge uprises   uprises    ROOT        uprises
the surge               surge      pobj        from

chunk.text текст, который составляет ваше предложение о зависимости (обратите внимание, что в зависимости от структуры предложения возможны совпадения). root.text дает корень (или голову) дерева зависимостей. head из дерева это спа token объект, и имеет дочерние элементы, которые вы можете перебрать, чтобы проверить, есть ли другой токен в дереве зависимостей.

def find_dependencies(doc, word_to_check=None, dep_choice=None):
    """
    word_to_check is the word you'd like to see on the dependency tree
    example, word_to_check="misty"

    dep_choice is the text of the item you'd like the dependency check
    to be against. Example, dep_choice='ridge'
    """
    tokens, texts = [], []

    for tok in doc:
        tokens.append(tok)
        texts.append(tok.text)

    # grabs the index/indices of the token that you are interested in
    indices = [i for i,text in enumerate(texts) if text==dep_choice]

    words_in_path = []

    for i in indices:

        reference = tokens[i]
        child_elements = [t.text for t in reference.get_children()]
        if word_to_check in child_elements:
            words_in_path.append((word_to_check, reference))

    return words_in_path

Код не самый красивый, но таким образом вы можете получить список кортежей, содержащих слово, которое вы хотите проверить, и соответствующий родительский токен. Надеюсь, это полезно

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

В целях более точной адаптации к вашему варианту использования (и огромного упрощения того, как выглядит мой первоначальный ответ):

# This will give you 'word':<spaCy doc object> key value lookup capability
tokens_lookup = {tok.text:tok for tok in doc}

if "misty" in tokens_lookup.get("ridge").children:
    # Extra logic here
Другие вопросы по тегам