本文地址https://www.cnblogs.com/oberon-zjt0806/p/12409536.html

#NLP-1 最大匹配算法(MM)

最大匹配算法(Maximum Matching)被用于对一个文段进行词语划分(Word Segmentation)。

注意

这是词元化(Tokenization)算法

此方法不适用于无分隔符的字母语言(e.g.:德语、使用假名替代汉字的日语、被取消分词符的英文等)

但是对汉语这类无词间分隔符但不依赖字母的语言效果拔群

输入输出

graph LR
input1(文段P)
input2(单词表W)
processor(MM)
output(词元表T)

input1--输入-->processor
input2--输入-->processor
processor--输出-->output

算法内容

人话版本(自然描述)

输入:文段\(\small P\),单词表\(\small W\)

过程:对于给定的\(\small P\)和\(\small W\):

  1. 令指针\(\small i\)从\(\small P\)的起点开始
  2. 每当找到最长匹配于\(\small i\)引领文段的单词\(\small w\),则将\(\small w\)加入词元分析表\(\small T\)(一个顺序表结构)中
  3. \(\small i\)向后移动\(\small w\)长度个位置
  4. 回到2,直至\(\small i\)无法向后移动为止

输出:词元分析表\(\small T\)

说明

最长匹配??

这个概念用定义去描述其实很不容易理解,这里直接上例子,比如,有一个字符串

The quick brown fox jumps over a lazy dog

现在给出这么几个字符串:ThTheThe slowThe quick brown fox jumps over a lazy dog and a little duckquick brown

注意,最长匹配的前提是能匹配得上,此外还要求是端点匹配

先看Th,很明显,尽管Th不能完美的匹配上原有字符串,但却是原字符串的子串(Substring),也就是说它能够完美的和原字符串的局部相匹配,而且是从起始位置相匹配,可以暂时认为是原字符串的最长匹配

再看The,和Th一样,其整体能够匹配上原字符串的部分,而且也是从起始位置匹配,因此也可能是最长匹配,这样一来ThThe都能匹配上原字符串,但是

一个字符串在一个给定的字符串集合中只能找到一个最长匹配,而且是尽可能长的那个

考虑到TheTh长,因此The替掉了Th成为了目前的最长匹配

接下来看看The slow,截止到The 都能匹配到原字符串上,但接下来的s无法匹配原字符串,尽管匹配部分的长度比The还长,但很遗憾,The slow只能认为是不匹配

The quick brown fox jumps over a lazy dog and a little duck也是同理,别看它甚至是原字符串的延长串(也就是原字符串是它的子串),但后面多出来的部分匹配不回去,所以也只能认为是不匹配

原字符串是大爷!!

最后再看看quick brown,当然这也是原字符串的子串,而且匹配长度为11,甚至比The的匹配性还强,但是也很遗憾,这并不是从起点匹配的,所以这个无法认为匹配

于是我们得到了结论:

在上述给出的5个字符串中,最长匹配为The

当然,这都是目前的最长匹配,如果我们继续给出The quickThe quick brown、……这个结果还是会跟着变化的,因为:

理论上,从所有字符串构成的全集寻找某一字符串的最长匹配,其结果只能是该字符串本身

为什么对汉语效果拔群??

这里先说对英语吧……

因为是做词元化工作,所以这里暂时无视英语中的空格分隔符

We are talking about weather.
↓ 移除所有分词符
Wearetalkingaboutweather.

当然,我们要对下面的内容做分词,按说分词工作做完后其分割结果应该和移除之前是一样的:We|are|talking|about|weather|.

但如果采用MM算法使用一个标准词库进行匹配,就会是下面这样:

首先从W开始,从词库中寻找从W开始能够最长匹配的字符串,然后非常巧,我们在词典中找到了……Wear!!

……

于是,我们先不管后面能不能分出来,反正分完肯定是这样子:Wear|...|...

很明显这种分法是不行的。

这里面的原因就在于:英语一共就26个字母,随便找若干个字母凑成一个单词的概率还是很大的,特别是移除分隔符后出现大量辅音字母+若干元音字母的情况。

而且,英语中词汇的长度方差很大,短的只有一个字母,长的可以10多个,极端情况下也有40多个的甚至更多,很多短单词会成为一些长单词的子串(we之于wear等),而移除分隔符后两个原本独立的子串被拼合成一个更长的单词也不是什么新鲜事。

一种极端情况:

graph LR
origin("Hear the voice")
obfuscated("Hearthevoice")
mm("Heart|he|voice")

origin--移除分隔符-->obfuscated
obfuscated--MM算法分割-->mm

但是汉语就不一样了,就以GB2312里面的6700多个汉字想随便挑出来几个字就凑巧拼出一个词语还是很困难的,而且词语长度的方差很低,不考虑诗句和歇后语的话,常用的词语和成语绝大多数为2~4个字,较长一些的8个字(比较少),这种情况下即使没有分隔符,两个独立的词语能够被混淆成一个的几率还是比较小的,比如:

一只穿云箭,千军万马来相见
一只|穿云|箭|,|千军万马|来|相见

基本上分割的完全正确,而且即使把标点符号都去掉,也不太影响其分割的结果,斯坦福大学也给出了这样的评价:

Doesn’t generally work in English!

But works astonishingly well in Chinese!

不过其实说到底,这种算法比较依赖于词典(事实上很多词元化算法都挺依赖词典),如果词典编写的不够好,那么即使是汉语其词元化的质量也不尽如人意(特别是汉语需要足够完善的词汇库,其工作量是相当庞大的)。

最新文章

  1. Dropzone.js实现文件拖拽上传
  2. [Erlang 0104] 当Erlang遇到Solr
  3. UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)
  4. Linux下Redis常用命令
  5. 《精通Linux内核必会的75个绝技》知识杂记
  6. ReportViewer技巧汇总
  7. Swift UICollectionView 简单使用
  8. Install and configure Intel NIC teaming on R420
  9. 读取和导出下载 excel 2003,2007 资料
  10. onethink 验证码二维码不显示的问题
  11. [lua]笔试-按字典序列出指指定的序列的位置
  12. Centos7.2 启用iptables
  13. 本地访问服务器上的wamp
  14. windows相关命令记录
  15. shell高效处理文本(1):xargs并行处理
  16. [20181130]如何猜测那些值存在hash冲突.txt
  17. Cookie的存活时间
  18. 1-学习tecplot360
  19. Tomcat的manager app管理web项目
  20. HDU-2586-裸LCA入门-tarjan离线

热门文章

  1. poj-3658 Artificial Lake(模拟)
  2. 一、Shell脚本高级编程实战第一部
  3. day12-模块导入
  4. 用logstash 作数据的聚合统计
  5. 67)PHP,cookie的基本使用和基本原理
  6. 年度Java技术盘点,懂这些技术的程序员2019发展大好
  7. 机器人可以拥有社交智能吗?——微软雷德蒙研究院院长Eric Horvitz与他的个人虚拟助理之梦
  8. 吴裕雄--天生自然HTML学习笔记:HTML 脚本
  9. JVM笔记(二)
  10. 不疯“模”不成活,海尔阿里II代电视将极致进行到底