jieba 分词的使用和原理浅析

自然语言处理目的在于让计算机“理解”人说的话或者文字,而在中文自然语言处理中第一步是获取语料,第二步就是对语料进行预处理,预处理的一个重要的环节就是对语料进行分词,其目的在于将一句话或者一个段落拆分成许多独立个体的词,这样能够方便后面将词转化成向量。

举个例子:

腾讯 DeepOcean 是一个很棒的技术公众号

当我们自己来读这句话的时候会自动的将这段话分解开理解就像这样:

腾讯 / DeepOcean / 是 / 一个 / 很棒的 / 技术 / 公众号

但是计算机并不会像人类一样去分词,那么就需要我们人类设计相应的算法来帮助计算机做到分词。

1. 现有的分词算法

现在已有的分词算法大体可以分为

  • 基于字符串匹配的分词方法:这种做法需要有一个足够大的可匹配词典,这个词典中存储了很多的词条,然后计算机会与这些已经存在的词条进行匹配,匹配到一个就完成一个分词。
  • 基于理解的分词方法:其做法就是让计算机尽可能模拟人类对于句子的理解,在分词的时候让计算机做到句法分析,语义分析,但是因为汉语言的庞杂以及多变性,这种分词方法并没有那么成熟。
  • 基于统计的分词:这种做法是给出大量的已分好词的文本,然后利用机器学习此文本的分词方式和方法,训练相应的分词模型,从而达到对未知文本的分词,随着大量的语料库的出现以及应用,这种基于统计的分词渐渐的崭露头角。

2. jieba 分词

2.1 安装结巴分词器

  • 全自动安装:easy_install jieba 或者 pip install jieba / pip3 install jieba
  • 半自动安装:先下载 http://pypi.python.org/pypi/jieba/ ,解压后运行 python setup.py install
  • 手动安装:将 jieba 目录放置于当前目录或者 site-packages 目录

最后通过 import jieba 来引用。

2.2 开始分词

这是我们将要处理的文本:

自然语言处理(英语:natural language processing,缩写作 NLP)是人工智能和语言学领域的分支学科。此领域探讨如何处理及运用自然语言;自然语言认知则是指让电脑“懂”人类的语言。自然语言生成系统把计算机数据转化为自然语言。自然语言理解系统把自然语言转化为计算机程序更易于处理的形式。

(1) 精确模式

此模式下面会尽可能的将句子精确切开:

 

jieba-code1

结果:

自然语言/处理/(/英语/:/natural/ /language/ /processing/,/缩写/作/NLP/)/是/人工智能/和/语言学/领域/的/分支/学科/。/此/领域/探讨/如何/处理/及/运用/自然语言/;/自然语言/认知/则/是/指/让/电脑/“/懂/”/人类/的/语言/。/自然语言/生成/系统/把/计算机/数据/转化/为/自然语言/。/自然语言/理解/系统/把/自然语言/转化/为/计算机程序/更/易于/处理/的/形式/。

在上面的结果中我们可以看到分词的效果还是不错的。

(2) 全模式:

此模式下会将所有可能的词语都进行分词:

jieba-code2

结果:

自然/自然语言/语言/处理///英语//natural/language/processing//缩写/写作/NLP//是/人工/人工智能/智能/和/语言/语言学/领域/的/分支/学科///此/领域/探讨/如何/何处/处理/及/运用/自然/自然语言/语言///自然/自然语言/语言/认知/则/是/指/让/电脑///懂///人类/的/语言///自然/自然语言/语言/生成/系统/把/计算/计算机/算机/机数/数据/转化/化为/自然/自然语言/语言///自然/自然语言/语言/理解/系统/把/自然/自然语言/语言/转化/化为/计算/计算机/计算机程序/算机/程序/更易/易于/处理/的/形式/

我们可以看到全模式和精确模式是存在明显的不同的,例如:“自然语言” 这四个字在全模式的情况下进行的处理比较精细。

(3) 搜索引擎模式

在精确模式的基础上,对长词再进行划分,提高分词的召回率,适合用于搜索引擎分词。

 

jieba-code3

结果:

自然/语言/自然语言/处理/(/英语/:/natural/ /language/ /processing/,/缩写/作/NLP/)/是/人工/智能/人工智能/和/语言/语言学/领域/的/分支/学科/。/此/领域/探讨/如何/处理/及/运用/自然/语言/自然语言/;/自然/语言/自然语言/认知/则/是/指/让/电脑/“/懂/”/人类/的/语言/。/自然/语言/自然语言/生成/系统/把/计算/算机/计算机/数据/转化/为/自然/语言/自然语言/。/自然/语言/自然语言/理解/系统/把/自然/语言/自然语言/转化/为/计算/算机/程序/计算机/计算机程序/更/易于/处理/的/形式/。

2.3 自定义添加词和字典

当我们在进行分词的时候可能会有一些新的词语,而这些词语分词器没有进行对应的训练,那么就可能导致分词有误。

 

jieba-code4

结果:

我 / 不是 / 药神 / 这部 / 电影 / 还是 / 很 / 不错 / 的

从上面的结果中我们可以看到结果还可以,但是“我不是药神”这几个字是不应该被分开的。

 

jieba-code5

结果:

我不是药神/这部/电影/还是/很/不错/的

当我们在代码的第3行加入一些自定义的词的时候,我们就发现结果变了,在分词的时候计算机将“我不是药神”这几个字当作了一个词来进行了处理。

当然,我们不可能一个词一个词的进行添加,官方提供了jieba.load_userdict(‘我是文件名字’)这个方法调用想要添加的字典文件。

3. jieba分词算法

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

jieba 在其源码中有一个 dict.txt 文件,基于这个文件生成一个 trie 树,将需要进行分词的句子生成有向无环图 (DAG),通俗来说就是将需要分词的句子对照已有的 trie 树生成几种可能的区分。

 

jieba-code6

就像上面这样我们将需要分词的句子“有意见分歧”对照已存在的trie树生成了一个DAG,那么可能的路径有:

  • 路径1:0-1-3-5    对应切分方案S1:有 / 意见 / 分歧
  • 路径2:0-2-3-5    对应切分方案S2:有意 / 见 / 分歧

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

查找待分词句子中已经切分好的词语, 对该词语查找该词语出现的频率(次数/总数),如果没有该词(既然是基于词典查找进行的分词,应该是有的), 就把词典中出现频率最小的那个词语的频率作为该词的频率, 也就是说P(某词语) = FREQ.get(‘某词语’,min_freq)

根据动态规划查找最大概率路径的方法, 对句子从右往左反向计算最大概率,即P(NodeN)=1.0, P(NodeN-1)=P(NodeN)*Max(P(倒数第一个词))…依次类推, 最后得到最大概率路径, 得到最大概率的切分组合:

 

jieba-code7

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

未登陆词指的是在dict.txt里面没有被记录的词,值得注意的是当我们把dict.txt中的词语全部删除,jieba依然能够进行分词,但是分出来的词大部分长度都为2,其实这个时候使用的就是HMM来进行分词了。

我们可以将中文的词汇按照B(begin–开始的位置)E(end–结束的位置)M(middle–中间的位置)S(singgle–单独成词的位置,没有前也没有后)排列成一个序列,jieba中就是以这种形式来标记中文的词语,举个例子:“深圳”这个词语可以被标记为BE,也就是深/B圳/E,其意义是深是开始的位置,圳是结束的位置,复杂一些的词语“值得关注”会被标记为BMME,也就是开始,中间,中间,结束。

在jieba中对语料进行了训练从而得到了三个概率表,通过训练得到了概率表再加上viterbi算法就可以得到一个概率最大的BEMS序列, 按照B打头, E结尾的方式, 对待分词的句子重新组合, 就得到了分词结果。

 

jieba-code8

例如我们有一个待分词的句子“全世界都在学中国话”,这句话可以得到一个BEMS序列 [S,B,E,S,S,S,B,E,S](注意这个序列是一个假设,不一定正确),接下来我们将序列中的BE放在一起得到一个词,单独的S独立出来,那么我们就可以得到这样的一个分词结果“全/S 世界/BE 都/S 在/S 学/S 中国/BE 话/S”这样我们就得到了一个较为准确的分词结果。

4. 总结

通过上面的三步我们就得到了尽可能正确的分词结果,我们来总结一下。

在上面的文章中我们了解了为什么在中文自然语言处理中需要分词,并且亲自动手实践了jieba分词器,我们发现其在不同的场景中可以使用不同的分词模式,并且还可以添加新词,在使用jieba分词器的基础上我们进一步了解了其实现的原理,感受到了jieba分词器在设计以及实现上的可靠性。

最后希望此时的阅读能够给你带来收获。

发表评论