中文分词-机械分词法

来源:互联网 发布:tomcat debug 端口 编辑:程序博客网 时间:2024/05/01 21:15

      中文分词是中文自然语言处理的基础,中文分词的正确率如何直接影响后续的词性标注(也有些词性标注算法不需要事先分词,但标注效果往往比先分词后标注差),实体识别、句法分析、语义分析。常用的分词方法主要有依赖词典的机械分词和序列标注方法。

      1.常用的机械分词方法

       在自然语言处理相关的书籍资料中常提到的机械分词方法主要有正向最大匹配、正向最小匹配、逆向最大匹配、逆向最小匹配四种,但是实际工程中用的比较多的还是正向最大匹配和逆向最大匹配,因此这里简要介绍下这两种最大匹配算法,最小匹配算法原理类似。

       假设我们已经有切词词典dict,要切词的句子为sentence; 为便于理解,后面介绍两种算法均以“南京市长江大桥”为例说明算法

      1)正向最大匹配算法

       正向最大匹配算法根据经验设定切词最大长度max_len(中文词语多为二字、三字、四字词,少数五字短语,比如“坐山观虎斗”,因此max_len设为4或5较合适),每次扫描的时候寻找当前开始的这个长度的词来和字典中的词匹配,如果没有找到,就缩短长度继续寻找,直到找到或者成为单字      具体分词算法如下:

a、 设置start = 0, total_len = 要切词的句子长度(字符串索引从0开始)

b、依次截取长度为max_len的字符串,

words = dict{}

while start  < total_len:

           tmp_len = start + max_len <= total_len ? max_len : total_len - start

           while tmp_len > 0:

                   sub_str = setence[start : start  + tmp_len]

                   if sub_str in dict:

                        words.append(setence[start : start  + tmp_len])

                        start = start + tmp_len

                        break

                   else:

                       tmp_len = tmp_len -1

              end

              // 所有长度大于1的子串都没有命中词典,则该字符单独成词

              if tmp_len = 0

                    words.append(setence[start : start  +1])

                    start = start + 1

     end

以“”南京市长江大桥“为例,设max_len = 4,dict = {南京、市长、长江、大桥}

 第一个长度为4的子串为“南京市长“,该词没有命中词典,子串长度减1得到新的子串“南京市”,该词仍然没有命中词典,子串长度再减1得到新的子串“南京”,该词命中词典;

则更新start,start = start + tmp_len = 0 + 2 = 2,下一个子串为“市长江大”,处理方法跟第一个词相同,可以切分出“市长”;依次类推,最后使用整箱最大匹配算法分词结果为“南京 市长  江  大桥”

    2)逆向最大匹配算法

    逆向最大匹配算法和正向最大匹配算法不同的是,切分汉字时,逆向最大匹配算法不是按照汉字顺序从左到右依次抽取子串,而是从汉字尾端开始抽取,算法伪码如下:

    

a、 设置 total_len = 要切词的句子长度,end = total_len(字符串索引从0开始)

b、依次截取长度为max_len的字符串

words = dict{}

while end  >= 0:

           tmp_len = end - max_len >= 0 ? max_len : end - 0

           while tmp_len > 0:

                   sub_str = setence[end - tmp_len : end](区间前闭后开)

                   if sub_str in dict:

                       words.append(setence[end - tmp_len : end])

                       end = end - tmp_len 

                        break

                   else:

                       tmp_len = tmp_len -1

              end

              // 没有子串匹配,则单独成词

             if tmp_len == 0:

                    words.append(setence[end - 1 : end])

                    end = end - 1

     end

 仍以“”南京市长江大桥“为例,设max_len = 4,dict = {南京、市长、长江、大桥}

 第一个长度为4的子串为“长江大桥“,该词没有命中词典,子串长度减1,得到新的子串“江大桥”;该词还是没有命中词典,子串长度再减1,得到新的子串“大桥”,“——大桥”命中词典,更新end的值end = end - tmp_len = 7 - 2 = 5;下一轮循环,取长度为4的最大子串“京市长江”,按照上面的算法可以切分出“长江”;进入下一轮循环,切分出“南京市”


     上面的例子正向最大切分结果为“南京 市长 江 大桥”,逆向最大切分结果为“南京 市 长江 大桥”;一般来说,逆向最大匹配切分准确率略高于正向最大匹配。

            

2、机械切分算法的局限性

        机械切词算法的局限性有两个:

1)歧义词切分问题

     歧义词切分问题是指同一个字符串,按照不同的切分算法,可以切分出不同的结果,我们上面介绍正向最大匹配算法和逆向最大匹配算法时给出的例句按照两种算法切分结果就不相同。歧义词切分又可以进一步分为“交集歧义字段”和“多义组合歧义字段”。

     交集歧义字段,是指字段AJB,可以切分为AJ B, 也可以切分为A JB,上面的例子中“市长江”就是属于交集歧义字段。研究表明汉语文本中,歧义现象出现的概率是1/110,其中90%以上属于交集歧义字段。

     多义组合歧义字段, 是指字段AB,不仅AB可以成词,而且A、B可以单独成词,例如“他将来做报告”中的“将来”。

歧义字段处理

     歧义字段处理可以考虑词语出现的频率等统计信息,开源软件结巴分词的机械分词实现算法就考虑了各个词语的概率,使用有向无环图和动态规划算法,找出各种切分结果中,概率最大的作为切分结果。具体实现可以参考结巴分词源码:https://github.com/fxsjy/jieba


2)未登陆词识别问题

     未登陆词是指没有在切词词典中出现的词,很显然,机械分词算法,对于未在词典中出现的词会切分成单字。

     未登录词处理方法:

     1)使用特定领域的此表,比如使用 中文姓氏频率表和人名常用字 频率表来切分人名(开源软件盘古分词使用姓氏和人名常用字表来切分人名http://pangusegment.codeplex.com/)

     2)具有指示意义的上线问信息

      中文中有些字或词语有特殊的意义,可以在切词时利用这些信息,比如统计常用语词首和词尾的字

    3)互信息

      

如果A、B相互独立,则P(AB)= P(A)P(B), I(A,B) = 0, 反之,如果I(A,B)的值很大,则说明A、B之间存在联系,可以通过设定阈值,当I(A,B)超过该阈值,就设为AB组成一个词语,同理,可以计算三字、四字词语。


通过上述方法识别出为登陆词之后,用识别出的未登录词更新切分词典


3. 复旦大学切词系统简介


该分词系统主要由4个模块组成,输入的汉语文本,经过预处理(根据标点符号分隔、全角字符转半角字符等),将首先利用分隔字符标记分隔成较短的汉字串,同时根据预处理规则预先切分出数词、英文、时间词等,然后通过正向最大匹配和逆向最大匹配算法识别出汉语字符串中的歧义字段,再利用歧义处理规则和词典中的统计信息处理歧义字段。

该系统的具体实现细节可以参考吴立德《大规模中文文本处理》一书。


        

      

              

0 0
原创粉丝点击