码迷,mamicode.com
首页 > 编程语言 > 详细

关于mmseg分词算法的资料总结

时间:2015-01-13 17:46:34      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:mmseg   python   

http://www.byywee.com/page/M0/S602/602088.html 或者是http://hi.baidu.com/catro/item/5c76247c0ff6a9376f29f6ed   关于mmseg的简介

http://blog.csdn.net/yangyan19870319/article/details/6399871  最大正向匹配算法的讲解

https://pypi.python.org/pypi/mmseg/1.3.0 关于mmseg python源码下载


https://pypi.python.org/pypi/mmseg/1.3.0   关于mmseg python的简单实现

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/ 并加入了一些常用函数


关于mmseg分词算法的资料总结

标签:mmseg   python   

原文地址:http://blog.csdn.net/huntinggo/article/details/42678527

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!