Отдельное поддерево NLTK на основе метки - PullRequest
0 голосов
/ 02 октября 2019

У меня есть дерево разбора NLTK, я хочу отделить листья дерева, основываясь только на метках "S". Обратите внимание, что S. не должен перекрывать листья.

Учитывая предложение «Он выиграл Gusher Maraton, заканчивая через 30 минут».

Форма дерева из corenlp:

tree = '(S
  (NP (PRP He))
  (VP
    (VBD won)
    (NP (DT the) (NNP Gusher) (NNP Marathon))
    (, ,)
    (S (VP (VBG finishing) (PP (IN in) (NP (CD 30) (NNS minutes))))))
  (. .))'

Идея состоит в том, чтобы извлечь 2 "S" и их листья, но не перекрывая друг друга. Таким образом, ожидаемый результат должен быть «Он выиграл Gusher Marathon». и «заканчивая через 30 минут».

# Tree manipulation

# Extract phrases from a parsed (chunked) tree
# Phrase = tag for the string phrase (sub-tree) to extract
# Returns: List of deep copies;  Recursive
def ExtractPhrases( myTree, phrase):
    myPhrases = []
    if (myTree.label() == phrase):
        myPhrases.append( myTree.copy(True) )
    for child in myTree:
        if (type(child) is Tree):
            list_of_phrases = ExtractPhrases(child, phrase)
            if (len(list_of_phrases) > 0):
                myPhrases.extend(list_of_phrases)
    return myPhrases
subtexts = set()
sep_tree = ExtractPhrases( Tree.fromstring(tree), 'S')
for sep in sep_tree:
    for subtree in sep.subtrees():
        if subtree.label()=="S":
            print(subtree)
            subtexts.add(' '.join(subtree.leaves()))
            #break

subtexts = list(subtexts)
print(subtexts)

Я получил вывод

['He won the Gusher Marathon , finishing in 30 minutes .', 'finishing in 30 minutes']

Я не хочу манипулировать им на уровне строки, скорее на уровне дерева, поэтому ожидаемый результат будетbe-

["He won the Gusher Marathon ,.",  "finishing in 30 minutes."]
...