wish to extract compound noun-adjective pairs from a sentence. So, basically I want something like :

点点圈 提交于 2019-12-08 08:03:31

问题


For the adjective:

"The company's customer service was terrible."
{customer service, terrible}

For the verb:

"They kept increasing my phone bill"
{phone bill, increasing}

This is a branch questions from this posting

However I'm trying to find adj and verbs corresponding to multi-token phrases/compound nouns such as "customer service" using spacy.

I'm not sure how to do this with spacy, nltk, or any other prepackaged natural language processing software, and I'd appreciate any help!


回答1:


For simple examples like this, you can use spaCy's dependency parsing with a few simple rules.

First, to identify multi-word nouns similar to the examples given, you can use the "compound" dependency. After parsing a document (e.g., sentence) with spaCy, use a token's dep_ attribute to find it's dependency.

For example, this sentence has two compound nouns:

"The compound dependency identifies compound nouns."

Each token and its dependency is shown below:

import spacy
import pandas as pd
nlp = spacy.load('en')

example_doc = nlp("The compound dependency identifies compound nouns.")
for tok in example_doc:
    print(tok.i, tok, "[", tok.dep_, "]")

>>>0 The [ det ]
>>>1 compound [ compound ]
>>>2 dependency [ nsubj ]
>>>3 identifies [ ROOT ]
>>>4 compound [ compound ]
>>>5 nouns [ dobj ]
>>>6 . [ punct ]
for tok in [tok for tok in example_doc if tok.dep_ == 'compound']: # Get list of 
compounds in doc
    noun = example_doc[tok.i: tok.head.i + 1]
    print(noun)
>>>compound dependency
>>>compound nouns

The below function works for your examples. However, it will likely not work for more complicated sentences.

adj_doc = nlp("The company's customer service was terrible.")
verb_doc = nlp("They kept increasing my phone bill")

def get_compound_pairs(doc, verbose=False):
    """Return tuples of (multi-noun word, adjective or verb) for document."""
    compounds = [tok for tok in doc if tok.dep_ == 'compound'] # Get list of compounds in doc
    compounds = [c for c in compounds if c.i == 0 or doc[c.i - 1].dep_ != 'compound'] # Remove middle parts of compound nouns, but avoid index errors
    tuple_list = []
    if compounds: 
        for tok in compounds:
            pair_item_1, pair_item_2 = (False, False) # initialize false variables
            noun = doc[tok.i: tok.head.i + 1]
            pair_item_1 = noun
            # If noun is in the subject, we may be looking for adjective in predicate
            # In simple cases, this would mean that the noun shares a head with the adjective
            if noun.root.dep_ == 'nsubj':
                adj_list = [r for r in noun.root.head.rights if r.pos_ == 'ADJ']
                if adj_list:
                    pair_item_2 = adj_list[0] 
                if verbose == True: # For trying different dependency tree parsing rules
                    print("Noun: ", noun)
                    print("Noun root: ", noun.root)
                    print("Noun root head: ", noun.root.head)
                    print("Noun root head rights: ", [r for r in noun.root.head.rights if r.pos_ == 'ADJ'])
            if noun.root.dep_ == 'dobj':
                verb_ancestor_list = [a for a in noun.root.ancestors if a.pos_ == 'VERB']
                if verb_ancestor_list:
                    pair_item_2 = verb_ancestor_list[0]
                if verbose == True: # For trying different dependency tree parsing rules
                    print("Noun: ", noun)
                    print("Noun root: ", noun.root)
                    print("Noun root head: ", noun.root.head)
                    print("Noun root head verb ancestors: ", [a for a in noun.root.ancestors if a.pos_ == 'VERB'])
            if pair_item_1 and pair_item_2:
                tuple_list.append((pair_item_1, pair_item_2))
    return tuple_list

get_compound_pairs(adj_doc)
>>>[(customer service, terrible)]
get_compound_pairs(verb_doc)
>>>[(phone bill, increasing)]
get_compound_pairs(example_doc, verbose=True)
>>>Noun:  compound dependency
>>>Noun root:  dependency
>>>Noun root head:  identifies
>>>Noun root head rights:  []
>>>Noun:  compound nouns
>>>Noun root:  nouns
>>>Noun root head:  identifies
>>>Noun root head verb ancestors:  [identifies]
>>>[(compound nouns, identifies)]


来源:https://stackoverflow.com/questions/51308482/wish-to-extract-compound-noun-adjective-pairs-from-a-sentence-so-basically-i-w

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!