Python nltk 如何解析出英语短语?
花了点时间研究 nltk,也试着去写点代码,我有这样一段文字,
>>> text = "i would't have the Scotland Yarders know it for the world"
这段话里有一个短语, for the world, 有无论如何的意思,参考: https://baike.baidu.com/item/for%20the%20world/8417068
>>> import nltk
>>> from nltk.collocations import *
>>> bigram_measures = nltk.collocations.BigramAssocMeasures()
>>> trigram_measures = nltk.collocations.TrigramAssocMeasures()
>>> text = "i would't have the Scotland Yarders know it for the world"
>>> tokens = nltk.wordpunct_tokenize(text)
>>> finder = BigramCollocationFinder.from_words(tokens)
>>> scored = finder.score_ngrams(bigram_measures.raw_freq)
>>> sorted(bigram for bigram, score in scored)
[("'", 't'), ('I', 'would'), ('Scotland', 'Yarders'), ('Yarders', 'know'), ('for', 'the'), ('have', 'the'), ('it', 'for'), ('know', 'it'), ('t', 'have'), ('the', 'Scotland'), ('the', 'world'), ('would', "'")]
这代码是 google 来的,不是我写的。最后运行的效果,似乎无法辨别出 for the world 这个短语。
我想问,目前的 nltk 能准确识别出来这个短语吗?
Python nltk 如何解析出英语短语?
2 回复
要解析出英语短语,用NLTK的RegexpParser配合语法规则最直接。先分词、标注词性,然后定义短语规则来提取。
比如提取名词短语(NP)和动词短语(VP)的示例:
import nltk
from nltk import RegexpParser
from nltk.tokenize import word_tokenize
# 示例文本
text = "The quick brown fox jumps over the lazy dog."
# 1. 分词和词性标注
tokens = word_tokenize(text)
tagged = nltk.pos_tag(tokens)
# 2. 定义短语语法规则
# NP: 名词短语,如限定词+形容词+名词
# VP: 动词短语,如动词+介词短语
grammar = r"""
NP: {<DT>?<JJ.*>*<NN.*>+} # 可选的限定词 + 多个形容词 + 一个或多个名词
VP: {<VB.*><IN|NP>} # 动词 + 介词或名词短语
"""
parser = RegexpParser(grammar)
# 3. 解析并提取短语
result = parser.parse(tagged)
# 4. 打印结果
print("完整解析树:")
print(result)
# 提取特定短语
print("\n提取的名词短语 (NP):")
for subtree in result.subtrees():
if subtree.label() == 'NP':
print(' '.join(word for word, tag in subtree.leaves()))
print("\n提取的动词短语 (VP):")
for subtree in result.subtrees():
if subtree.label() == 'VP':
print(' '.join(word for word, tag in subtree.leaves()))
# 也可以可视化
result.draw()
关键点:
- 词性标注:
pos_tag是基础,要确保标注准确 - 语法规则:用正则模式定义短语结构,比如
NP: {<DT>?<JJ.*>*<NN.*>+}匹配像"the quick brown fox"这样的名词短语 - 规则调整:根据你的文本特点修改规则,比如添加
PP(介词短语)规则:PP: {<IN><NP>}
如果效果不好:
- 试试用
nltk.chunk.ne_chunk()提取命名实体 - 或者用
stanfordnlp/stanza这些更强大的工具
一句话建议:根据你的具体文本调整语法规则。
bigram 是两个单词的短语,trigram 才是三个词的。你研究花的时间是 5 分钟?

