词是自然语言中能够独立运用的最小单位,是自然语言处理的基本单位。

自动分词分析就是利用计算机对自然语言的形态进行分析,判断词的结构和类别等。

最大匹配法(Maximum Match Method)

  • 正向最大匹配算法(Forward MM,FMM)
  • 逆向最大匹配算法(Backward MM,BMM)
  • 双向最大匹配法(Bi-directional MM)

算法流程

前向最⼤匹配算法(FMM):

(1)待切分的汉字串 s1 ,已切分的汉字串 s2(初始为空);

(2)如果 s1 为空串,转到(6);

(3)从 s1 的左边复制⼀个⼦串 w 作为候选词, w 尽可能长,但不超过最⼤词长;

(4)如果在词表中能找到 w,或者 w 的长度为2(这个数值可以自己根据情况设定,通常为词表内最短的词的长度),那么,将 w 和⼀个界词标记⼀起加到 s2 的右边,并从 s1 的左边去掉 w,转 到(2);

(5)去掉w的最后⼀个汉字,转到(4);

(6)结束。

实例

给定词表:

['他', '是', '研究', '研究⽣', '⽣物', '物化', '化学', '⽣物化学', '的', '⼀位', '科学家', '学']

待划分句⼦:

"他是研究⽣物化学的⼀位科学家"

最⼤词长:

MaxWordLength = 8 (汉字)

划分过程

FMM划分过程:

1、考虑子串 "他是研究生物化学" ,判断其不再给定词表中,因此,删除最后一个汉字,考虑子串 "他是研究生物化",再次判断其不再给定词表中,因此,再次删除最后一个汉字;重复这个过程,直到最后只剩一个汉字或考虑的子串在给定的词表中,通过这一轮划分,可以将 '他' 划分出来。

2、将 '他' 从待划分句子中排出,考虑子串 "是研究生物化学的"。重复(1)中的步骤,最终可以把 '是' 划分出来。

3、重复上述的步骤,可以得到最终的划分结果。

FMM划分结果:他/是/研究⽣/物化/学/的/⼀/位/科学家

BMM的原理和FMM差不多,只不过BMM是从后往前划分,如上述例子,BMM先考虑子串 "化学的一位科学家",不再给定词表中,BMM删除的是子串的第一个汉字。

BMM划分结果:他/是/研究/⽣物化学/的/⼀位/科学家

从划分结果可以看出,FMM和BMM的划分并不同,在这个例子中显然BMM的划分更好。

代码实现

# -*- coding:utf-8 -*-def FMM(user_dict, sentence):""""前向最大匹配算法 FMM"""segment_words = []      # 用于保存已经划分好的词max_len = max([len(item) for item in user_dict])    # 获得给定的词表中最长词的长度start = 0   # 起始划分位置,FMM从前往后划分nums = 1    # 记录划分轮数print("FMM:")print("*****开始切分*****")while start != len(sentence):index = start + max_len     # 每一轮划分考虑 index-start=max_len 长度if index > len(sentence):   # 如果当前的 index 位置超过了句子长度,则让其指向句子的最后index = len(sentence)for i in range(max_len):print(sentence[start:index])# 如果当前考虑的词在我们给定的词表中或者词的长度已经等于1,就将其加入到划分好的列表中if (sentence[start:index] in user_dict)\or (len(sentence[start:index]) == 1):segment_words.append(sentence[start:index])start = indexbreakindex -= 1print('当前已切分:', segment_words)print("————第 %d 轮结束————" % nums)nums += 1return segment_wordsdef BMM(user_dict, sentence):""""逆向最大匹配算法 BMM"""# 大部分代码同FMM一致,只需把start转换为end即可segment_words = []max_len = max([len(item) for item in user_dict])end = len(sentence)     # 起始划分位置,BMM从后往前划分nums = 1    # 记录划分轮数print("BMM:")print("*****开始切分*****")while end != 0:index = end - max_len   # 每一轮划分考虑 end-index=max_len 长度if index < 0:index = 0for i in range(max_len):print(sentence[index:end])if (sentence[index:end] in user_dict)\or (len(sentence[index:end]) == 1):segment_words.append(sentence[index:end])end = indexbreakindex += 1print('当前已切分:', segment_words)print("————第 %d 轮结束————" % nums)nums += 1return segment_wordsif __name__ == '__main__':user_dict = ['时间', '就', '是', '生命']      # 给定词表sentence = "时间就是生命"                     # 待划分的例句# 使用FMM划分segment_words = FMM(user_dict, sentence)print("最终结果:\n", segment_words)print()# 使用BMM划分segment_words = BMM(user_dict, sentence)print("最终结果:\n", segment_words[::-1])   # 由于BMM是逆向划分的,将其倒转就与例句中词的出现顺序一致了

上述代码考虑的实例:

词表:['时间', '就', '是', '生命']

例句:"时间就是生命"

划分结果:

FMM:
*****开始切分*****
时间
当前已切分: ['时间']
————第 1 轮结束————
就是
就
当前已切分: ['时间', '就']
————第 2 轮结束————
是生
是
当前已切分: ['时间', '就', '是']
————第 3 轮结束————
生命
当前已切分: ['时间', '就', '是', '生命']
————第 4 轮结束————
最终结果:['时间', '就', '是', '生命']BMM:
*****开始切分*****
生命
当前已切分: ['生命']
————第 1 轮结束————
就是
是
当前已切分: ['生命', '是']
————第 2 轮结束————
间就
就
当前已切分: ['生命', '是', '就']
————第 3 轮结束————
时间
当前已切分: ['生命', '是', '就', '时间']
————第 4 轮结束————
最终结果:['时间', '就', '是', '生命']进程已结束,退出代码为 0

从这个例子可以看出,FMM和BMM的划分结果相同,我们现在将代码的词表和例句改为上述的例子:

词表:['他', '是', '研究', '研究⽣', '⽣物', '物化', '化学', '⽣物化学', '的', '⼀位', '科学家', '学']

例句:"他是研究⽣物化学的⼀位科学家"

划分结果:

FMM:
*****开始切分*****
他是研究
他是研
他是
他
当前已切分: ['他']
————第 1 轮结束————
是研究⽣
是研究
是研
是
当前已切分: ['他', '是']
————第 2 轮结束————
研究⽣物
研究⽣
当前已切分: ['他', '是', '研究⽣']
————第 3 轮结束————
物化学的
物化学
物化
当前已切分: ['他', '是', '研究⽣', '物化']
————第 4 轮结束————
学的⼀位
学的⼀
学的
学
当前已切分: ['他', '是', '研究⽣', '物化', '学']
————第 5 轮结束————
的⼀位科
的⼀位
的⼀
的
当前已切分: ['他', '是', '研究⽣', '物化', '学', '的']
————第 6 轮结束————
⼀位科学
⼀位科
⼀位
当前已切分: ['他', '是', '研究⽣', '物化', '学', '的', '⼀位']
————第 7 轮结束————
科学家
当前已切分: ['他', '是', '研究⽣', '物化', '学', '的', '⼀位', '科学家']
————第 8 轮结束————
最终结果:['他', '是', '研究⽣', '物化', '学', '的', '⼀位', '科学家']BMM:
*****开始切分*****
位科学家
科学家
当前已切分: ['科学家']
————第 1 轮结束————
学的⼀位
的⼀位
⼀位
当前已切分: ['科学家', '⼀位']
————第 2 轮结束————
物化学的
化学的
学的
的
当前已切分: ['科学家', '⼀位', '的']
————第 3 轮结束————
⽣物化学
当前已切分: ['科学家', '⼀位', '的', '⽣物化学']
————第 4 轮结束————
他是研究
是研究
研究
当前已切分: ['科学家', '⼀位', '的', '⽣物化学', '研究']
————第 5 轮结束————
他是
是
当前已切分: ['科学家', '⼀位', '的', '⽣物化学', '研究', '是']
————第 6 轮结束————
他
当前已切分: ['科学家', '⼀位', '的', '⽣物化学', '研究', '是', '他']
————第 7 轮结束————
最终结果:['他', '是', '研究', '⽣物化学', '的', '⼀位', '科学家']进程已结束,退出代码为 0

FMM的划分结果:

['他', '是', '研究⽣', '物化', '学', '的', '⼀位', '科学家']

BMM的划分结果:

['他', '是', '研究', '⽣物化学', '的', '⼀位', '科学家']

可以看出两者的划分结果并不相同。

用python实现FMM和BMM相关推荐

  1. FMM和BMM的python代码实现

    FMM和BMM的python代码实现 FMM和BMM的编程实现,其实两个算法思路都挺简单,一个是从前取最大词长度的小分句,查找字典是否有该词,若无则分句去掉最后面一个字,再次查找,直至分句变成单词或者 ...

  2. FMM和BMM分词题目

    题目:假设词典中包括词{的确,王公,实在,在理,公子}以及所有单字集合,请分别给出句子"王公子说的确实在理"的FMM和BMM分词结果. FMM分词结果: 王公/子/说/的确/实在/ ...

  3. 词频统计,中文分词FMM,BMM博客

    分词 | 双向匹配中文分词算法python实现 https://blog.csdn.net/Elenore1997/article/details/83274720 正向最大匹配算法实现之python ...

  4. 中文分词的古今中外,你想知道的都在这里

    作者:QvQ,夕小瑶,小鹿鹿鹿 前言 分词(word tokenization),也叫切词,即通过某种方式将句子中的各个词语识别并分离开来,使得文本从"字序列"的表示升级为&quo ...

  5. 史上最全的分词算法与工具介绍

    分词(word tokenization),也叫切词,即通过某种方式将句子中的各个词语识别并分离开来,使得文本从"字序列"的表示升级为"词序列"表示.分词技术不 ...

  6. 中文分词算法之--最大匹配法

    中文分词算法之–最大匹配法 ​ 前段时间研究了如何用分词工具进行分词,但是分词中涉及的一些算法,不太了解,所以,准备这段时间专攻分词算法原理,大家有补充,或者建议,欢迎留言. 1. 最大匹配法(Max ...

  7. NLP-基础任务-中文分词算法(1)-基于词典: 机械分词(词典字符串匹配):前向最大匹配、后向最大匹配、双向最大匹配【OOV:基于现有词典,不能进行新词发现处理】

    分词与NLP关系:分词是中文自然语言处理的基础,没有中文分词,我们对语言很难量化,进而很能运用数学的知识去解决问题.对于拉丁语系是不需要分词的. 拉丁语系与亚系语言区别 拉丁语言系不需要分词,因为他们 ...

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

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

  9. 【自然语言处理与文本分析】中文分词的基本原理,如何进行词性标注 使用HMM算法提高准确率

    分词(中文) 本次内容 分词: N-Gram vs.中文分词 分词的难点 法则式分词 统计式分词 词性标注: 词性标注简介 词性标注的难点 词性的种类及意义 保留某些词性的词 分词: N-Gram v ...

最新文章

  1. ‘utf-8‘ codec can‘t decode byte 0xa8 in position 1210: invalid start byte报错解决
  2. android wm 改变大小,Android 屏幕适配经验总结
  3. java 链表实现堆栈_《Java数据结构与算法》笔记-CH5-链表-4用链表实现堆栈
  4. 一个小栗子聊聊JAVA泛型基础
  5. [css] 你知道什么是面向对象的css(oocss)吗?有没有实践过?
  6. 15款精美的 WordPress 电子商务网站模板
  7. 微众银行在联邦推荐算法上的探索及应用(文末附PPT下载链接)
  8. socket编程(三)
  9. Synchronous Bidirectional Inference for Neural Sequence Generation
  10. 网站测试自动化系统—在测试代码中硬编码测试数据
  11. Excel表格数据生成ECharts图表
  12. 局域网共享工具_Win10局域网共享开启工具
  13. 风机盘管介绍,及其控制 (1)
  14. DSP eQEP正交编码
  15. 后台管理系统 - 权限设计
  16. 关系数据库的三大范式以及BCNF范式
  17. 双窗格文件管理器:Commander One PRO Mac中文版
  18. mysql 5.7的my.ini的位置在隐藏文件夹“ProgramData”下面
  19. ac3168无线网卡驱动下载_台式机无线网卡驱动怎么安装
  20. python查看图片的源代码,python网络爬虫源代码(可直接抓取图片)

热门文章

  1. Java代码分析器(一): JDT入门
  2. vue实现分屏_WebRTC如何在Vue.js 配合video标签实现多分屏功能?
  3. “熊猫烧香”主犯:毒王?黑客英雄?
  4. linux 编译-l,GCC编译器下的-L与-l的区别
  5. 关于物联网卡,您想了解的都在这里
  6. python 绘制多分类变量折线图
  7. 孙悟空在大闹蟠桃园的时候,第一天吃掉了所有桃子总数一半多一个,第二天又将剩下的桃子吃掉一半多一个,以后每天吃掉前一天剩下的一半多一个,到第n天准备吃的时候只剩下一个桃子。第一天开始吃的时候一共有多少个
  8. win用户计算机批量添加用户,win10系统巧用cmd命令快速创建新账户的技巧
  9. 使用certbot openresty执行获取 Let’s Encrypt https 免费证书
  10. [java8] Stream流