自然语言处理的首要任务是分词,将一段文本分割成独立的词语。
中文分词介绍
已经归纳的三种分词如下:
规则分词、统计分词、混合分词规则分词:
通过设立人工词库,按照一定方式进行切分匹配。
正向最大匹配法(Maximum Match Method MM法)的基本思路,假定分词词典中最最长词为 i 个汉字字符,则首先切分待处理文档的前 i 个字符作为匹配子串,在分词词典中查找。如果找到则表示匹配成功,匹配子串作为一个词切分出来。如果在字典中找不到这个词,则匹配失败,然后将匹配字段中的最后一个字去掉对剩下的子串重新匹配。按照这个方法直到匹配成功。
逆向最大匹配算法(Reverse Maximum Match Method, RMM法):其算法描述和MM法基本一致,唯一的不同在于RMM法是从文本的后面开始匹配。
双向最大匹配法 (Bi-directction method):是将MM法和RMM法得到的结果进行比较,然后按照最大匹配原则,选取词数切分最少的作为结果。统计分词
把每个词看做由单个字组成的,如果相连的两个字在不同的文本中出现词数越多,那么这两个词大概率是一个词,当出现的概率高于设定的阈值时我们认为这个”字组“可能会构成一个词。
基于统计的分词一般有两部分内容:建立统计语言模型
对句子进行单词划分,对划分结果进行概率统计,获得概率最大分词方式。
Jieba中文分词工具
Jieba分词结合了基于规则和基于统计这两类方法实现中文分词。通过前缀词典构建可能的有向无环图,通过在该图中的多条分词路径找到最优路线,也就确定了具体分词。对于未记录在词典的词,其使用HMM模型,采用Viterbi算法进行推导(表示我也不知道这个是什么意思)。
Jieba提供三种分词模式:精确分词
试图将句子最精确的分开,适合文文本分析。
全模式分词
把句子中所有可以成词的词语都扫描出来,速度快,但存在歧义。
搜索引擎模式分词
在精确模式的基础上,对长词再切分,提高召回率,适用于搜索引擎分词。
下面是简单的基于Jieba的三种中文分词示例。注意Python打印有中文的list会输出十六进制编码字符,需要特殊处理。首先是搭建环境
开发环境配置安装中文分词框架
sudo pip install jieba安装uniout用于解决直接打印包含中文的list
sudo pip install uniout
Jieba分词示例#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File : jieba_1.py
# @Author: evenvi
# @Date : 19-4-28
# @Desc :
import jieba
import uniout # 中文显示
sent = '我要开发一个智能中文报告舆情分析系统'
seg_list = jieba.cut(sent, cut_all=True)
print('全局模式', '/'.join(seg_list))
seg_list = jieba.cut(sent, cut_all=False)
print('精确模式', '/'.join(seg_list))
seg_list = jieba.cut(sent)
print('默认精确模式', '/'.join(seg_list))
seg_list = jieba.cut_for_search(sent)
print('搜索引擎模式', '/'.join(seg_list))
JIeba中文分词实战 - 分析政府工作报告,提取高频词Top10
高频词一般指出现频率较高且有用的词语,其一定程度上代表了文章所要表达的主要意思。通常可以作为热点、舆论焦点。
高频词提取就是自然语言处理中的TF(Term Frequency)策略。其主要的干扰项如下:标点符号:一般标点符号无任何价值,需要剔除
停用词:像“的“ ”是“ ”了“无意义也要剔除
分析政府工作报告前十的高频词语
报告原文 政府工作报告 /premier/-03/16/content_5374314.htm
将文本复制下来存入文件 "gov.txt"
下面是具体的代码#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File : jieba_gov_report.py
# @Author: evenvi
# @Date : 19-4-28
# @Desc : 使用Jieba对政府工作报告分词
import codecs
import uniout # 中文显示
# 读取待分词文本数据
def get_content(path, encoding='gbk'):
with codecs.open(path, 'r', encoding=encoding
, errors='ignore') as f:
content = ''
for l in f:
l = l.strip()
content += l
return content
# 定义高频词函数
def get_TF(words, topK=10):
tf_dic = {}
for w in words:
tf_dic[w] = tf_dic.get(w, 0) + 1
return sorted(tf_dic.items(), key=lambda x:x[1], reverse=True)[:topK]
def main():
import jieba
reportContent = get_content('./data/reports/gov.txt', encoding='utf-8')
split_words = list(jieba.cut(reportContent))
print('样本之一:'+ reportContent.encode('utf-8') + '\r\n')
print('样本分词效果:' + '/'.join(split_words).encode('utf-8')+ '\r\n')
print('样本的topK(10)词语' + str(get_TF(split_words))+ '\r\n')
if __name__ == '__main__':
main()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File : jieba_gov_report.py
# @Author: evenvi
# @Date : 19-4-28
# @Desc : 使用Jieba对政府工作报告分词
import codecs
import uniout # 中文显示
# 读取待分词文本数据
def get_content(path, encoding='gbk'):
with codecs.open(path, 'r', encoding=encoding
, errors='ignore') as f:
content = ''
for l in f:
l = l.strip()
content += l
return content
# 定义高频词函数
def get_TF(words, topK=10):
tf_dic = {}
for w in words:
tf_dic[w] = tf_dic.get(w, 0) + 1
return sorted(tf_dic.items(), key=lambda x:x[1], reverse=True)[:topK]
def main():
import jieba
reportContent = get_content('./data/reports/gov.txt', encoding='utf-8')
split_words = list(jieba.cut(reportContent))
print('样本之一:'+ reportContent.encode('utf-8') + '\r\n')
print('样本分词效果:' + '/'.join(split_words).encode('utf-8')+ '\r\n')
print('样本的topK(10)词语' + str(get_TF(split_words))+ '\r\n')
if __name__ == '__main__':
main()
分析得到高频词TOP10样本的topK(10)词语[(u',', 806), (u'。', 612), (u'、', 324), (u'的', 216), (u'和', 187), (u'发展', 134), (u'改革', 92), (u'要', 88), (u'“', 63), (u'”', 63)]
显然停用词和标点符号占据了很高的位置,而这类词语对于把控文章毫无意义,需要将这些数据剔除。这里需要用到"停用词典”功能。
stop_words.utf8
修改后的代码如下:#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File : jieba_gov_report.py
# @Author: evenvi
# @Date : 19-4-28
# @Desc : 使用Jieba对政府工作报告分词
import codecs
import uniout # 中文显示
# 读取待分词文本数据
def get_content(path, encoding='gbk'):
with codecs.open(path, 'r', encoding=encoding
, errors='ignore') as f:
content = ''
for l in f:
l = l.strip()
content += l
return content
# 定义高频词函数
def get_TF(words, topK=10):
tf_dic = {}
for w in words:
tf_dic[w] = tf_dic.get(w, 0) + 1
return sorted(tf_dic.items(), key=lambda x:x[1], reverse=True)[:topK]
def main():
import jieba
reportContent = get_content('./data/reports/gov.txt', encoding='utf-8')
split_words = list(jieba.cut(reportContent))
print('样本之一:'+ reportContent.encode('utf-8') + '\r\n')
print('样本分词效果:' + '/'.join(split_words).encode('utf-8')+ '\r\n')
print('样本的topK(10)词语' + str(get_TF(split_words))+ '\r\n')
if __name__ == '__main__':
main()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File : jieba_gov_report.py
# @Author: evenvi
# @Date : 19-4-28
# @Desc : 使用Jieba对政府工作报告分词
import codecs
import uniout # 中文显示
# 读取待分词文本数据
def get_content(path, encoding='gbk'):
with codecs.open(path, 'r', encoding=encoding
, errors='ignore') as f:
content = ''
for l in f:
l = l.strip()
content += l
return content
# 定义高频词函数
def get_TF(words, topK=10):
tf_dic = {}
for w in words:
tf_dic[w] = tf_dic.get(w, 0) + 1
return sorted(tf_dic.items(), key=lambda x:x[1], reverse=True)[:topK]
def stop_words(path):
with codecs.open(path, 'r', encoding='utf-8' , errors='ignore') as f:
return [l.strip() for l in f]
def main():
import jieba
reportContent = get_content('./data/reports/gov.txt', encoding='utf-8')
# split_words = list(jieba.cut(reportContent))
split_words = [x for x in jieba.cut(reportContent) if x not in stop_words('./data/stop_words.utf8')]
print('样本之一:'+ reportContent.encode('utf-8') + '\r\n')
print('样本分词效果:' + '/'.join(split_words).encode('utf-8')+ '\r\n')
print('样本的topK(10)词语' + str(get_TF(split_words))+ '\r\n')
if __name__ == '__main__':
main()
改造之后的高频词TOP!10结果样本的topK(10)词语[(u'发展', 134), (u'改革', 92), (u'加强', 62), (u'推进', 59), (u'建设', 56), (u'新', 54), (u'企业', 51), (u'经济', 46), (u'完善', 43), (u'加快', 43)]
对比第一次的分词结果有了很大提升,这里使用的“停用词典”是一个通用版本,也是《python自然语言处理实践 核心技术与算法》作者提供的。一般实践过程中都是根据自己任务定期维护该词典。
总结
通常情况下针对特定情况下定制“领域词典”以提升分词效果,Jieba提供领域词典功能。
参考: python自然语言处理实践 核心技术与算法
Tags: none
Related Posts:
[尚无相关文章]