词是中文表达语义的最小单位,中文分词是中文文本处理的一个基础步骤,分词的结果对中文信息处理至为关键。

本文先对中文分词方法进行概述,然后简单介绍结巴分词背后的原理。

1. 中文分词概述

中文分词根据实现特点大致可分为两类:基于词典的分词方法、基于统计的分词方法。

1.1 基于词典的分词方法

基于词典的分词方法首先会建立一个充分大的词典,然后依据一定的策略扫描句子,若句子中的某个子串与词典中的某个词匹配,则分词成功。

常见的扫描策略有:正向最大匹配、逆向最大匹配、双向最大匹配和最少词数分词。

1.1.1 正向最大匹配

对输入的句子从左至右,取词典中最长单词的个数作为第一次取词的个数,在词典中进行扫描,若不匹配,则逐字递减;若匹配,则取出当前词,从后面的词开始正向最大匹配,组不了词的字单独划开。其分词基本原则是:词的颗粒度越大越好;切分结果中非词典词越少越好;总体词数越少越好。

1.1.2 逆向最大匹配

分词原则与正向最大匹配相同,但顺序不是从首字开始,而是从末字开始,而且它使用的分词词典是逆序词典,其中每个词条都按逆序方式存放。在实际处理时,先将句子进行倒排处理,生成逆序句子,然后根据逆序词典,对逆序句子用正向最大匹配处理。

1.1.3 双向最大匹配

将正向最大匹配与逆向最大匹配组合起来,对句子使用这两种方式进行扫描切分,如果两种分词方法得到的匹配结果相同,则认为分词正确,否则,按最小集处理。

1.1.4 最少词数分词

即一句话应该分成数量最少的词串,该方法首先会查找词典中最长的词,看是不是所要分词的句子的子串,如果是则切分,然后不断迭代以上步骤,每次都会在剩余的字符串中取最长的词进行分词,最后就可以得到最少的词数。

总结:基于词典的分词方法简单、速度快,效果也还可以,但对歧义和新词的处理不是很好,对词典中未登录的词没法进行处理。

1.2 基于统计的分词方法

基于统计的分词方法是从大量已经分词的文本中,利用统计机器学习模型来学习词的切分规律,从而实现对未知文本的切分。随着大规模语料库的建立,基于统计的分词方法不断受到研究和发展,渐渐成为了主流。

常用的统计学习方法有:隐马尔可夫模型(HMM)、条件随机场(CRF)和基于深度学习的方法。

1.2.1 HMM和CRF

这两种方法实质上是对序列进行标注,将分词问题转化为字的分类问题,每个字有4种词位(类别):词首(B)、词中(M)、词尾(E)和单字成词(S)。由字构词的方法并不依赖于事先编制好的词典,只需对分好词的语料进行训练即可。当模型训练好后,就可对新句子进行预测,预测时会针对每个字生成不同的词位。其中HMM属于生成式模型,CRF属于判别式模型。

1.2.2 基于深度学习的方法

神经网络的序列标注算法在词性标注、命名实体识别等问题上取得了优秀的进展,这些端到端的方法也可以迁移到分词问题上。与所有深度学习的方法一样,该方法需要较大的训练语料才能体现优势,代表为BiLSTM-CRF。

总结:基于统计的分词方法能很好地处理歧义和新词问题,效果比基于词典的要好,但该方法需要有大量人工标注分好词的语料作为支撑,训练开销大,就分词速度而言不如前一种。

在实际应用中一般是将词典与统计学习方法结合起来,既发挥词典分词切分速度快的特点,又利用了统计分词结合上下文识别生词、自动消除歧义的优点。结巴分词正是这一类的代表,下面简单介绍它的实现算法。

2. 结巴分词原理

官方Github上对所用算法的描述为:

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

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

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

下面逐一介绍:

2.1 构造前缀词典

结巴分词首先会依照统计词典dict.txt构造前缀词典。dict.txt含有近35万的词条,每个词条占用一行,其中每一行有3列,第一列为词条,第二列为对应的词频,第三列为词性,构造前缀词典需要用到前两列。

具体做法为:首先定义一个空的python字典,然后遍历dict.txt的每一行,取词条作为字典的键,词频作为对应的键值,然后遍历该词条的前缀,如果前缀对应的键不在字典里,就把该前缀设为字典新的键,对应的键值设为0,如果前缀在字典里,则什么都不做。

这样等遍历完dict.txt后,前缀词典就构造好了。在构造前缀词典时,会累加统计词典里所有词条的词频,累加值等计算最大概率路径时会用到。

2.2 生成有向无环图(DAG)

用正则表达式分割句子后,对每一个单独的子句会生成一个有向无环图。

具体方式为:先定义一个空的python字典,然后遍历子句,当前子句元素的索引会作为字典的一个键,对应的键值为一个python列表(初始为空),然后会以当前索引作为子串的起始索引,不断向后遍历生成不同的子串,如果子串在前缀词典里且键值不为0的话,则把子串的终止索引添加到列表中。

这样等遍历完子句的所有字后,对应的DAG就生成好了。(子串的键值如果是0,则说明它不是一个词条)

2.3 计算最大概率路径

DAG的起点到终点会有很多路径,需要找到一条概率最大的路径,然后据此进行分词。可以采用动态规划来求解最大概率路径。

具体为:从子句的最后一个字开始,倒序遍历子句的每个字,取当前字对应索引在DAG字典中的键值(一个python列表),然后遍历该列表,当前字会和列表中每个字两两组合成一个词条,然后基于词频计算出当前字到句尾的概率,以python元组的方式保存最大概率,元祖第一个元素是最大概率的对数,第二个元素为最大概率对应词条的终止索引。

词频可看作DAG中边的权重,之所以取概率的对数是为了防止数值下溢。有了最大概率路径,分词结果也就随之确定。

2.4 对未登录词采用HMM模型进行分词

当出现没有在前缀词典里收录的词时,会采用HMM模型进行分词。HMM模型有5个基本组成:观测序列、状态序列、状态初始概率、状态转移概率和状态发射概率。分词属于HMM的预测问题,即已知观测序列、状态初始概率、状态转移概率和状态发射概率的条件下,求状态序列。结巴分词已经内置了训练好的状态初始概率、状态转移概率和状态发射概率。

句子会作为观测序列,当有新句子进来时,具体做法为:先通过Viterbi算法求出概率最大的状态序列,然后基于状态序列输出分词结果(每个字的状态为B、M、E、S之一)。

至此,结巴分词的原理就简单介绍完了。

下面举一个简单的例子:

假如待分词的句子为: “这几天都在学自然语言处理”。

首先依据前缀词典生成DAG:

{  0: [0],

1: [1, 2],

2: [2, 3],

3: [3],

4: [4],

5: [5],

6: [6, 7, 9],

7: [7],

8: [8, 9],

9: [9],

10: [10, 11],

11: [11]  }

句子元素对应的索引会作为字典的键,对应键值的第一项与当前索引相同,其余项会与当前索引组成词条,这个词条在前缀词典里且对应键值不为0。

生成的DAG如下:

然后采用动态规划求出的最大概率路径为:

{12: (0, 0),

11: (-9.073726763747516, 11),

10: (-8.620554852761583, 11),

9: (-17.35315508178225, 9),

8: (-17.590039287472578, 9),

7: (-27.280113467960604, 7),

6: (-22.70346658402771, 9),

5: (-30.846092652642497, 5),

4: (-35.25970621827743, 4),

3: (-40.95138241952608, 3),

2: (-48.372244833381465, 2),

1: (-50.4870755319817, 2),

0: (-55.92332690525722, 0)}

最大概率路径按句子索引倒序排列,但分词时会从索引0开始顺序遍历句子。

具体做法为:

首先遍历0,0对应的键值最后一项为0,即词的长度为1,遇到长度为1的词时(即单字)先不分,继续往后看,然后遍历1,1对应的键值最后一项为2,即词的长度为2,这时会把索引为0的单字作为词分割出来,然后接着把索引1、2对应的词分割出来,然后遍历3,3对应的键值最后一项为3,属于单字,先不分,索引4、5同理,然后遍历6,6对应的键值最后一项为9,即词的长度为4,注意,这里索引3、4、5对应的单字序列(即“都在学”)如果不在前缀词典中或者在前缀词典中但键值为0,则会对单字序列采用HMM模型进行分词,否则的话,会对单字序列每个字进行分词,分好之后把索引6、7、8、9对应的词分割出去,然后遍历10,10对应的键值最后一项为11,即词的长度为2,直接把索引10、11对应的词分割出去,至此分词结束。

下面对结巴分词的逻辑进行总结:

在遇到长度>=2的词之前会把它前面出现的所有单字保存下来;

如果保存下来的单字序列长度为0,则直接把当前词分割出去;

如果保存下来的单字序列长度为1,则直接把单字作为词分割出去,然后把后面词分割出去;

如果保存下来的单字序列长度>1,会分两种情况:假如单字序列不在前缀词典中或者在前缀词典中但键值为0,则会对单字序列采用HMM模型进行分词,否则的话,会对单字序列每个字进行分词。

最后分好的词为:['这',  '几天',  '都',  '在',  '学',  '自然语言',  '处理']。

3. 总结

本文先对中文分词方法进行了概述,然后讲解了结巴分词原理。实际应用中,一般将基于词典的分词方法和基于统计的分词方法相结合以达到比较好的效果。除结巴分词外,成熟的中文分词包还有北大中文分词工具、HanLP等,可多了解比较它们的效果。

结巴分词优点_中文分词概述及结巴分词原理相关推荐

  1. java中文分词工具_中文分词工具(LAC) 试用笔记

    一.背景 笔者2年前写过一篇<PHP使用elasticsearch搜索安装及分词方法>的文章,记录了使用ES的分词的实现步骤,最近又需要用到分词,在网上发现一个百度的中文分词项目,中文词法 ...

  2. java lucene 分词器_中文分词器—IKAnalyzer

    对于lucene自带分词器,没有一个能很好的处理中文的分词,因此,我们使用的分词的时候,往往会使用国人开发的一个分词器IKAnalyzer,使用非常简单,只需要将jar包拷入即可. 如果需要扩展词库或 ...

  3. 关键词分词工具_为解决万千竞价员分词痛苦的——厚昌分词工具2.0版 即将正式上线...

    ​​01 竞价推广是企业在进行营销推广时一定不会放过的一种推广方式. 于企业来说,竞价推广是可以以较低的成本,较短的时间,带来更多的精准目标人群,获取较大效益的一种推广方式.于竞价员而言,搭建一个优质 ...

  4. 关键词分词工具_打破繁琐,采用智能分词——厚昌网络分词工具2.0版即将正式上线...

    ​​科技改变生活,随着互联网技术和智能手机的发展,互联网+,成为一种新型突破口,企业与互联网的有机结合,也让企业焕发出新的活力.网络营销,则是互联网技术融入市场营销的一种新营销方式,也是传统营销的继承 ...

  5. java中文分词工具_中文分词常用方法简述

    中文分词 就是将一句话分解成一个词一个词,英文中可以用空格来做,而中文需要用一些技术来处理. 三类分词算法: 1. 基于字符串匹配: 将汉字串与词典中的词进行匹配,如果在词典中找到某个字符串,则识别出 ...

  6. python分词代码_中文分词--最大正向匹配算法python实现

    最大匹配法:最大匹配是指以词典为依据,取词典中最长单词为第一个次取字数量的扫描串,在词典中进行扫描(为提升扫描效率,还可以跟据字数多少设计多个字典,然后根据字数分别从不同字典中进行扫描).例如:词典中 ...

  7. java 中文分词 比较_中文分词工具评估:chinese-segmentation-evaluation

    作者:tiandi,小米AI实验室,智能问答.智能客服方向.

  8. springmvc 优点_深入整合SSM框架引发底层原理——SpringMVC

    MVC概述 在Web系统开发中一般按照视图(View).模型(Model).控制(Controller)三层设计模式进行构建,视图层负责模型数据的渲染,将数据用一定的形式展现给用户:模型层负责监听实体 ...

  9. python中文分词工具_结巴中文分词工具的安装使用 Python分词教程

    结巴分词 中文分词是中文文本处理的一个基础性工作,结巴分词利用进行中文分词.其基本实现原理有三点: 1.基于Trie树结构实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图(DAG) ...

最新文章

  1. Transformer的PyTorch实现
  2. mysql cluster 安装NDB二进制版本
  3. addListener添加事件监听器,第三个参数useCapture (Boolean) 的作用
  4. 张队长主讲这堂 .NET Core技术培训公开课,太原你约不约
  5. python基础-userlist、userdict、userstring
  6. CCF 201503-2 数字排序
  7. java 原子量_JAVA线程10 - 新特性:原子量
  8. SQL从入门到入魔之初入门
  9. mongodb java 执行js脚本_MongoDB编写并执行js脚本
  10. 达内 python培训视频教程
  11. 视频自动生成字幕(免费版)
  12. 万里汇WorldFirst个人和公司帐户注册教程(送$25+0.3%提现费)
  13. python语言保留字有true吗_python语言的保留字
  14. ZIP RAR文件密码破解软件ARCHPR Pro4.54(绿色中文破解版)
  15. 线段树+平衡树(STL) 勤快的love 枫
  16. dot.tk+namecheap.com搭建免费顶级域名+快速动态域名+Dns解析
  17. python随机函数random、画、星轨_如何使用 NVIDIA StyleGAN 生成自己的动漫(老婆)头像...
  18. [历朝通俗演义-蔡东藩-前汉]第012回 戕县令刘邦发迹 杀郡守项梁举兵
  19. 163邮箱免费账号注册,163邮箱申请能免费注册吗?
  20. 计算机图形绘制三棱柱源代码,三棱柱(三棱柱用纸的制作方法)

热门文章

  1. 《leetcode》valid-parentheses
  2. 《程序员面试金典》输出单层节点
  3. 《剑指offer》和为s的连续正数序列
  4. Hadoop使用MultipleOutputs输出多文件或者指定命名
  5. HBase删除和修改操作
  6. 使用 cert-manager 签发免费证书
  7. leetcode-728-Self Dividing Numbers
  8. 利用js实现 禁用浏览器后退| 去除上一个历史记录链接
  9. 学习Java的三十三个建议
  10. jquery自动触发事件