自然语言应用很多,也是人工智能应用比较成熟的技术领域。下面就是一个选择一个文档的主题的例子。该例子基于nltk框架实现,包含分句,分词,词性标注,命名实体识别;然后根据规则打分,得到主题语句。
本例子纯体验下NLP的趣味性,选择的内容来自《中国日报》英文版的一篇报道。
实现代码
import nltk
# 1. 读取文本数据
with open('datasets/news.txt','r') as fd:
text = fd.read()
# 2. 分句
list_sentences = nltk.sent_tokenize(text)
# 3. 分词处理(根据文本顺序编号)
# 转换为枚举类型,产生编号
enum_sentences = enumerate(list_sentences)
# 遍历分词,统计
results = [] # 存放结果数据(编号,分词数量,名词数量,命名实体数,得分,句子)
for sent_no, sentence in enum_sentences:
words = nltk.word_tokenize(sentence)
# 3.1. 对分词做数据处理:统计分词数量
words_num = len(words)
# 3.2. 对分词做数据处理:对分词做词性标记处理
words_tags = nltk.pos_tag(words)
# 3.3. 对分词做数据处理:根据分词的词性标记,统计名词的数量(寻找摘要的重要步骤)
# 根据词性标记,得到名词列表
words_nouns = [word for word, pos in words_tags if pos in ['NN', 'NNP']]
# 统计名词数量
nouns_num = len(words_nouns)
# 3.4. 对分词做数据处理:对词性标记做命名实体识别
words_ners = nltk.ne_chunk(words_tags)
# 3.5. 对分词做数据处理:统计命名实体的数量(判定是否是nltk.tree.Tree)
# 命名实体的类型是nltk.tree.Tree,非命名实体是tuple
chunk_named = [chunk for chunk in words_ners if type(chunk) == nltk.tree.Tree]
chunk_num = len(chunk_named)
# 3.6. 计算得分:根据上面命名实体的数量,名词的数量,分词的数量三个值计算主题得分
score = (chunk_num + nouns_num) / float(words_num)
# 3.7. 得到分词的相关信息:(编号,分词数量,名词数量,命名实体数,得分,句子)
results.append((sent_no, words_num, nouns_num, chunk_num, score, sentence))
# 4. 根据分词处理结果,按照得分排序,得分最高的就是文档的主题句
results_sorted = sorted(results, key=lambda x: x[4], reverse=True) # 从高到低排序
# 输出得分最高的
# for result in results_sorted:
# print(result[4], "\t", result[5])
print(results_sorted[0][4], "\t", results_sorted[0][5])
运行的输出结果
- 选择排名靠前的几个句子就可以看成是文档的摘要。选择规则是得分计算公式:(名词数 + 命名实体数) / 单词数;所谓摘要句子就是名词与命名实体最多的句子。
- 计算的得分:0.5813953488372093
- 主题句如下,目测基本上可以作为这篇新闻的主题摘要:
Premier Li Keqiang, ROK President Moon Jae-in and Japanese Prime Minister Shinzo Abe also laid out a blueprint for trilateral cooperation for the next decade as they convened in Chengdu, Sichuan province, for the eighth China-Japan-ROK leaders' meeting.
- 说明:
- 其实还有更好的规则可以选择更好的主题句,当然也可以用机器学习来学习选择主题句。