中文分词是中文文本处理的一个基础步骤,也是中文人机自然语言交互的基础模块,在进行中文自然语言处理时,通常需要先进行分词。“结巴”分词是一个Python 中文分词组件,可以对中文文本进行分词、词性标注、关键词抽取等功能,并且支持自定义词典。

特点
  1. 精确模式,试图将句子最精确地切开,适合文本分析;
  2. 全模式,把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;
  3. 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。
  4. paddle模式,利用PaddlePaddle深度学习框架,训练序列标注(双向GRU)网络模型实现分词。同时支持词性标注。paddle模式使用需安装paddlepaddle-tiny,pip install paddlepaddle-tiny==1.6.1。目前paddle模式支持jieba v0.40及以上版本。jieba v0.40以下版本,请升级jieba,pip install jieba --upgrade 。
安装说明

在python2.x和python3.x均兼容,有以下三种:

1. 全自动安装:easy_install jieba 或者 pip install jieba / pip3 install jieba

2. 半自动安装: 先下载,网址为: http://pypi.python.org/pypi/jieba, 解压后运行: python setup.py install

3. 手动安装: 将jieba目录放置于当前目录或者site-packages目录,

4.如果需要使用paddle模式下的分词和词性标注功能,请先安装paddlepaddle-tiny,pip install paddlepaddle-tiny==1.6.1

主要功能

先介绍主要的使用功能,再展示代码输出。jieba分词的主要功能有如下几种:

1. jieba.cut:该方法接受三个输入参数:需要分词的字符串; cut_all 参数用来控制是否采用全模式;HMM参数用来控制是否适用HMM模型

2. jieba.cut_for_search:该方法接受两个参数:需要分词的字符串;是否使用HMM模型,该方法适用于搜索引擎构建倒排索引的分词,粒度比较细。

3. 待分词的字符串可以是unicode或者UTF-8字符串,GBK字符串。注意不建议直接输入GBK字符串,可能无法预料的误解码成UTF-8,

4. jieba.cut 以及jieba.cut_for_search返回的结构都是可以得到的generator(生成器), 可以使用for循环来获取分词后得到的每一个词语或者使用

5. jieb.lcut 以及 jieba.lcut_for_search 直接返回list

6. jieba.Tokenizer(dictionary=DEFUALT_DICT) 新建自定义分词器,可用于同时使用不同字典,jieba.dt为默认分词器,所有全局分词相关函数都是该分词器的映射。

代码演示:

# encoding=utf-8 import jieba jieba.enable_paddle()# 启动paddle模式。 0.40版之后开始支持,早期版本不支持 strs=["我来到北京清华大学","乒乓球拍卖完了","中国科学技术大学"] for str in strs: seg_list = jieba.cut(str,use_paddle=True) # 使用paddle模式 print("Paddle Mode: " '/'.join(list(seg_list))) seg_list = jieba.cut("我来到北京清华大学", cut_all=True) print("Full Mode: " "/ ".join(seg_list)) # 全模式 seg_list = jieba.cut("我来到北京清华大学", cut_all=False) print("Default Mode: " "/ ".join(seg_list)) # 精确模式 seg_list = jieba.cut("他来到了网易杭研大厦") # 默认是精确模式 print(", ".join(seg_list)) seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造") # 搜索引擎模式 print(", ".join(seg_list))

其中下面的是输出结果。

【全模式】: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学 【精确模式】: 我/ 来到/ 北京/ 清华大学 【新词识别】:他, 来到, 了, 网易, 杭研, 大厦 (此处,“杭研”并没有在词典中,但是也被Viterbi算法识别出来了) 【搜索引擎模式】: 小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所, 后, 在, 日本, 京都, 大学, 日本京都大学, 深造

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

使用命令:

jieba.load_userdict(filename) # filename为自定义词典的路径

在使用的时候,词典的格式和jieba分词器本身的分词器中的词典格式必须保持一致,一个词占一行,每一行分成三部分,一部分为词语,一部分为词频,最后为词性(可以省略),用空格隔开。下面其中userdict.txt中的内容为小修添加的词典,而第二部分为小修没有添加字典之后对text文档进行分词得到的结果,第三部分为小修添加字典之后分词的效果。

示例:

userdict.txt自定义文件

云计算 5 李小福 2 nr 创新办 3 i easy_install 3 eng 好用 300 韩玉赏鉴 3 nz 八一双鹿 3 nz 台中 凱特琳 nz Edu Trust认证 2000

test.py

import jieba jieba.load_userdict("userdict.txt") import jieba.posseg as pseg jieba.add_word('石墨烯') jieba.add_word('凱特琳') jieba.del_word('自定义词') test_sent = ( "李小福是创新办主任也是云计算方面的专家; 什么是八一双鹿\n" "例如我输入一个带“韩玉赏鉴”的标题,在自定义词库中也增加了此词为N类\n" "「台中」正確應該不會被切開。mac上可分出「石墨烯」;此時又可以分出來凱特琳了。" ) words = jieba.cut(test_sent) print('/'.join(words)) print("="*40) result = pseg.cut(test_sent) for w in result: print(w.word, "/", w.flag, ", ", end=' ') print("\n" "="*40) terms = jieba.cut('easy_install is great') print('/'.join(terms)) terms = jieba.cut('python 的正则表达式是好用的') print('/'.join(terms)) print("="*40) # test frequency tune testlist = [ ('今天天气不错', ('今天', '天气')), ('如果放到post中将出错。', ('中', '将')), ('我们中出了一个叛徒', ('中', '出')), ] for sent, seg in testlist: print('/'.join(jieba.cut(sent, HMM=False))) word = ''.join(seg) print('%s Before: %s, After: %s' % (word, jieba.get_FREQ(word), jieba.suggest_freq(seg, True))) print('/'.join(jieba.cut(sent, HMM=False))) print("-"*40)

输出结果:

之前: 李小福 / 是 / 创新 / 办 / 主任 / 也 / 是 / 云 / 计算 / 方面 / 的 / 专家 /

加载自定义词库后: 李小福 / 是 / 创新办 / 主任 / 也 / 是 / 云计算 / 方面 / 的 / 专家 /

jieba中主要基于TF-IDF算法的关键词抽取, 只有关键词抽取并且进行词向量化之后,才好进行下一步的文本分析,可以说这一步是自然语言处理技术中文本处理最基础的一步

jieba分词中含有analyse模块,在进行关键词提取时可以使用下列代码

中文分词技术图解(jieba中文分词详解)(1)

当然也可以使用基于TextRank算法的关键词抽取:

中文分词技术图解(jieba中文分词详解)(2)

这里举一个例子,分别使用两种方法对同一文本进行关键词抽取,并且显示相应的权重值。

中文分词技术图解(jieba中文分词详解)(3)

jieba分词还可以进行词性标注,标注句子分词后每个词的词性,采用和ictclas兼容的标记法,这里只是简单的举一个栗子。

jieba.posseg.POSTokenizer(tokenizer=None) 新建自定义分词器,tokenizer 参数可指定内部使用的 jieba.Tokenizer 分词器。jieba.posseg.dt 为默认词性标注分词器。标注句子分词后每个词的词性,采用和 ictclas 兼容的标记法。除了jieba默认分词模式,提供paddle模式下的词性标注功能。paddle模式采用延迟加载方式,通过enable_paddle()安装paddlepaddle-tiny,并且import相关代码。

import jieba import jieba.posseg as pseg words = pseg.cut("我爱北京天安门") #jieba默认模式 jieba.enable_paddle() #启动paddle模式。 0.40版之后开始支持,早期版本不支持 words = pseg.cut("我爱北京天安门",use_paddle=True) #paddle模式 for word, flag in words: print('%s %s' % (word, flag))

输出:

我 r 爱 v 北京 ns 天安门 ns

paddle模式词性标注对应表如下:

paddle模式词性和专名类别标签集合如下表,其中词性标签 24 个(小写字母),专名类别标签 4 个(大写字母)。

中文分词技术图解(jieba中文分词详解)(4)

原理:将目标文本按行分隔后,把各行文本分配到多个 Python 进程并行分词,然后归并结果,从而获得分词速度的可观提升,基于 python 自带的 multiprocessing 模块,目前暂不支持 Windows

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

import time import jieba jieba.enable_parallel() url = sys.argv[1] content = open(url,"rb").read() t1 = time.time() words = "/ ".join(jieba.cut(content)) t2 = time.time() tm_cost = t2-t1 log_f = open("1.log","wb") log_f.write(words.encode('utf-8')) print('speed %s bytes/second' % (len(content)/tm_cost))

实验结果:在 4 核 3.4GHz Linux 机器上,对金庸全集进行精确分词,获得了 1MB/s 的速度,是单进程版的 3.3 倍。

注意:并行分词仅支持默认分词器 jieba.dt 和 jieba.posseg.dt。

输入参数只接受 unicode

默认模式

result = jieba.tokenize(u'永和服装饰品有限公司') for tk in result: print("word %s\t\t start: %d \t\t end:%d" % (tk[0],tk[1],tk[2]))

word 永和 start: 0 end:2 word 服装 start: 2 end:4 word 饰品 start: 4 end:6 word 有限公司 start: 6 end:10

搜索模式

result = jieba.tokenize(u'永和服装饰品有限公司', mode='search') for tk in result: print("word %s\t\t start: %d \t\t end:%d" % (tk[0],tk[1],tk[2]))

word 永和 start: 0 end:2 word 服装 start: 2 end:4 word 饰品 start: 4 end:6 word 有限 start: 6 end:8 word 公司 start: 8 end:10 word 有限公司 start: 6 end:10

其他词典

有一些开源的自定义词典文件,可以直接使用

  • 占用内存较小的词典文件 https://github.com/fxsjy/jieba/raw/master/extra_dict/dict.txt.small
  • 支持繁体分词更好的词典件 https://github.com/fxsjy/jieba/raw/master/extra_dict/dict.txt.big
  • 下载你所需要的词典,然后覆盖 jieba/dict.txt 即可;或者用 jieba.set_dictionary('data/dict.txt.big')

    ,