当前位置:   article > 正文

正向/逆向最大匹配法分词实现_正向最大匹配法

正向最大匹配法

最大匹配法:最大匹配是指以词典为依据,取词典中最长单词为第一个次取字数量的扫描串,在词典中进行扫描(为提升扫描效率,还可以跟据字数多少设计多个字典,然后根据字数分别从不同字典中进行扫描)。例如:词典中最长词为“中华人民共和国”共7个汉字,则最大匹配起始字数为7个汉字。然后逐字递减,在对应的词典中进行查找。

下面以“我们在野生动物园玩”为例详细说明一下正向与逆向最大匹配方法:

  • 1、正向最大匹配法:

正向即从前往后取词,从7->1,每次减一个字,直到词典命中或剩下1个单字。

第1次:“我们在野生动物”,扫描7字词典,无

第2次:“我们在野生动”,扫描6字词典,无

。。。。

第6次:“我们”,扫描2字词典,有

扫描中止,输出第1个词为“我们”,去除第1个词后开始第2轮扫描,即:

第2轮扫描:

第1次:“在野生动物园玩”,扫描7字词典,无

第2次:“在野生动物园”,扫描6字词典,无

。。。。

第6次:“在野”,扫描2字词典,有

扫描中止,输出第2个词为“在野”,去除第2个词后开始第3轮扫描,即:

第3轮扫描:

第1次:“生动物园玩”,扫描5字词典,无

第2次:“生动物园”,扫描4字词典,无

第3次:“生动物”,扫描3字词典,无

第4次:“生动”,扫描2字词典,有

扫描中止,输出第3个词为“生动”,第4轮扫描,即:

第4轮扫描:

第1次:“物园玩”,扫描3字词典,无

第2次:“物园”,扫描2字词典,无

第3次:“物”,扫描1字词典,无

扫描中止,输出第4个词为“物”,非字典词数加1,开始第5轮扫描,即:

第5轮扫描:

第1次:“园玩”,扫描2字词典,无

第2次:“园”,扫描1字词典,有

扫描中止,输出第5个词为“园”,单字字典词数加1,开始第6轮扫描,即:

第6轮扫描:

第1次:“玩”,扫描1字字典词,有

扫描中止,输出第6个词为“玩”,单字字典词数加1,整体扫描结束。

正向最大匹配法,最终切分结果为:“我们/在野/生动/物/园/玩”

2、正向最大匹配python代码实现

  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Thu Jul 19 08:57:56 2018
  4. @author: Lenovo
  5. """
  6. test_file = 'train/train.txt'#训练语料
  7. test_file2 = 'test/test.txt'#测试语料
  8. test_file3 = 'test_sc/test_sc_zhengxiang.txt'#生成结果
  9. def get_dic(test_file): #读取文本返回列表
  10. with open(test_file,'r',encoding='utf-8',) as f:
  11. try:
  12. file_content = f.read().split()
  13. finally:
  14. f.close()
  15. chars = list(set(file_content))
  16. return chars
  17. dic = get_dic(test_file)
  18. def readfile(test_file2):
  19. max_length = 5
  20. h = open(test_file3,'w',encoding='utf-8',)
  21. with open(test_file2,'r',encoding='utf-8',) as f:
  22. lines = f.readlines()
  23. for line in lines:#分别对每行进行正向最大匹配处理
  24. max_length = 5
  25. my_list = []
  26. len_hang = len(line)
  27. while len_hang>0 :
  28. tryWord = line[0:max_length]
  29. while tryWord not in dic:
  30. if len(tryWord)==1:
  31. break
  32. tryWord=tryWord[0:len(tryWord)-1]
  33. my_list.append(tryWord)
  34. line = line[len(tryWord):]
  35. len_hang = len(line)
  36. for t in my_list:#将分词结果写入生成文件
  37. if t == '\n' :
  38. h.write('\n')
  39. else:
  40. h.write(t + " ")
  41. h.close()
  42. readfile(test_file2)
  • 3、逆向最大匹配算法

逆向即从后往前取词,其他逻辑和正向相同。即:

第1轮扫描:“在野生动物园玩”

第1次:“在野生动物园玩”,扫描7字词典,无

第2次:“野生动物园玩”,扫描6字词典,无

。。。。

第7次:“玩”,扫描1字词典,有

扫描中止,输出“玩”,单字字典词加1,开始第2轮扫描

第2轮扫描:“们在野生动物园”

第1次:“们在野生动物园”,扫描7字词典,无

第2次:“在野生动物园”,扫描6字词典,无

第3次:“野生动物园”,扫描5字词典,有

扫描中止,输出“野生动物园”,开始第3轮扫描

第3轮扫描:“我们在”

第1次:“我们在”,扫描3字词典,无

第2次:“们在”,扫描2字词典,无

第3次:“在”,扫描1字词典,有

扫描中止,输出“在”,单字字典词加1,开始第4轮扫描

第4轮扫描:“我们”

第1次:“我们”,扫描2字词典,有

扫描中止,输出“我们”,整体扫描结束。

逆向最大匹配法,最终切分结果为:“我们/在/野生动物园/玩

4、逆向python代码实现

  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Thu Jul 19 08:57:56 2018
  4. @author: Lenovo
  5. """
  6. test_file = 'train/train.txt'
  7. test_file2 = 'test/test.txt'
  8. test_file3 = 'test_sc/test_sc.txt'
  9. def get_dic(test_file):
  10. with open(test_file,'r',encoding='utf-8',) as f:
  11. try:
  12. file_content = f.read().split()
  13. finally:
  14. f.close()
  15. chars = list(set(file_content))
  16. return chars
  17. dic = get_dic(test_file)
  18. def readfile(test_file2):
  19. max_length = 5
  20. h = open(test_file3,'w',encoding='utf-8',)
  21. with open(test_file2,'r',encoding='utf-8',) as f:
  22. lines = f.readlines()
  23. for line in lines:
  24. my_stack = []
  25. len_hang = len(line)
  26. while len_hang>0 :
  27. tryWord = line[-max_length:]
  28. while tryWord not in dic:
  29. if len(tryWord)==1:
  30. break
  31. tryWord=tryWord[1:]
  32. my_stack.append(tryWord)
  33. line = line[0:len(line)-len(tryWord)]
  34. len_hang = len(line)
  35. while len(my_stack):
  36. t = my_stack.pop()
  37. if t == '\n' :
  38. h.write('\n')
  39. else:
  40. h.write(t + " ")
  41. h.close()
  42. readfile(test_file2)
  • 5、正确率,召回率和F值

    正确率、召回率和F值是目标的重要评价指标。 

    正确率 = 正确识别的个体总数 / 识别出的个体总数 
    召回率 = 正确识别的个体总数 / 测试集中存在的个体总数 
    F值 = 正确率 * 召回率 * 2 / (正确率 + 召回率)

编写评价程序:首先对生成的文本和gold文本每行通过切分形成词汇表,然后对两个词汇表从第一个词开始比较:
         如果当前词汇相同,表明结果正确,且之前的词汇拼成的字符串长度相等;
         如果当前词汇不同,结果错误,不断取词汇拼字符串直到两个字符串长度相同;
    依次对每行进行处理,计算出f值。

  评价程序实现如下:

  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Fri Jul 27 15:32:46 2018
  4. @author: Lenovo
  5. """
  6. test_file = 'test_sc/test_sc_zhengxiang.txt'
  7. test_file2 = 'gold/test_gold.txt'
  8. def get_word(fname):
  9. f = open(fname,'r',encoding='utf-8',)
  10. lines = f.readlines()
  11. return lines
  12. def calc():
  13. lines_list_sc = get_word(test_file)
  14. lines_list_gold = get_word(test_file2)
  15. lines_list_num = len(lines_list_gold)
  16. right_num = 0
  17. m = 0#m存逆向结果文本词的总数
  18. n = 0#n存gold文本词的总数
  19. for i in range(lines_list_num):
  20. line_list_sc = list(lines_list_sc[i].split())#line_list_sc为生成结果每行通过空格切分后的词汇表
  21. line_list_gold = list(lines_list_gold[i].split())#line_list_gold为正确结果每行通过空格切分后的词汇表
  22. m += len(line_list_sc)
  23. n += len(line_list_gold)
  24. str_sc = ''#存结果文本每行无空格连接起来的字符串
  25. str_gold = ''#存gold文本每行无空格连接起来的字符串
  26. s = 0#表示结果文本每行列表的下标
  27. g = 0#表示gold文本每行列表的下标
  28. while s < len(line_list_sc) and g < len(line_list_gold):
  29. str_word_sc = line_list_sc[s]
  30. str_word_gold = line_list_gold[g]
  31. str_sc += str_word_sc
  32. str_gold += str_word_gold
  33. if str_word_sc == str_word_gold:#如果当前词汇相同,表明结果正确,且之前的词汇拼成的字符串长度相等
  34. s += 1
  35. g += 1
  36. right_num += 1
  37. else:#如果当前词汇不同,结果错误,不断取词汇拼字符串直到两个字符串长度相同
  38. while len(str_sc) > len(str_gold):
  39. g += 1
  40. str_gold += line_list_gold[g]
  41. while len(str_sc) < len(str_gold):
  42. s += 1
  43. str_sc += line_list_sc[s]
  44. g += 1
  45. s += 1
  46. print("生成结果词的个数:", m)
  47. print("gold文本词的个数:", n)
  48. print("正确词的个数:", right_num)
  49. p = right_num/m
  50. r = right_num/n
  51. f = 2*p*r/(p+r)
  52. print("正确率:", p)
  53. print("召回率:", r)
  54. print("正向f值:", f)
  55. calc()

运行结果如下:

  • 6、训练语料和测试语料见下百度云盘链接

链接: https://pan.baidu.com/s/1X0coEznut6_s0jsDG9_9Dg 密码: b393

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号