首先使用NLTK的分块提取所有名词短语(代码复制自here):
import nltk
import re
import pprint
from nltk import Tree
import pdb
patterns="""
NP: {<JJ>*<NN*>+}
{<JJ>*<NN*><CC>*<NN*>+}
{<NP><CC><NP>}
{<RB><JJ>*<NN*>+}
"""
NPChunker = nltk.RegexpParser(patterns)
def prepare_text(input):
sentences = nltk.sent_tokenize(input)
sentences = [nltk.word_tokenize(sent) for sent in sentences]
sentences = [nltk.pos_tag(sent) for sent in sentences]
sentences = [NPChunker.parse(sent) for sent in sentences]
return sentences
def parsed_text_to_NP(sentences):
nps = []
for sent in sentences:
tree = NPChunker.parse(sent)
print(tree)
for subtree in tree.subtrees():
if subtree.label() == 'NP':
t = subtree
t = ' '.join(word for word, tag in t.leaves())
nps.append(t)
return nps
def sent_parse(input):
sentences = prepare_text(input)
nps = parsed_text_to_NP(sentences)
return nps
if __name__ == '__main__':
print(sent_parse('I ate peanut butter and beef burger and a cup of coffee for breakfast.'))
这将 POS 标记您的句子并使用正则表达式解析器来提取名词短语。
1.定义和优化你的名词短语正则表达式
您需要更改 模式 正则表达式来定义和优化您的名词短语。
例如,告诉解析器一个 NP 后跟一个协调器 (CC),如 ''and'',另一个 NP 本身就是一个 NP。
2.从 NLTK 词性标注器更改为斯坦福词性标注器
我还注意到 NLTK 的词性标注器表现不佳(例如,它认为 had花生 是动词短语。如果需要,您可以将词性标注器更改为 Stanford Parser。
3.删除较小的名词短语:
在您提取了一个句子的所有名词短语后,您可以删除属于较大名词短语一部分的名词短语。例如,在以下示例中,应该删除 beef burger 和 peanut butter,因为
它们是更大的名词短语花生酱和牛肉汉堡的一部分。
4.删除食物词典中没有单词的名词短语
你会得到像school bus这样的名词短语。如果你可以从维基百科或 WordNet 编译的食物词典中没有学校和公共汽车,那么你删除名词短语。在这种情况下,请删除 cup 和 breakfast,因为它们希望不在您的食物词典中。
当前代码返回
['peanut butter and beef burger', 'peanut butter', 'beef burger', 'cup', 'coffee', 'breakfast']
输入
print(sent_parse('I ate peanut butter and beef burger and a cup of coffee for breakfast.'))