中文分词—规则分词
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 BMM
import 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()
下期预告笔记:中文分词—统计分词笔记
以上是关于中文分词—规则分词的主要内容,如果未能解决你的问题,请参考以下文章