检查元组列表的顺序

时间:2019-08-29 15:13:19

标签: python python-3.x nlp nltk part-of-speech

我有一个使用NLTK的PoS标记器从字符串生成的元组列表。

我试图找到特定字符串的“意图”以便将其附加到数据帧,因此我需要一种生成语法/语法规则的方法。

string = "RED WHITE AND BLUE"

string_list = nltk.pos_tag(a.split())

string_list = [('RED', 'JJ'), ('WHITE', 'NNP'), ('AND', 'NNP'), ('BLUE', 'NNP')]

字符串的大小各不相同,从2-3个元素一直到完整的段落(40-50 +),所以我想知道是否可以创建一般形式或规则来解析句子

因此,如果我想在列表中找到模式,则示例伪代码输出将是:

string_pattern = "I want to kill all the bad guys in the Halo Game"

pattern = ('I', 'PRP') + ('want', 'VBP') + ('to', 'TO') + ('kill:', 'JJ') + ('all', 'DT') + ('bad', 'JJ') + ('guys', 'NNS') + ('in', 'IN') + ('Halo', 'NN') + ('Game', 'NN')

理想情况下,我可以在标记的字符串中匹配模式的一部分,因此它可以找到:

('I', 'PRP') + ('want', 'VBP') + ('to', 'TO') + ('kill:', 'JJ')

,但是它不需要其余的内容,反之亦然,如果字符串是一个段落,它可以在同一字符串中找到模式的多个示例。如果有人知道最好的方法或更好的选择,那将真的很有帮助!

1 个答案:

答案 0 :(得分:1)

我能想到的最简单的方法是使用蛮力(当然,您可以对其进行调整,甚至可以使用一些机器学习来帮助查找易于匹配的类)。

一个简单的蛮力方法如下:

标记字符串

string_list = nltk.pos_tag(a.split())

创建所需标签列表

pos_tags = ["NN", "VBP", "NN"]

以下功能将能够检查此模式是否出现:

def find_match(string_list, pos_tags)

    num_matched = 0
    match_start_pos = 0
    matched = False
    #Enumerating gives you an index to compare to enable you to find where matching starts
    for idx, tuple in enumerate(string_list):
        if tuple[1] == pos_tags[num_matched]:
            num_matched += 1
            if num_matched == 0:
                match_start_pos = idx
        else: 
            num_matched = 0
        if num_matched == len(pos_tags):
            matched = True
            break
    return (matched, match_start_pos)

更现实的是:

现在,更实际的是,假设您属于平民保护机构,并且想知道在校学生提到杀害的任何推文。您以某种方式过滤了这些推文,并想检查是否有人想杀死其他人。

只需稍作修改,您就可以实现类似的目标(以下想法由Frame Semantics推动):

killing_intent_dict = {"PRP":set("I", "YOU", "He", "She"), "V": set("kill"), "NNP":set("All", "him", "her")}
if find_match_pattern(string_list, killing_intent_dict):
#    someone wants to kill! Call 911

def find_match_pattern(string_list, pattern_dict) 
    num_matched = 0
    match_start_pos = 0
    matched = False
    #Enumerating gives you an index to compare to enable you to find where matching starts
    for idx, tuple in enumerate(string_list):
        if tuple[1] == pattern_dict.keys()[num_matched]:
            if tuple[0] in pattern_dict[tuple[1]]:
                num_matched += 1
                if num_matched == 0:
                    match_start_pos = idx
            else:
                num_matched = 0
        else: 
            num_matched = 0
        if num_matched == len(pattern_dict):
            matched = True
            break
    return (matched, match_start_pos)

请记住,这都是实验性的,需要大量的手工编码。您可以向其添加NER标签,以便抽象名称。

添加了另一种可能性,类似于我在硕士研究中使用的可能性:

您可以创建一个包含动作,代理和意图并将它们连接在一起的图形,而不是使用线性蛮力机制。然后,在程序读取输入时,您将使用某种图扩展算法。您可以在我的研究中阅读更多内容,但请记住,您所问的主题(自然语言理解)是深入而又正在开发中的:https://drive.google.com/open?id=12gWLx2saFe5mZI96roUG_p1YfzrqVNbx