中文分词—规则分词

Posted 合成尸的进击路

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了中文分词—规则分词相关的知识,希望对你有一定的参考价值。

本文主要介绍中文分词基于规则分词的个人学习笔记。

下期预告:文分词—统计分词笔记


自中文自动分词被提出以来,30年的探索,提出了很多方法,可主要归纳为“规则分词”“统计分词”和“混合分词(规 +统计)”这三个主要流派。规则分词是最早兴起的方法,主要是通过人工设立词库,按照一定方式进行匹配切分,其实现简单高效,但是对新词很难进行处理。随后统计机器学习技术的兴起,应用于分词任务上后,就有了统计分词,能够较好地应对新词发现等特殊场景。


规则分词

  • 正向最大匹配法(Maximum Match Method)

  • 逆向最大匹配法(Reversw Maximum Match)

  • 双向最大匹配法

基于规则的分词是一种机械分词方法,主要是通过维护词典,在切分语句时,将语句的每个字符串与词表中的词进行逐一匹配,找到则切分,否则不予切分。

按照匹配切分的方式,主要有正向最大匹配法、逆向最大匹配法以及双向最大匹配法。


正向最大匹配法

正向最大匹配(Maximum Match Method)的基本思想为:假定分词中的最长词有i个汉字字符,则用被处理文档的当前字符串的前i个字符作为匹配字段,查找字典。若字典中存在这样的一个i字词,则匹配成功,匹配字段被作为一个词切分出来。

如果词典中找不到这样的一个i字词,则匹配失败,将匹配字段中的最后一个字去掉,对剩下的字符串进行匹配处理。如此进行下去,直到匹配成功,即切分出一个词或剩余字符串的长度为零为止。


word_dic = []  
def init(): with open('dic.txt', 'r', encoding='utf-8') as dic_input: for word in dic_input:            word_dic.append(word.strip())            def cut_words(raw_sentence, words_dic):    max_length = max(len(word) for word in word_dic)    sentence = raw_sentence.strip()    words_length = len(sentence) cut_word_list = []    while words_length > 0:          max_cut_length = min(max_length, words_length)        subSentence = sentence[0: max_cut_length] while max_cut_length > 0: if subSentence in word_dic: cut_word_list.append(subSentence) break elif max_cut_length == 1: cut_word_list.append(subSentence) break else: max_cut_length = max_cut_length - 1                subSentence = subSentence[0: max_cut_length]        sentence = sentence[max_cut_length:]          words_length = words_length - max_cut_length  
    return cut_word_list    def main(): init() while True: print("请输入您要分词的序列") input_str = input() if not input_str: break result = cut_words(input_str, word_dic) print("分词的结果") print(result)
main()


逆向最大匹配法

逆向最大匹配(Reversw Maximum Match)的基本思想是:假定分词中的最长词有i个汉字字符,则从被处理的文档末端开始匹配,每次取末端的i个字符(i为词典中最长词数)作为匹配字段。若匹配失败,则去掉匹配字段的最前面一个字,继续匹配。相应地,它使用的分词词典是逆序词典,其中的每个词条都将按逆序方式存放。

由于汉语中偏正结构较多,若从后向前匹配,可以适当提高精确度。所以逆向最大匹配算法比正向最大匹配算法的误差要小。统计结果表明,单纯使用正向最大匹配算法的错误率1/169,单纯的逆向最大匹配的错误率为1/254,比如之前的“南京市长江大桥”,按照逆向最大匹配,最终得到“南京市”“长江大桥”。当然,如此切分并不代表完全正确,可能有个“江大桥”的“南京市长”也说不定。

words_dic = []def init():
with open('dic.txt', 'r',encoding='utf-8') as dic_input: for word in dic_input: words_dic.append(word.strip())
def cut_words(raw_sentence, words_dic): max_length = max(len(word) for word in words_dic) sentence = raw_sentence.strip() words_length = len(sentence) cut_words_list = []
while words_length >0: max_cut_length = min(max_length, words_length) subSentence = sentence[-max_cut_length:] while max_cut_length >0: if subSentence in words_dic: cut_words_list.append(subSentence) break elif max_cut_length == 1: cut_words_list.append(subSentence) break            else:                  max_cut_length = max_cut_length - 1  subSentence = subSentence[-max_cut_length:] sentence = sentence[0:-max_cut_length]        words_length = words_length - max_cut_length      cut_words_list.reverse() return cut_words_list
def main(): init() while True: print("请输入你要分词的序列:") input_str = input() if not input_str: break result = cut_words(input_str, words_dic) print("分词结果") print(result)main()


双向最大匹配法

双向最大匹配法是将正向最大匹配法得到的分词结果和逆向最大匹 配法的到的结果进行比较,从而决定正确的分词方法。据SunM.S. 和 Benjamin K.T.(1995)的研究表明,中文中90.0%左右的句子, 正向最大匹配法和逆向最大匹配法完全重合且正确,只有大概9.0% 的句子两种切分方法得到的结果不一样,但其中必有一个是正确的 (歧义检测成功),只有不到1.0%的句子,或者正向最大匹配法和 逆向最大匹配法的切分虽重合却是错的,或者正向最大匹配法和逆 向最大匹配法切分不同但两个都不对(歧义检测失败)。这正是双 向最大匹配法在实用中文信息处理系统中得以广泛使用的原因所在。

启发式算法

  • 如果正反向分词结果词数不同,则取分词数量较少的那个

  • 如果分词结果词数相同

    • 分词结果相同,就说明没有歧义,可返回任意一个。

import BMMimport RMM
word_dic = [] # 申请一个词典def init(): with open('dic.txt', 'r', encoding='utf-8') as dic_input: for word in dic_input: word_dic.append(word.strip())
def cut_words(raw_sentence, words_dic): bmm_words_list = BMM.cut_words(raw_sentence, words_dic) fmm_words_list = RMM.cut_words(raw_sentence, words_dic) bmm_words_list_size = len(bmm_words_list) fmm_words_list_size = len(fmm_words_list) if bmm_words_list_size != fmm_words_list_size: if bmm_words_list_size < fmm_words_list_size: return bmm_words_list_size else:            return fmm_words_list_size else: FSingle = 0 RSingle = 0 isSame = True        for i in range(len(fmm_words_list)):    if fmm_words_list[i] not in bmm_words_list: isSame = False if len(fmm_words_list[i]) == 1: FSingle = FSingle +1 if len(bmm_words_list[i]) == 1: RSingle = RSingle + 1 if isSame: return fmm_words_list elif RSingle > FSingle: return fmm_words_list else: return bmm_words_list
def main(): init() while True: print("请输入您要分词的序列") input_str = input() if not input_str: break result = cut_words(input_str, word_dic) print("分词的结果") print(result)main()


下期预告笔记:中文分词—统计分词笔记

以上是关于中文分词—规则分词的主要内容,如果未能解决你的问题,请参考以下文章

基于词典规则的中文分词

java如何分词??

规则分词法|自然语言

中文分词:正向最大匹配与逆向最大匹配

自然语言处理之HMM模型分词

中文分词