文章目录
- 自然语言处理系列十七
- 分词工具实战
- Python的Jieba分词
- 总结
自然语言处理系列十七
分词工具实战
分词工具有Java、Python、C++实现的,这里给大家推荐目前最流行的分词工具。CRF++是采用C++语言编写,但可以用Python来调用。HanLP是用Java编写的,也可以用Python调用。IK分词和mmseg4j分词也是用Java编写,经常集成在搜索引擎Solr和Elasticsearch里。下面分别进行讲解这几个开源分词包。
Python的Jieba分词
Jieba 是目前最好的 Python 中文分词组件,它主要有以下 3 种特性:
支持 3 种分词模式:精确模式、全模式、搜索引擎模式
支持繁体分词
支持自定义词典
【代码6.14】 PrefixSpanJob.scala
# 导入 jieba
import jieba
import jieba.posseg as pseg #词性标注
import jieba.analyse as anls #关键词提取
1.分词
可使用 jieba.cut 和 jieba.cut_for_search 方法进行分词,两者所返回的结构都是一个可迭代的 generator,可使用 for 循环来获得分词后得到的每一个词语(unicode),或者直接使用 jieba.lcut 以及 jieba.lcut_for_search 直接返回 list。其中:
jieba.cut 和 jieba.lcut 接受 3 个参数:
需要分词的字符串(unicode 或 UTF-8 字符串、GBK 字符串)
cut_all 参数:是否使用全模式,默认值为 False
HMM 参数:用来控制是否使用 HMM 模型,默认值为 True
jieba.cut_for_search 和 jieba.lcut_for_search 接受 2 个参数:
需要分词的字符串(unicode 或 UTF-8 字符串、GBK 字符串)
HMM 参数:用来控制是否使用 HMM 模型,默认值为 True
#尽量不要使用 GBK 字符串,可能无法预料地错误解码成 UTF-8
1)全模式和精确模式
# 全模式
seg_list = jieba.cut("他来到上海交通大学", cut_all=True)
print("【全模式】:" + "/ ".join(seg_list))
【全模式】:他/ 来到/ 上海/ 上海交通大学/ 交通/ 大学
# 精确模式
seg_list = jieba.cut("他来到上海交通大学", cut_all=False)
print("【精确模式】:" + "/ ".join(seg_list))
【精确模式】:他/ 来到/ 上海交通大学
type(seg_list)
generator
# 返回列表
seg_list = jieba.lcut("他来到上海交通大学", cut_all=True)
print("【返回列表】:{0}".format(seg_list))
【返回列表】:['他', '来到', '上海', '上海交通大学', '交通', '大学']
type(seg_list)
list
2)搜索引擎模式
# 搜索引擎模式
seg_list = jieba.cut_for_search("他毕业于上海交通大学机电系,后来在一机部上海电器科学研究所工作")
print("【搜索引擎模式】:" + "/ ".join(seg_list))
【搜索引擎模式】:他/ 毕业/ 于/ 上海/ 交通/ 大学/ 上海交通大学/ 机电/ 系/ ,/ 后来/ 在/ 一机部/ 上海/ 电器/ 科学/ 研究/ 研究所/ 工作
# 返回列表
seg_list = jieba.lcut_for_search("他毕业于上海交通大学机电系,后来在一机部上海电器科学研究所工作")
print("【返回列表】:{0}".format(seg_list))
【返回列表】:['他', '毕业', '于', '上海', '交通', '大学', '上海交通大学', '机电', '系', ',', '后来', '在', '一机部', '上海', '电器', '科学', '研究', '研究所', '工作']
2)HMM 模型
HMM 模型,即隐马尔可夫模型(Hidden Markov Model, HMM),是一种基于概率的统计分析模型,用来描述一个系统隐性状态的转移和隐性状态的表现概率。在 jieba 中,对于未登录到词库的词,使用了基于汉字成词能力的 HMM 模型和 Viterbi 算法,其大致原理是:
采用四个隐含状态,分别表示为单字成词,词组的开头,词组的中间,词组的结尾。通过标注好的分词训练集,可以得到 HMM 的各个参数,然后使用 Viterbi 算法来解释测试集,得到分词结果。
# 代码实现如下所示:
# 未启用 HMM
seg_list = jieba.cut("他来到了网易杭研大厦", HMM=False) #默认精确模式和启用 HMM
print("【未启用 HMM】:" + "/ ".join(seg_list))
【未启用 HMM】:他/ 来到/ 了/ 网易/ 杭/ 研/ 大厦
# 识别新词
seg_list = jieba.cut("他来到了网易杭研大厦") #默认精确模式和启用 HMM
print("【识别新词】:" + "/ ".join(seg_list))
【识别新词】:他/ 来到/ 了/ 网易/ 杭研/ 大厦
2.繁体字分词
jieba 还支持对繁体字进行分词。
# 繁体字文本
ft_text = """人生易老天難老 歲歲重陽 今又重陽 戰地黃花分外香 壹年壹度秋風勁 不似春光 勝似春光 寥廓江天萬裏霜 """
#全模式
print("【全模式】:" + "/ ".join(jieba.cut(ft_text, cut_all=True)))
【全模式】:人生/ 易/ 老天/ 難/ 老/ / / 歲/ 歲/ 重/ 陽/ / / 今/ 又/ 重/ 陽/ / / 戰/ 地/ 黃/ 花/ 分外/ 香/ / / 壹年/ 壹/ 度/ 秋/ 風/ 勁/ / / 不似/ 春光/ / / 勝/ 似/ 春光/ / / 寥廓/ 江天/ 萬/ 裏/ 霜/ /
# 精确模式
print("【精确模式】:" + "/ ".join(jieba.cut(ft_text, cut_all=False)))
【精确模式】:人生/ 易/ 老天/ 難老/ / 歲/ 歲/ 重陽/ / 今/ 又/ 重陽/ / 戰地/ 黃/ 花/ 分外/ 香/ / 壹年/ 壹度/ 秋風勁/ / 不/ 似/ 春光/ / 勝似/ 春光/ / 寥廓/ 江天/ 萬/ 裏/ 霜/
# 搜索引擎模式
print("【搜索引擎模式】:" + "/ ".join(jieba.cut_for_search(ft_text)))
【搜索引擎模式】:人生/ 易/ 老天/ 難老/ / 歲/ 歲/ 重陽/ / 今/ 又/ 重陽/ / 戰地/ 黃/ 花/ 分外/ 香/ / 壹年/ 壹度/ 秋風勁/ / 不/ 似/ 春光/ / 勝似/ 春光/ / 寥廓/ 江天/ 萬/ 裏/ 霜/
3.添加自定义词典
开发者可以指定自定义词典,以便包含 jieba 词库里没有的词,词典格式如下:
词语 词频(可省略) 词性(可省略)
例如:
创新办 3 i
云计算 5
凱特琳 nz
# 虽然 jieba 有新词识别能力,但自行添加新词可以保证更高的正确率。
1)载入词典
使用 jieba.load_userdict(file_name) 即可载入词典。
# file_name 为文件类对象或自定义词典的路径
# 示例文本
sample_text = "周大福是创新办主任也是云计算方面的专家"
# 未加载词典
print("【未加载词典】:" + '/ '.join(jieba.cut(sample_text)))
【未加载词典】:周大福/ 是/ 创新/ 办/ 主任/ 也/ 是/ 云/ 计算/ 方面/ 的/ 专家
# 载入词典
jieba.load_userdict("userdict.txt")
# 加载词典后
print("【加载词典后】:" + '/ '.join(jieba.cut(sample_text)))
【加载词典后】:周大福/ 是/ 创新办/ 主任/ 也/ 是/ 云计算/ 方面/ 的/ 专家
2)调整词典
使用 add_word(word, freq=None, tag=None) 和 del_word(word) 可在程序中动态修改词典。
jieba.add_word('石墨烯') #增加自定义词语
jieba.add_word('凱特琳', freq=42, tag='nz') #设置词频和词性
jieba.del_word('自定义词') #删除自定义词语
使用 suggest_freq(segment, tune=True) 可调节单个词语的词频,使其能(或不能)被分出来。
# 调节词频前
print("【调节词频前】:" + '/'.join(jieba.cut('如果放到post中将出错。', HMM=False)))
【调节词频前】:如果/放到/post/中将/出错/。
# 调节词频
jieba.suggest_freq(('中', '将'), True)
494
# 调节词频后
print("【调节词频后】:" + '/'.join(jieba.cut('如果放到post中将出错。', HMM=False)))
【调节词频后】:如果/放到/post/中/将/出错/。
Jieba除了有分词功能外,还有词性标注,关键词提取等功能,我们在后面的章节会逐一讲到,接下来的自然语言处理系列十八我们看一下Java的HanLP分词。