文本分类聚类-基于规则的分词

1.原理

基于规则或词典的分词方法是一种较为机械的分词方法,基本思想如下:

  • 1.将待分词语句中的字符串和词典逐个匹配。
  • 2.找到匹配的字符串则切分,不匹配则减去边缘的某些字符。
  • 3.从头再次匹配,直至匹配完毕或者没有找到词典的字符串而结束。

基于规则的最大匹配方法是一种基于词典和规则的一种分词方法,最大的缺点是严重依赖词典,未登录词和分词歧义无法很好的处理。优点是方法简单,容易实现,速度快,有一定规模的词典效果可以满足基本需求。最大匹配方法包含正向最大匹配(MM)、逆向最大匹配(RMM)和双向最大匹配(BIMM)三种匹配方法。

2.步骤

1 读取词典信息

  • 1.通过open函数打开词典文件
  • 2.通过for循环访问读取到的文件
  • 3.通过set()函数将dictionary转换为元组去重,将去重后的元组转换为列表
dictionary = [] 
dic_path = 'dic.utf8'

data = open(dic_path,encoding= 'utf-8-sig')
for i in data:
    print(i)
    i = i.replace('\n','')#replace取代,替换函数
    dictionary.append(i)
    
dictionary = list(set(dictionary))#自 动去重并且升序排序
print('词典信息为:\n',dictionary)

在这里插入图片描述

2 计算词典中的最大字符长度

  • 1、通过for循环遍历整个dictionary列表
  • 2、使用max函数求出所有词语的最大长度
word_length = []
for i in dictionary:
    word_length.append(len(i))
max_length = max(word_length)

print('词典中最大的字符长度为:',max_length)

在这里插入图片描述

3 基于规则的分词法

1、正向最大匹配法

  • (1)假设有一个待分词中文文本和一个分词词典,词典中最长的字符串长度为m。
  • (2)从左至右切分待分词文本的前m个字符,然后查找是否有和词典一致的字符串。
  • (3)若匹配失败,则删去该字符串的最后一个字符,仅留下前m-1个字符,继续匹配这个字符串,以此类推。
  • (4)如果匹配成功,那么被切分下来的第二个文本成为新的待分词文本,重复以上操作直至匹配完毕。如果一个字符串全部匹配失败,那么逐次删去第一个字符,重复上述操作。

2、逆向最大匹配法

  • (1)RMM与MM法原理相反,从右至左匹配待分词文本的后m个字符串,查找是否有和词典一致的字符串。
  • (2)若匹配失败,仅留下待分词文本的后m-1个词,继续匹配这个字符串,以此类推。
  • (3)如果匹配成功,则被切分下来的第一个文本序列成为新的待分词文本,重复以上操作直至匹配完毕。
  • (4)如果一个词序列全部匹配失败,则逐次删去最后一个字符,重复上述操作。

3、双向最大匹配法

  • (1)双向最大匹配法基本思想是将MM法和RMM法的结果进行对比,选取两种方法中切分次数较少的作为切分结果。
  • (2)用正向最大匹配法和逆向最大匹配法对“北京市民办高中”进行分词,结果分别为“北京市民”、“办”、“高中”和“北京市”、“民办”和“高中”。
  • (3)选取切分次数最少的结果为“北京市”和“民办高中”。
    研究表明,利用正向最大匹配法和逆向最大匹配法匹配,中文分词大约90%的词句完全重合且正确,有9%左右的句子得到的结果不一样,但其中有一个是正确的。剩下不到1%的句子使用两种方法进行切分都是错误的。因而,双向最大匹配法在中文分词领域中得以广泛运用。

4、逆向最大匹配的算法实现步骤

  • 1、输入待分词的文本“北京市民办高中”。
  • 2、定义一个空列表cut_list保存分词结果。
  • 3、读取文本的字符长度。
  • 4、以文本的长度text_length构建while循环,每一次从文本末尾开始切分词语,遍历匹配一次词典中的信息。若有相同的情况,则添加到空列表中。

这里只进行最大逆向匹配算法:

text = '北京市民办高中'
cut_list  = []
text_length = len(text)
while text_length > 0:
    for i in range(text_length,0,-1):#以文本的长度text_length为循环
        #print(i)
        #print(text_length)
        piece = text[(text_length - i):text_length]
        #print(piece)#遍历从右到左所有可能
        if piece in dictionary:#判断是否在词典中
            word = piece
            cut_list.append(word)
            text_length -= i#分词
            
    text_length-=1
print('分词结果为:',cut_list)

在这里插入图片描述

4 函数封装与调用

将上述函数封装起来直接调用:

def RMM(text):
    dictionary = [] 
    dic_path = 'dic.utf8'
    data = open(dic_path,encoding= 'utf-8-sig')
    for i in data:
        #print(i)
        i = i.replace('\n','')#replace取代,替换函数
        dictionary.append(i)
    dictionary = list(set(dictionary))#自动去重并且升序排序
    #print('词典信息为:\n',dictionary)
    
    word_length = []
    for i in dictionary:
        word_length.append(len(i))
    max_length = max(word_length)
    #print('词典中最大的字符长度为:',max_length)
    
    text = input("请输入:")
    cut_list  = []
    text_length = len(text)
    while text_length > 0:
        for i in range(text_length,0,-1):#以文本的长度text_length为循环
            #print(i)
            #print(text_length)
            piece = text[(text_length - i):text_length]
            #print(piece)#遍历从右到左所有可能
            if piece in dictionary:#判断是否在词典中
                word = piece
                cut_list.append(word)
                text_length -= i#分词
            
        text_length-=1
    print('分词结果为:',cut_list)
RMM(text)

在这里插入图片描述
————————————————————————————————————

有想要自己去试一下最大正向匹配的或者双向匹配的也可以自己去试试,后面我会继续分享给大家。

猜你喜欢

转载自blog.csdn.net/YYANyk/article/details/129938434