[转]关于MMSEG分词算法

标签: mmseg 分词 算法 | 发表时间:2013-12-11 14:44 | 作者:bjzhkuang
出处:http://www.iteye.com

转自:http://hi.baidu.com/catro/item/5c76247c0ff6a9376f29f6ed

MMSEG是中文分词中一个常见的、基于词典的分词算法(作者主页:http://chtsai.org/index_tw.html),简单、效果相对较好。由于它的简易直观性,实现起来不是很复杂,运行速度也比较快。关于算法的原文,可以参 见:http://technology.chtsai.org/mmseg/
总的来说现在的中文分词算法,大概可以笼统的分为两大类:一种基于词典的,一种是非基于词典的。
基于词典的分词算法比较常见,比如正向/逆向最大匹配,最小切分(使一句话中的词语数量最少)等。具体使用的时候,通常是多种算法合用,或者一种为主、多种为辅,同时还会加入词性、词频等属性来辅助处理(运用某些简单的数学模型)。
非 基于词典的算法,一般主要是运用概率统计、机器学习等方面的方法,目前常见的是CRF(Conditional random field, http://en.wikipedia.org/wiki/Conditional_random_field)。此类方法可以让计算机根据现成的资 料,“学习”如何分词。具体的实现可参考(http://nlp.stanford.edu/software/segmenter.shtml)。
一般来说,这两类方法各有优缺点:基于词典的方法,实现、部署比较容易,但是分词精度有限,且对于未登录 词(词典里没有的词语)识别较差;非基于词 典的方法,速度较快,对未登录词识别效果较好,能够根据使用领域达到较高的分词精度,但是实现比较复杂,通常需要大量的前期工作。
MMSEG是一种基于词典的分词算法,以正向最大匹配为主,多种消除歧义的规则为辅。下面来具体看一下:
根 据作者在原文中的阐述,对MMSEG的解释分为“匹配算法(Matching algorithm)”和“消除歧义的规则(Ambiguity resolution rules)”这两部分。“匹配算法”是说如何根据词典里保存的词语,对要切分的语句进行匹配(正向?逆向?粒度?);“消除歧义的规则”是说当一句话可 以这样分,也可以那样分的时候,用什么规则来判定使用哪中分法,比如“设施和服务”这个短语,可以分成“设施_和服_务”,也可以分成“设施_和_服 务”,选择哪个分词结果,就是“消除歧义的规则”的功能。
MMSEG的“匹配方法”有两种:
1.Simple方法,即简单的正向匹配,根据开头的字,列出所有可能的结果。比如“一个劲儿的说话”,可以得到
一个
一个劲
一个劲儿
一个劲儿的
这四个匹配结果(假设这四个词都包含在词典里)。
2.Complex方法,匹配出所有的“三个词的词组”(原文中使用了chunk,这里感觉用“词组”比较合适),即从某一既定的字为起始位置,得到所有可能的“以三个词为一组”的所有组合。比如“研究生命起源”,可以得到
研_究_生
研_究_生命
研究生_命_起源
研究_生命_起源
这些“词组”(根据词典,可能远不止这些,仅此举例)
“消除歧义的规则”有四个,使用中依次用这四个规则进行过滤,直到只有一种结果或者第四个规则使用完毕。这个四个规则分别是:
1.Maximum matching (最大匹配),有两种情况,分别对应于使用“simple”和“complex”的匹配方法。对“simple”匹配方法,选择长度最大的词,用在上文的 例子中即选择“一个劲儿的”;对“complex”匹配方法,选择“词组长度最大的”那个词组,然后选择这个词组的第一个词,作为切分出的第一个词,上文 的例子中即“研究生_命_起源”中的“研究生”,或者“研究_生命_起源”中的“研究”。
2.Largest average word length(最大平均词语长度)。经过规则1过滤后,如果剩余的词组超过1个,那就选择平均词语长度最大的那个(平均词长=词组总字数/词语数量)。比如“生活水平”,可能得到如下词组:
生_活水_平 (4/3=1.33)
生活_水_平 (4/3=1.33)
生活_水平 (4/2=2)
根据此规则,就可以确定选择“生活_水平”这个词组
3.Smallest variance of word lengths(词语长度的最小变化率),由于词语长度的变化率可以由标准差(http://baike.baidu.com/view/78339.htm)反映,所以此处直接套用标准差公式即可。比如
研究_生命_起源 (标准差=sqrt(((2-2)^2+(2-2)^2+(2-2^2))/3)=0)
研究生_命_起源 (标准差=sqrt(((2-3)^2+(2-1)^2+(2-2)^2)/3)=0.8165)
于是选择“研究_生命_起源”这个词组。
4.Largest sum of degree of morphemic freedom of one-character words,其中degree of morphemic freedom可以用一个数学公式表达:log(frequency),即词频的自然对数(这里log表示数学中的ln)。这个规则的意思是“计算词组中的所有单字词词频的自然对数,然后将得到的值相加,取总和最大的词组”。比如:
设施_和服_务
设施_和_服务
这两个词组中分别有“务”和“和”这两个单字词,假设“务”作为单字词时候的频率是5,“和”作为单字词时候的频率是10,对5和10取自然对数,然后取最大值者,所以取“和”字所在的词组,即“设施_和_服务”。
也许会问为什么要对“词频”取自然对数呢?可以这样理解,词组中单字词词频总和可能一样,但是实际的效果并不同,比如
A_BBB_C (单字词词频,A:3, C:7)
DD_E_F (单字词词频,E:5,F:5)
表示两个词组,A、C、E、F表示不同的单字词,如果不取自然对数,单纯就词频来计算,那么这两个词组是一样的(3+7=5+5),但实际上不同的词频范围所表示的效果也不同,所以这里取自然对数,以表区分(ln(3)+ln(7) < ln(5)+ln(5), 3.0445<3.2189)。
这个四个过滤规则中,如果使用simple的匹配方法,只能使用第一个规则过滤,如果使用complex的匹配方法,则四个规则都可以使用。实际使用中,一般都是使用complex的匹配方法+四个规则过滤。(simple的匹配方法实质上就是正向最大匹配,实际中很少只用这一个方法)
看到这里也许对MMSEG的分词方法有了一个大致的了解,正如文章开头所述,它是一个“直观”的分词方法。它把一个句子“尽可能长(这里的长,是指所切分的词尽可能的长)”“尽可能均匀”的区切分,稍微想象一下,便感觉与中文的语法习惯比较相符。如果对分词精度要求不是特别高,MMSEG是一个简单、可行、快速的方法。
在具体实现一个分词程序的时候,大概有以下几点需要考虑:
1.“方法”决定“速度”。在基于词典的分词算法中,词典的结构对速度的影响是比较大的(词典的结构一般决定了匹配的方法和速度)。一般的构造词典的方法有很多,比如“首字索引+整词二分”,将所有词语的首字用某一Hash算法索引,然后将词体部分排序,使用二分查找。这样的方法可行,但不是最快的。对于这样的词典匹配,trie结构一般是首选。trie也有一些变种和实现方法,对于大量静态数据的匹配(比如词典,一旦创建,便很少去修改里面的内容,故称之为“静态”),一般采用“双数组trie树结构(Double array trie tree)”,其相关资料网上有很多,可以Google或者Baidu。这里提几个可供参考的类库:
Darts,   http://chasen.org/~taku/software/darts/ , C++
Darts-clone, http://code.google.com/p/darts-clone/ , C++, 某些方面比Darts好一些
2.MMSEG的分词效果与词典关系较大(这里是说词典里有哪些词语,以及词频的精确度),尤其是词典中单字词的频率。可以根据使用领域,专门定制词典(比如计算机类词库,生活信息类词库,旅游类词库等),尽可能的细分词典,这样得到的分词效果会好很多。同时也可以通过词典达到一些特殊目的(地址分词等)。关于词库,可以参考“搜狗”的细胞词库(http://pinyin.sogou.com/dict/)以及其提供的语料库(可以根据其划分好的语料库,统计某一方面的词频,http://www.sogou.com/labs/resources.html)。
3.中文分词的处理,与编码关系很大(GBK, GB2312, BIG5, UTF-8),一般是以UTF-8为主,减少编码的复杂性。
4.MMSEG算法中取得所有的“chunk”是比较复杂的部分,根据不同的词典结构会有不同的方法。如果使用“双数组trie树”结构,会简单一些,可以用“递归”实现,也可以用“三层for循环实现”。出于性能考虑,一般是使用for循环。
这里是一个基于MMSEG算法的PHP中文分词扩展 http://code.google.com/p/xsplit/ 并加入了一些常用函数

已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [mmseg 分词 算法] 推荐:

[转]关于MMSEG分词算法

- - 行业应用 - ITeye博客
转自:http://hi.baidu.com/catro/item/5c76247c0ff6a9376f29f6ed. MMSEG是中文分词中一个常见的、基于词典的分词算法(作者主页:http://chtsai.org/index_tw.html),简单、效果相对较好. 由于它的简易直观性,实现起来不是很复杂,运行速度也比较快.

漫话中文分词算法

- dumin - Matrix67: My Blog
    记得第一次了解中文分词算法是在 Google 黑板报 上看到的,当初看到那个算法时我彻底被震撼住了,想不到一个看似不可能完成的任务竟然有如此神奇巧妙的算法. 最近在詹卫东老师的《中文信息处理导论》课上再次学到中文分词算法,才知道这并不是中文分词算法研究的全部,前前后后还有很多故事可讲. 在没有建立统计语言模型时,人们还在语言学的角度对自动分词进行研究,期间诞生了很多有意思的理论.

中文分词算法代码大全

- - 鲁塔弗的博客
做中文搜索,关键词提取,文档分类都离不开中文分词,能用的代码包有如下. 单字切分 sphinx只要把min_word_len设置为1,并配置charset_table,默认就是单字切分,lucene用StandardAnalyzer. CJKAnalyzer lucene自带,两两分词,就是把 ABCD 分成 AB,BC,CD 3段.

英文分词的算法和原理

- - 鲁塔弗的博客
分词质量对于基于词频的相关性计算是无比重要的. 英文(西方语言)语言的基本单位就是单词,所以分词特别容易做,只需要3步:. 根据空格/符号/段落 分隔,得到单词组. 过滤,排除掉stop word. ''' re.findall(pattern,待分词文本). 第二步:排除stop word. stopword就是类似 a/an/and/are/then 的这类高频词,高频词会对基于词频的算分公式产生极大的干扰,所以需要过滤.

中文分词算法概述

- - zzm
所谓全文检索是指计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就 根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式. 在中文文档中根据是否采用分词技术,索引项可以是字、词或词组,由此可分为基于字的全 文索引和基于词的全文索引.

中文分词算法 之 基于词典的逆向最大匹配算法

- - ITeye博客
在之前的博文中介绍了 基于词典的正向最大匹配算法,用了不到50行代码就实现了,然后分析了词典查找算法的时空复杂性,最后使用前缀树来实现词典查找算法并做了3次优化. 下面我们看看基于词典的逆向最大匹配算法的实现,如下代码所示:. //取指定的最大长度的文本去词典里面匹配. //如果长度为一且在词典中未找到匹配,则按长度为一切分.

中文分词算法 之 基于词典的逆向最小匹配算法

- - 编程语言 - ITeye博客
在之前的博文中介绍了 基于词典的逆向最大匹配算法,比如我们切分句子: 中华人民共和国万岁万岁万万岁,使用逆向最大匹配算法的切分结果为:[中华人民共和国, 万岁, 万岁, 万万岁],可以看到,切分出来的词是很长的,粒度很粗,如果我们想要切分出很细粒度的词,该怎么办呢. 本文介绍 逆向最小匹配算法,该算法和 逆向最大匹配算法相得益彰,一个强调细粒度,一个强调粗粒度.

在Hadoop上运行基于RMM中文分词算法的MapReduce程序

- - Xiaoxia[PG]
我知道这个文章标题很“学术”化,很俗,让人看起来是一篇很牛B或者很装逼的论文. 其实不然,只是一份普通的实验报告,同时本文也不对RMM中文分词算法进行研究. 这个实验报告是我做高性能计算课程的实验里提交的. 所以,下面的内容是从我的实验报告里摘录出来的,当作是我学习hadoop分享出来的一些个人经验.

java中文分词组件-word分词

- - 研发管理 - ITeye博客
关键字:java中文分词组件-word分词. word分词器主页 :https://github.com/ysc/word. word分词是一个Java实现的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义. 能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名等未登录词.

缓存算法

- lostsnow - 小彰
没有人能说清哪种缓存算法由于其他的缓存算法. (以下的几种缓存算法,有的我也理解不好,如果感兴趣,你可以Google一下  ). 大家好,我是 LFU,我会计算为每个缓存对象计算他们被使用的频率. 我是LRU缓存算法,我把最近最少使用的缓存对象给踢走. 我总是需要去了解在什么时候,用了哪个缓存对象.