• 关于MMSEG分词算法


    http://hi.baidu.com/catro/blog/item/e9b8ceea24754ec0d539c9b8.html

    关于MMSEG分词算法
    2011-02-02 13:54

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

  • 相关阅读:
    实战演示 H5 性能分析
    测试开发工资为什么这么高?
    战胜测试内卷转型测试开发,拿名企offer最多的班型是如何设计的
    接口协议之抓包分析 TCP 协议
    面试 | 如果测试时间不够,你会怎么办?
    史上最全 Appium 自动化测试从入门到框架实战精华学习笔记(三)
    容器技术 Docker & K8S 在测试场景中的经典应用实战
    实战演练基于加密接口测试测试用例设计
    技术风向标 | 云原生技术架构成熟度模型解读
    期待已久的 RocketMQ Summit 等待你的参与!
  • 原文地址:https://www.cnblogs.com/lexus/p/2195845.html
Copyright © 2020-2023  润新知