检查元组列表的顺序

Checking the order of a list of tuples

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

我试图找到特定字符串的 "intent" 以便将其附加到数据框,因此我需要一种方法来生成 syntax/grammar 规则。

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')

但它不需要其余部分,反之亦然,如果该字符串是一个段落,它可以在同一个字符串中找到该模式的多个示例。如果有人知道执行此操作的最佳方法或更好的替代方法,那将非常有帮助!

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

下面是一个简单的暴力破解方法:

标记字符串

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