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

关键点:

  1. 词性标注pos_tag是基础,要确保标注准确
  2. 语法规则:用正则模式定义短语结构,比如NP: {<DT>?<JJ.*>*<NN.*>+}匹配像"the quick brown fox"这样的名词短语
  3. 规则调整:根据你的文本特点修改规则,比如添加PP(介词短语)规则:PP: {<IN><NP>}

如果效果不好:

  • 试试用nltk.chunk.ne_chunk()提取命名实体
  • 或者用stanfordnlp/stanza这些更强大的工具

一句话建议:根据你的具体文本调整语法规则。


bigram 是两个单词的短语,trigram 才是三个词的。你研究花的时间是 5 分钟?

回到顶部