当前位置: 首页 >服务端 > 中文分词库jieba介绍

中文分词库jieba介绍

1.jieba库是较好的中文分词词库

2.jieba库分词思想有三步:定义前缀词典,构建字典树;生成句子有向图,路径规划输出最优路径;基于HMM模型求解decoding问题

3.生成句子有向图本质是贝叶斯网络,路径规划实质是求解联合概率分布

4.jieba的HMM模型的隐状态有四种:BMES,基于大量语料库初始化参数(初始概率分布,转移矩阵和发射矩阵)

分词是对文本预处理重要环节,英文分词可以针对空格切分达到很好的效果。而中国文字博大精深,需要用一定的方法处理。本文就介绍基于python第三方库jieba分词库,它是比较好的中文分词词库。jieba库的分词原理主要有三项:

  • 基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的向无环图(DAG)

  • 采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合

  • 对于未登录词,采用了基于汉字成词能力的HMM模型,使用Viterbi算法求解

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

前缀词典与DAG

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

首先是前缀词典的扫描。jieba库是利用了Tier树进行高效扫描,Tier树中文名叫字典树、前缀树。它的用途主要是将字符串整合成树形。

比如由“清华”、“清华大学”、“清白”、“中华”、“华夏”五个中文词构成的Tier树:

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

这个树里面每一个方块代表一个节点,其中根节点Root不代表任何字符;紫色代表分支节点;绿色代表叶子节点。除根节点外每一个节点都只包含一个字符。从根节点到叶子节点,路径上经过的字符连接起来,构成一个词。而叶子节点内的数字代表该词在字典树中所处的链路(字典中有多少个词就有多少条链路),具有共同前缀的链路称为串。

字典树有以下三个特点:

  • 具有相同前缀的词必须位于同一个串内

比如“清华”和“清白”两个词语,都有“清”这个前缀,那么在字典树上只需要构建一个“清”节点即可,这在一定程度减少存储空间。

  • 字典树中的词只可共用前缀,不可共用词的其他部分

比如“华夏”和“中华”,这两个词都有共同的后缀“华”,但在字典树上必须是两条独立的链路,即字典树仅依靠公共前缀压缩字典存储空间。再看“清华大学”这个词语,“大学”也是一个词语,但是“清华大学”的后缀,所以“大学”必须从根节点开始重新构建。

  • 一个完整的词必须从根节点开始,至叶子节点结束

字典树实质是一个有限状态自动机(Definite Automata,DFA),它从一个节点(状态)转移到另一个节点(状态)的行为完全由状态转移函数控制,而状态转移函数本质上是一种映射,这意味着:逐字搜索字典树时,从一个字符到下一个字符比对是不需要遍历该节点的所有子节点的。

构建完字典树后就可以生成句子的有向无环图(DAG)

假设对于待切分的字符串(句子)有m个字符,考虑每个字符左右两边的位置,则有m+1个点,编号从0~m,把候选词看成边,根据前缀词典生成一个切分图。比如句子“我毕业于北京大学”:

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

“我”这条边起点是0,终点是1;“毕业”这条边起点是1,终点是3,依次类推,根据词典,我们可以得到两条路径:

路径1:0-1-3-4-6-8  切分方案S1:我/毕业/于/北京/大学

路径2:0-1-3-4-8      切分方案S2:我/毕业/于/北京大学

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

动态规划

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

对于方案S1和S2,我们最终选取哪种切分方案呢。jieba库的字典树会标记每个词的频率,它存储在dict.txt文件中:

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

该文件每一行代表一个词语,每一行存储【词名 词频 词性】三个字段。

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

注:词性标注表在网上有大量资料,读者可以自行查找

在知道每个词出现的频率之后,就可以基于动态规划的方法来寻找概率最大的分词路径,这里采取从右往左去寻找最优路径。具体怎么做,其实就是算每种路径的联合概率分布,还记得有向无环图(DAG)其实是一种贝叶斯网络嘛,我们在概率图模型中介绍过其联合概率分布的公式:

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

传送门:概率图模型(模型表示)

比如对于上一节的两种路径S1和S2,它其实对应着两个贝叶斯网络:

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

分别计算他们的联合概率分布,最大的那个即为最终切分方案

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

注:jieba分词是从右往左,所以实际中方向与上图箭头相反

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

HMM的译码分词

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

如果遇到一些词典中没有的词语,那怎么办呢。jieba采取了HMM模型进行生成,它主要是进行译码(Decoding)问题:

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

回顾一下HMM模型,要求解上述状态序列,需要知道HMM的参数λ=(π,A,B),即初始状态概率分布π,状态转移矩阵A和发射矩阵B.

传送门:

隐马尔可夫模型(背景介绍)

隐马尔可夫模型(前向算法与后向算法)

隐马尔可夫模型(Baum Welch算法与Viterbi算法)

隐马尔可夫模型(模型推断五大问题)

隐马尔可夫模型(算法流程&实例演示)

那么在jieba库里,这三个参数是什么呢。jieba库首先定义了四种状态BEMS,B是开始,begin位置;E是end,是结束位置;M是middle,是中间位置;S是singgle,单独成词的位置,没有前,也没有后。采用(B、E、M、S)这四种状态来标记中文词语,比如北京可以标注为 BE;中华民族可以标注为BMME,就是开始、中间、中间、结束。

然后采用大量的语料进行训练,得到了HMM的参数λ,分别存储在finalseg目录下的三个文件(prob_start.py、prob_trans.py 、prob_emit.py 、 )

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

我们来大概浏览一下这三个文件的内容,

  • 初始状态分布π

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

  • 状态转移矩阵A:

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

  • 发射矩阵B:

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

jieba库应用

中文分词库jieba介绍 _ JavaClub全栈架构师技术笔记

总结一下,jieba库的分词原理是:生成字典树——给定句子生成DAG——路径规划输出概率最大切分组合——不在字典树的词语基于HMM模型求解Decoding问题

这一节我们简单介绍一下jieba库在代码层面的具体应用。

  • 分词

import jiebajieba.cut(sentence,cut_all=False,HMM=True,use_paddle=False)jieba.cut_for_search(sentence,HMM=True)

cut 方法接受四个输入参数: 需要分词的字符串;cut_all 参数用来控制是否采用全模式;HMM 参数用来控制是否使用 HMM 模型;use_paddl参数是否使用训练序列标注(双向GRU)网络模型实现分词。

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

上面两个方法返回的结构是 generator,利用jieba.lcut 以及 jieba.lcut_for_search 直接返回 list

注:paddle需要额外安装,官网见参考资料

  • 字典

jieba.load_userdict(filename)jieba.add_word(word, freq=None, tag=None)jieba.del_word(word)jieba.suggest_freq(segment, tune=False)

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍load_userdict方法添加自定义词典,词典格式和 dict.txt 一样,词频和词性可省略,顺序不可颠倒;add_word和 del_word可在程序中动态修改词典;suggest_freq可调节单个词语的词频

  • 关键词提取

   

import jieba.analyse#基于TF-IDF算法的关键词抽取jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())jieba.analyse.TFIDF(idf_path=None) #新建TFIDF 实例,idf_path 为IDF 频率文件jieba.analyse.set_idf_path(file_name)# 切换成自定义语料库,file_name为自定义语料库的路径#基于TextRank算法的关键词抽取jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'))jieba.analyse.TextRank()#关键词提取所使用停止词jieba.analyse.set_stop_words(file_name)

sentence为待提取的文本,topK 为返回权重最大的关键词的个数,默认 20,withWeight 为是否一并返回关键词权重值,默认 False,allowPOS 仅包括指定词性的词,默认为空。

TFIDF方法表示新建 TFIDF 实例,同理,TextRank方法新建自定义 TextRank 实例

  • 词性标注

import jiebaimport jieba.posseg as psegwords = pseg.cut(sentence) #jieba默认模式jieba.enable_paddle()words = pseg.cut(sentence, use_paddle=True) # paddle模式for word, flag in words:    print(' %s %s ' % (word, flag))jieba.posseg.POSTokenizer(tokenizer=None)

POSTokenizer 方法是新建自定义分词器,tokenizer 参数可指定内部使用Tokenizer 分词器。jieba.posseg.dt 为默认词性标注分词器。

  • 其他

import jieba#返回词语在原文的起止位置re = jieba.tokenize(sentence,mode='search',HMM=True) #默认模式for i in re:    print("word %s\t\t start: %d \t\t end:%d" % (i[0], i[1], i[2]))#延迟加载,初始化字典jieba.initialize() # 手动初始化(可选)jieba.set_dictionary('data/dict.txt.big')

jieba 采用延迟加载,import jieba 和 jieba.Tokenizer() 不会立即触发词典的加载,一旦有必要才开始加载词典构建前缀字典。也可以改变主词典的路径。

参考资料:

https://github.com/fxsjy/jieba

https://www.paddlepaddle.org.cn/

作者:整得咔咔响
来源链接:https://blog.csdn.net/qq_27388259/article/details/118231359

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaclub.cn/server/68649.html

标签:jieba 分词
分享给朋友:

“中文分词库jieba介绍” 的相关文章