【问题标题】:Walking throughout syntax tree recursively递归遍历语法树
【发布时间】:2019-09-28 18:54:49
【问题描述】:

我有一个句法分析的句子。例如,“我妈妈想做饭”。解析为 [('My', 1), ('mom', 2), ('wants', -1), ('to', 2), ('cook', 3)]。数字表示单词所依赖的项目的索引:“妈妈”取决于“想要”,“想要”是数组的第二个元素(像往常一样从零开始)。 “Wants”有“-1”,因为那是句子的核心,它不依赖于其他任何东西。 我需要在这里获取“我妈妈”的主题。我该怎么做?

到目前为止,我只尝试编写并非在所有情况下都有效的循环。交易是主题可能包含两个以上的单词,并且该数字未定义。像这样的……

'值'是 [('My', 1), ('mom', 2), ('wants', -1), ('to', 2), ('cook', 3)]

for indx, value in enumerate(values):
    m = morph.parse(value[0])
    if isinstance(m, list):
        m = m[0]
    if 'NOUN' in m.tag:
        if value[1] == str(index[0]): #it checks if the word (part of the subject) depends on the verb
            terms.append([value[0], indx])

if len(terms) > 0:
    term = terms[0][0]
    t = []
    for indx, value in enumerate(values):
        if value[1] == str(terms[0][1]): #it checks if the word depend on the found part of the subject
            m = morph.parse(value[0])
            if isinstance(m, list):
                m = m[0]
            if 'NOUN' in m.tag:
                t.append([value[0], terms[0][0]])

算法应该是这样工作的:遍历整个数组并在找到给定单词的所有依赖项以及这些依赖项的所有依赖项时停止。 (在示例中,“妈妈”的所有依赖项)。请帮忙!

【问题讨论】:

  • 你使用的是哪个库?
  • 我正在使用 pymorphy2
  • @ЕвгенияРубанова pymorphy2 似乎适用于俄语和乌克兰语,而不是英语,尽管您给出的所有句子都是英语。有没有用于英语词法分析的引擎?

标签: python python-3.x syntax tree xml-parsing


【解决方案1】:

抱歉,这么久才回复您。
我终于弄明白了。代码在底部,但我会先解释它是如何工作的:

parse(values) 被调用时,它会遍历值中的句子并为每个单词调用递归getDepth。 ```getDepth`` 计算给定单词和动词之间有多少单词关系。
例如。对于“The”,深度为1,因为它直接调用动词。
对于“King”,它是 2,因为“King”调用“The”而“The”调用动词(其中 call = 有一个指向某个单词的指针


计算完所有深度后,parse 会找到深度最高的单词(“France”)并使用递归 traceFrom() 将主题串在一起。


你真正关心的是parse(),它接受预先解析的字符串,如 [('My', 1), ('mom', 2), ('wants', -1), ('to', 2), ('cook', 3)] 并吐出完整的主题。 对这两个例子都有效,但你应该多测试一些。

values = [('The', 4), ('King', 0), ('of', 1), ('France', 2), ('died', -1)]

#values = [('My', 1), ('mom', 2), ('wants', -1), ('to', 2), ('cook', 3)]

def getDepth(i, s, n = 0):
    print('D is %d' % n)
    if s[i][1] == -1:
        return n
    else:
        return getDepth(s[i][1], s, n+1)

def traceFrom(m, s, dt=[]):
    print('Got n:%d, s:' % m, s)
    if s[m][1] == -1:
        d = []
        n = 0
        for i in range(len(s)):
            if i in dt:
                d.append(s[i][0])
        return " ".join(d)
    else:
        dt.append(m)
        return traceFrom(s[m][1], s, dt)


def parse(sentence):
    d = []
    for i in range(len(sentence)):
        d.append(getDepth(i, sentence))
    m = d.index(max(d))
    print('Largest is ' , d[m], ' of ', d)
    return traceFrom(m, sentence)
print('Subject :', parse(values))

【讨论】:

    【解决方案2】:

    鉴于您的预解析数组,这很容易:

    values = [('My', 1), ('mom', 2), ('wants', -1), ('to', 2), ('cook', 3)]
    
    
    def parseFrom(n, data):
            if values[n][1] != -1:
                    #print('Stepping (%s,%d)' % (values[n][0], values[n][1]))
                    data.append(values[n][0])
                    return parseFrom(values[n][1], data)
            else:
                    #print('At verb')
                    return data
    
    subject = ' '.join(parseFrom(0, []))
    
    print('Sentence has subject:', subject)
    
    

    如果当前单词不是动词,则该函数是递归的,否则将主题作为数组返回。 对不起,如果它不适用于所有句子

    【讨论】:

    • 非常感谢!你的决定非常好,非常适合我的例子!但是我忘了提到我还需要获取单词依赖项的所有依赖项(这是主题的一部分)的情况。例如,[('W', 4), ('X', 3), ('Y', 3),('Z', 0), ('VERB', -1)] 其中主语是 WXYZ .对此感到抱歉:(我对递归决策真的很愚蠢......
    • 你能给我一个(解析的)句子作为例子吗?
    • 是的,[('The', 4), ('King', 0), ('of', 1), ('France', 2), ('died', -1 )] 我这里需要的主题是“法国国王”。
    • 你用什么库来预解析句子?
    • @ЕвгенияРубанова 刚刚注意到您的 [('W', 4), ('X', 3), ('Y', 3),('Z', 0), ( 'VERB', -1)] 句子,它给出了 W X Z,因为第一个索引规则,正在寻找修复...
    猜你喜欢
    • 2018-07-12
    • 2014-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    • 2014-12-21
    相关资源
    最近更新 更多