我有一个使用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')
,但是它不需要其余的内容,反之亦然,如果字符串是一个段落,它可以在同一字符串中找到模式的多个示例。如果有人知道最好的方法或更好的选择,那将真的很有帮助!
答案 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