0%

结巴分词实践

由于新工作关系的原因,需要用到中文分词去计算两个文本的相关度。中文分词器发展到现在也五花八门,如 .NET 下经常会用到的盘古分词,JAVA 的 IKAnalyzer、庖丁解牛,以 api 服务形式提供的搜狗分词、腾讯文智等。在 Python 下比较常用的中文分词库就是 jieba 分词,结巴分词也致力于成为最好的中文分词库。

jieba 分词的开源地址在 https://github.com/fxsjy/jieba,摘录一下它的描述文档:

  • 支持三种分词模式:
    • 精确模式,试图将句子最精确地切开,适合文本分析;
    • 全模式,把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;
    • 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。
  • 支持繁体分词
  • 支持自定义词典
  • MIT 授权协议

jieba 支持 pip 直接安装:pip install jieba,同时也支持 Python2/Python3,安装完毕后,在 Python 交互窗口输入:

1
2
3
4
Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import jieba
>>>

或者在命令行输入:

1
2
$ python -m jieba -V
Jieba 0.39

证明 jieba 分词器安装成功.

分词模式

jieba 支持三种分词模式:

模式 说明
精确模式 试图将句子最精确地切开,适合文本分析
全模式 把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义
搜索引擎模式 在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词

这三种分词模式是通过两个方法实现的 jieba.cut 以及 jieba.cut_for_search,它们都有各自的扩展方法 jieba.lcut 以及 jieba.lcut_for_search。前者得到的是生成器对象而后者得到的是列表。

jieba.cut

先了解一下 jieba.cut,使用 help(jieba.cut) 我们知道:

1
cut(self, sentence, cut_all=False, HMM=True)

其中:

  • selfjieba.Tokenizer 的实例对象
  • sentence:需要分词的中文句子
  • cut_all:选择分词模式,True 为全模式,默认 False 为精确模式
  • HMM:是否使用 HMM 模型识别未登录的词

jieba.cut_for_search 方法将启用搜索模式对中文进行分词,使用 help(jieba.cut_for_search) 可以知道其签名 signature :

1
cut_for_search(self, sentence, HMM=True)

其中:

  • selfjieba.Tokenizer 的实例对象
  • sentence: 需要分词的中文句子
  • HMM:是否使用 HMM 模型识别未登录的词

jieba.Tokenizer

1
jieba.Tokenizer(dictionary=DEFAULT_DICT)

新建自定义分词器,可用于同时使用不同词典。jieba.dt 为默认分词器 DEFAULT_DICT,所有全局分词相关函数都是该分词器实例的方法。

分词实例

下面一段简短代码查看各种分词模式的差异

1
2
3
4
5
6
7
8
9
# -*- coding=utf-8 -*-
import jieba
s = u'著名的高尔基先生说过:“书籍是人类进步的阶梯。”'
print(u'[精确模式]:%s' % ('/'.join(jieba.cut(s))))
# [精确模式]:著名/的/高尔基/先生/说/过/:/“/书籍/是/人类/进步/的/阶梯/。/”
print(u'[全模式]: %s' % ('/'.join(jieba.cut(s, cut_all=True))))
# [全模式]: 著名/的/高尔基/先生/说/过////书籍/是/人类/进步/的/阶梯///
print(u'[搜索模式] %s' % ('/'.join(jieba.cut_for_search(s))))
# [搜索模式] 著名/的/高尔基/先生/说/过/:/“/书籍/是/人类/进步/的/阶梯/。/”

自定义词典

开发者可以指定自己自定义的词典,以便包含 jieba 词库里没有的词。虽然 jieba 有新词识别能力,但是自行添加新词可以保证更高的正确率。

初始化词典

使用 jieba.load_userdict(f) 可以加载用户定义的词典提高识别率。其中 f 是一个类文件对象(file-like object)或者是词典文件的路径。

一个词典的格式如下:

1
2
3
4
word1 freq1 word_type1
word2 freq2 word_type2
...
Word type may be ignored

其中 word 是词,freq 是这个词出现的次数(可以理解为优先级),word_type 是词性。

如:

1
百度百科 1 n

动态调整词典

有两个方法可以动态调整词典:一个是 add_word 方法,一个是 del_word 方法。

另外还有 suggest_freq 方法调节单个词语的词频,使其可以(或禁止)被分辨出来。如:

1
2
3
4
>>> jieba.suggest_freq("你好吗汤姆", True)
1
>>> print('/'.join(jieba.cut("你好吗汤姆?")))
你好吗汤姆/?
方法 签名 参数说明 说明
add_word add_word(self, word, freq=None, tag=None) word 是要新增的词,freq 是词的优先级,tag 是词的词性 往词典中新增一个词以便它可以被识别出来
del_word del_word(self, word) word 是要排除的词 是从词典中删除某个词的便捷方法
suggest_freq suggest_freq(self, segment, tune=False) segment 是要被切成小节的词,如果不想切割,请整个以 str 输入;tune 为真的话,调整这个词的优先级 调整词频,控制词中字符的链接或分离。注意,如果启用了 HMM 则不会改变结果

关键字提取

使用 jieba 的关键字提取需引用 jieba.analyse 库。

基于 TF-IDF 算法的关键词抽取

使用 jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=()) 可以对中文进行基于 TF-IDF 算法的关键词抽取。

其中:

  • sentence 为待提取的文本
  • topK 为返回几个 TF/IDF 权重最大的关键词,默认值为 20
  • withWeight 为是否一并返回关键词权重值,默认值为 False
  • allowPOS 仅包括指定词性的词,默认值为空,即不筛选

基于 TextRank 算法的关键词抽取

使用 jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v')) 可以对中文进行基于 TextRank 算法的关键字提取。入参和上面的含义相同。

词性标注

jieba.posseg 可以在分词的时候进行词项标注,得到的是 (word, flag) 元组,其中 word 是划分的词,flag 是词性。

1
2
3
4
5
6
7
8
# -*- coding=utf-8 -*-
import jieba.posseg as pseg
s = u'一行人来到了中山大学进行调研工作'

gen = pseg.cut(s)

for word, flag in gen:
print word, flag

输出结果为:

1
2
3
4
5
6
7
8
一行 m
人 n
来到 v
了 ul
中山大学 nt
进行 v
调研 vn
工作 vn

在命令行使用 jieba

在命令行中输入 python -m jieba -h 打印出在命令行中是用 jieba 的帮助信息:

1
python.exe -m jieba [options] filename

其中 filename 是要分词的文本文件。

对于可选参数 options 有以下可选值:

选项 说明
-d [DELIM], --delimiter [DELIM] 使用指定的 DELIM 而不是 ‘/‘ 作为分隔符,如果没有指定 DELIM 则使用空格
-p [DELIM], --pos [DELIM] 输出词性,同时以 DELIM 作为词性分隔符,而不是以默认的 _
-D DICT, --dict DICT 使用 DICT 作为词典
-u USER_DICT, --user-dict USER_DICT 使用用户自定义词典 USER_DICT 一同作为分词词典
-a, --cut-all 使用全模式(忽略词性)
-n, --no-hmm 不使用 HMM 模型
-q, --quiet 不打印任何载入信息

并行分词

jieba 并行分词原理:将目标文本按行分隔后,把各行文本分配到多个 Python 进程并行分词,然后归并结果,从而获得分词速度的可观提升。

基于 python 自带的 multiprocessing 模块,目前暂不支持 Windows。

用法:

  • jieba.enable_parallel(4) # 开启并行分词模式,参数为并行进程数
  • jieba.disable_parallel() # 关闭并行分词模式