基于规则的分词是一种机械分词方法,需要不断维护和更新词典,在切分语句时,将语句的每个字符串与词表中的每个次进行逐一匹配,找到则切分,找不到则不予切分。

按照匹配方法来划分,主要有正向最大匹配、逆向最大匹配以及双向最大匹配。

1. 正向最大匹配

正向最大匹配(Maximum Match,MM):

  1. 从左向右取待切分汉语句的m个字符作为匹配字段,m为机器词典中最长词条的字符数。
  2. 查找机器词典并进行匹配。若匹配成功,则将这个匹配字段作为一个词切分出来。 若匹配不成功,则将这个匹配字段的最后一个字去掉,剩下的字符串作为新的匹配字段,进行再次匹配,重复以上过程,直到切分出所有词为止。

比如我们现在有个词典,最长词的长度为5,词典中存在“南京市长”“长江大桥”和 “大桥”3个词。现采用正向最大匹配对句子“南京市长江大桥”进行分词,那么首先从句 子中取出前5个字“南京市长江”,发现词典中没有该词,于是缩小长度,取前4个字“南 京市长”,词典中存在该词,于是该词被确认切分。再将剩下的“江大桥”按照同样方式 切分,得到“江”“大桥”,最终分为“南京市长”“江”“大桥”3个词。显然,这种结果不是我们所希望的。

正向最大匹配法示例代码如下:

class MaximumMatch:"""正向最大匹配的中文分词器"""def __init__(self):self.window_size = 3  # 字典中最长词条的字符数def cut(self, text):global pieceresult = []index = 0  # 前指针text_length = len(text)dictionary = {'研究', '研究生', '声明', '起源'}while text_length > index:for r_index in range(self.window_size+index, index, -1):  # 后指针piece = text[index: r_index]if piece in dictionary:index = r_index - 1breakindex = index + 1result.append(piece)return resultif __name__ == '__main__':text = '研究生命的起源'tokenizer = MaximumMatch()print(tokenizer.cut(text))

输出结果:

['研究生', '命', '的', '起源']

2. 逆向最大匹配

逆向最大匹配简称为RMM法。RMM法的基本原理与MM法大致相同,不同的是分词切分的方向与MM法相反。

逆向最大匹配法从被处理文档的末端开始匹配扫描,每次取最末端的m个字符(m为词典中最长词数作为匹配字段,若匹配失败,则去掉匹配字段最前面的一个字,继续匹配。相应地,它使用的分词词典是逆序词典,其中的每个词条都将按逆序方式存放。在实际处理时,先将文档进行倒排处理,生成逆序文档。然后,根据逆序词典,对逆序文档用正向最大匹配法处理即可。

由于汉语中偏正结构较多,若从后向前匹配,可以适当提高精确度。所以,逆向最大匹配法比正向最大匹配法的误差要小。统计结果表明,单纯使用正向最大匹配的错误率为1/169,单纯使用逆向最大匹配的错误率为1/25。比如之前的“南京市长江大桥”,按照逆向最大匹配,最终得到“南京市”“长江大桥”的分词结果。当然,如此切分并不代表完全正确、可能有个叫“江大桥”的“南京市长”也说不定。

逆向最大匹配法示例代码如下:

class ReverseMaximumMatch:"""逆向最大匹配"""def __init__(self):self.window_size = 3def cut(self, text):result = []right = len(text)  # 右指针dic = {'研究', '研究生', '生命', '命', '的', '起源'}global piecewhile right > 0:for left in range(right - self.window_size, right):  # 固定右指针,左指针逐渐右移piece = text[left: right]  # 切片if piece in dic:  # 当命中时right = left + 1  # 命中更新breakright = right - 1  # 自然更新result.append(piece)result.reverse()return resultif __name__ == '__main__':text = '研究生命的起源'rmm_tokenizer = ReverseMaximumMatch()print(rmm_tokenizer.cut(text))

输出结果:

['研究', '生命', '的', '起源']

3. 双向最大匹配

双向最大匹配法是将正向最大匹配法得到的分词结果和逆向最大匹配法得到的结果进行比较,然后按照最大匹配原则,选取词数切分最少的作为结果。据SunM.s.和 Benjamin K…研究表明,对于中文中90.0%左右的句子,正向最大匹配和逆向最大匹配的切分结果完全重合且正确,只有大概9.0%的句子采用两种切分方法得到的结果不一样,但其中必有一个是正确的(歧义检测成功),只有不到1.0%的句子,或者正向最大匹配和逆向最大匹配的切分结果虽重合却都是错的,或者正向最大匹配和逆向最大匹配的切分结果不同但两个都不对(歧义检测失败)。这正是双向最大匹配法在实用中文信息处理系统中得以广泛使用的原因所在。

前面列举的“南京市长江大桥”采用双向最大匹配法进行切分,中间产生“南京市/江/大桥”和“南京市/长江大桥”两种结果,最终选取词数较少的“南京市/长江大桥”这一结果。

双向最大匹配的规则如下所示:

  1. 如果正反向分词结果词数不同,则取分词数量较少的那个结果(上例:“南京市江/大桥”的分词数量为3,而“南京市/长江大桥”的分词数量为2,所以返回分词数量为2的结果)
  2. 如果分词结果词数相同,则:
    ① 分词结果相同,就说明没有歧义,可返回任意一个结果。
    ② 分词结果不同,返回其中单字较少的那个。比如前文示例代码中,正向最大匹配返回的结果为“[‘研究生’,‘命’,‘的起源’]”,其中单字个数为2个;而逆向最大匹配返回的结果为“[研究’,生命’, ‘的’,‘起源’]",其中单字个数为1。所以返回的是逆向最大匹配的结果。

代码如下:

class BidirectionalMaximumMatch:"""双向最大匹配"""def _count_single_char(self, world_list: List[str]):"""统计单字成词的个数"""return sum(1 for word in world_list if len(word) == 1)def cut(self, text: str):mm = MaximumMatch()rmm = ReverseMaximumMatch()f = mm.cut(text)b = rmm.cut(text)if len(f) < len(b):return felif len(f) > len(b):return belse:return b if self._count_single_char(f) >= self._count_single_char(b) else fif __name__ == '__main__':text = '研究生命的起源'bmm = BidirectionalMaximumMatch()print(bmm.cut(text))

输出结果:

['研究', '生命', '的', '起源']

基于规则的分词一般都较为简单高效,但是词典的维护面临很庞大的工作量。在网络发达的今天,网络新词层出不穷,很难通过词典覆盖所有词。另外,词典分词也无法区分歧义以及无法召回新词。


在实际项目中,我们是否会考虑使用规则分词?
虽然使用规则分词的分词准确率看上去非常高,但是规则分词有几个特别大的问题:
① 不断维护词典是非常烦琐的,新词总是层出不穷,人工维护费时费力;
② 随着词典中条目数的增加,执行效率变得越来越低;
③ 无法解决歧义问题。
所以在这里不建议采用规则分词法。

【NLP】中文分词方法:规则分词(正向最大匹配、逆向最大匹配、双向最大匹配)相关推荐

  1. Java---中文词匹配 正向、逆向和双向最大匹配算法

    完成正向.逆向和双向最大匹配算法 import java.io.*; import java.util.*;/*** 正向最大匹配* 逆向最大匹配* 双向最大匹配*/ public class Two ...

  2. 【Python自然语言处理】中文分词技术——规则分词

    中文分词方法 本文参考自书籍<Python自然语言处理实战:核心技术与算法> 用做个人的学习笔记和分享 1. 规则分词 规则分词是一种机械分词方法,主要通过维护词典,在切分语句时将语句的每 ...

  3. 【自然语言处理】正向、逆向、双向最长匹配算法的 切分效果与速度测评

    本文摘要 · 理论来源:[统计自然语言处理]第七章 自动分词:[自然语言处理入门]第二章 词典分词: · 代码目的:手写三种算法:正向最长匹配.逆向最长匹配.双向最长匹配,比较它们的单词切分效果与速度 ...

  4. 11大Java开源中文分词器的使用方法和分词效果对比,当前几个主要的Lucene中文分词器的比较...

    本文的目标有两个: 1.学会使用11大Java开源中文分词器 2.对比分析11大Java开源中文分词器的分词效果 本文给出了11大Java开源中文分词的使用方法以及分词结果对比代码,至于效果哪个好,那 ...

  5. 中文分词方法汇总笔记

    中文分词方法汇总笔记 分词难点 分词方法 传统基于字典(规则分词) 基于机器学习的分词方法 统计分词 语言模型 隐马尔可夫 HMM 模型 其他 分词工具和云服务 其他 感谢知乎 @华天清 的总结 分词 ...

  6. 简单理解NLP中文分词

    什么是中文分词 中文分词指将一个汉字序列切分成一个个单独的词. 中文分词的难题 分词规则(粒度)问题:不同应用对粒度的要求不一样,比如"百度搜索"可以是一个词也可以是两个词 消除歧 ...

  7. 计算机毕设——中文分词方法研究与实现

    毕业论文 中文分词方法研究与实现 1.课题意义及目标 中文分词技术不断发展,各种中文分词系统层出不穷.中文分词技术应用也原来越广泛.如搜索引擎的应用.语音识别系统.机器翻译.自动分类校对等.学生应通过 ...

  8. 中文分词算法python代码_中文分词算法之最大正向匹配算法(Python版)

    最大匹配算法是自然语言处理中的中文匹配算法中最基础的算法,分为正向和逆向,原理都是一样的. 正向最大匹配算法,故名思意,从左向右扫描寻找词的最大匹配. 首先我们可以规定一个词的最大长度,每次扫描的时候 ...

  9. 基于N-gram的双向最大匹配中文分词

    • 摘要 这次实验的内容是中文分词.将一个句子的所有词用空格隔开,将一个字串转换为一个词序列. 而我们用到的分词算法是基于字符串的分词方法中的正向最大匹配算法和逆向最大匹配算法.然后对两个方向匹配得出 ...

  10. 中文分词原理及分词工具介绍

    中文分词学习记录 中文分词 实现方法 基于字符串匹配的分词方法 基于理解的分词方法 基于统计的分词方法 工具介绍 结巴分词 SnowNLP 北大PKUSEG 中文分词 首先,我们将介绍中文分词的思想和 ...

最新文章

  1. MySQL绿色版的安装
  2. [教程]JS从糊涂到明白:一步一步编写计算器3 – 功能扩展
  3. 【高德地图开发3】---地图显示
  4. android按钮防止重复点击事件,实例详解Android解决按钮重复点击问题
  5. jmeter 用户数 线程数_如何使用jmeter编写TCP测试脚本
  6. excel二极管伏安特性曲线_从交流电转直流电出发调研二极管的使用
  7. 一些系统事件的手动触发方法
  8. 苏州银行对公定存通项目
  9. MinGW-w64离线安装包,环境配置(Windows)
  10. 进阶篇:3.4.1)机械加工件-不同制造工艺详解和对应设备
  11. 废粉盒在哪里_复印机提示“废粉盒满”“请及时更换废粉盒”
  12. 少数者博弈 matlab,复杂网络中的少数者博弈研究
  13. PMP知识点总结—合同类型
  14. jike2012年5月实习题
  15. 机器学习笔记(四)——正则化
  16. 计算机图形学——反走样技术
  17. google authenticator python_谷歌验证器(Google Authenticator)
  18. css中滑轮中是如何做的,横向的网页如何实现鼠标滑轮横向移动?_html/css_WEB-ITnose...
  19. 微信小程序 父子组件通讯/传值
  20. 远程桌面端口映射如何设置

热门文章

  1. Unity 自定义standard shader
  2. thinkphp 2.x 任意代码执行
  3. Blast2GO-Pro心得
  4. 新浪UC端自动登录小工具和分析UC端登录
  5. HTTPS 与 SSL 证书
  6. 新加坡国际学校IB课程体系
  7. sony相机二次开发sdK C语言,sdk与开放API协议支持二次开发的摄像头
  8. python QQ聊天机器人,qqbot 使用简介
  9. 李治军操作系统 笔记
  10. 手把手教你搭建免费云平台——新浪云