当前位置:   article > 正文

NLP中文信息处理---正向最大匹配法分词_正向最大匹配算法分词顺序

正向最大匹配算法分词顺序

弄了好几天正向最大匹配法分词,终于弄完了吧。Python写的。Python确实是一门好语言,写起来很简单、顺手。


一、关于正向最大匹配法分词

中文分词(Chinese Word Segmentation)指的是将一个汉字序列切分成一个一个单独的词。中文分词是文本挖掘的基础,对于输入的一段中文,成功的进行中文分词,可以达到电脑自动识别语句含义的效果。


正向最大匹配法

例子: 将句子 ’ 今天来了许多新同事 分词。  最大词长为5

今天来了许
今天来了
今天来
今天  ====》 得到一个词 – 今天
来了许多新
来了许多
来了许
来了
来   ====》 得到一个词 –
了许多新同
了许多新
了许多
了许
了   ====》 得到一个词 –
许多新同事
许多新同
许多新
许多 ====》得到一个词 – 许多
新同事
新同
新   ====》得到一个词 –
同事 ====》得到一个词 – 同事


最后正向最大匹配的结果是:/今天/来/了/许多/新/同事/


二、正向最大匹配分词算法



三、语料库的处理算法的输入


语料库的处理流程


输入:人民日报语料库199801.txt

输出:dict.txt词表文件


分词算法

输入:将dict.txt处理后得到的list集,以及最大词长;待分词的句子

输出:分词后的句子


四、Python实现

1. 语料库的初步处理 ( MaxBuildDict.py )

  1. # -*- coding: cp936 -*-
  2. #最大匹配法进行分词----创建词表文件.
  3. #author 徐能
  4. #date 2013/3/23
  5. import string
  6. import re
  7. #输入:语料库199801.txt文件; 输出:换行分割后的词表文件dict.txt(已经去重复, 去日期)
  8. def create_dict(filename):
  9. print("读取文件......")
  10. src_data = open(filename,'r').read()
  11. sp_data = src_data.split()#分割
  12. print("原始词数为:",len(sp_data))
  13. set_data = set(sp_data) #去重复
  14. data = list(set_data) #set转换成list, 否则不能索引
  15. print("去除重复后总词数为:",len(data))
  16. print("正在建立词表文件......")
  17. tmp = []
  18. for i in range(0,len(data)):
  19. if re.compile(r'\d+\-\S+').match(data[i]): #去除类似这样的词'19980101-01-001-002/m'
  20. continue
  21. else:
  22. p_ok_data = re.compile(r'\/\w+').sub('\n',data[i]) #将类似的词'埃特纳/ns'替换为'埃特纳'
  23. if re.compile(r'(\[\S+)|(\]\S+)').match(p_ok_data): #找到以'['或']'开头的词
  24. ok_data = re.compile(r'(\]\w+\[)|(\])|(\[)').sub('',p_ok_data) #去除']nt[澳门',']澳门','[澳门'三类词的头部无用部分(先匹配长的部分)
  25. tmp.append(ok_data)
  26. continue
  27. tmp.append(p_ok_data)
  28. print("最终得到的词表文件中总词数为:",len(tmp))
  29. open('dict_tmp.txt','w').writelines(tmp)
  30. print("初步词表文件建立完成! (dict_tmp.txt)")
  31. #运行
  32. if __name__ == '__main__':
  33. create_dict('199801.txt')


2. 进一步对词表的优化 ( MaxBuildDictModify.py )

  1. # -*- coding: cp936 -*-
  2. #修正词表文件.
  3. #author 徐能
  4. #date 2013/3/24
  5. import string
  6. import re
  7. #输入:dict_tmp.txt文件; 输出:dict.txt(已经去重复, 去特殊符号)
  8. def create_dict(filename):
  9. print("读取文件......")
  10. src_data = open(filename,'r').read()
  11. data = src_data.split()#分割
  12. print("正在建立词表文件......")
  13. tmp = []
  14. for i in range(0,len(data)):
  15. ok_data = re.compile(r'\]..').sub('',data[i]) #将类似的词']..埃特纳'前面的东西去掉
  16. tmp.append(ok_data+'\n')
  17. print("去重复前的词数为:",len(tmp))
  18. set_data = set(tmp) #去重复
  19. lalst_data = list(set_data) #set转换成list, 否则不能索引
  20. print("去除重复后总词数为:",len(lalst_data))
  21. open('dict.txt','w').writelines(lalst_data)
  22. print("最终词表文件建立完成! (dict.txt)")
  23. #运行
  24. if __name__ == '__main__':
  25. create_dict('dict_tmp.txt')
  26. ## create_dict('testdict1.txt')
  27. ## create_dict('testdict2.txt')


3. 分词算法实现 ( MaxWordSegmentation.py )

  1. # -*- coding: cp936 -*-
  2. #最大匹配法进行分词, 测试文件为MaxWordSegmentationTest.py
  3. #author 徐能
  4. #date 2013/3/25
  5. import string
  6. import re
  7. #读入词表文件到内存list
  8. #输入:词典文件名, 输出:词典中所有词的list表,其中最大词长
  9. def load_dict(filename):
  10. f = open(filename,'r').read()
  11. maxLen = 1
  12. strList=f.split("\n")
  13. #寻找最大词长
  14. for i in strList:
  15. if len(i)>maxLen:
  16. maxLen=len(i)
  17. return strList,maxLen;
  18. #分词方法.
  19. #输入:词表中所有词的列表与其中的最大词长, 输出:分词后的列表
  20. def segmentation(strList,maxLen,sentence):
  21. wordList=[] #用于输出的词列表
  22. while(len(sentence)>0):
  23. word=sentence[0:maxLen] #每次取最大词长的词
  24. meet=False; #标记位, 判断是否找到该词
  25. while((not meet) and (len(word)>0)):
  26. #如果词在词表中
  27. if(word in strList):
  28. wordList.append(word) #添加到输出列表
  29. sentence=sentence[len(word):len(sentence)]#后移
  30. meet=True;
  31. #词不在词表中时
  32. else:
  33. #当词长为1时, 添加到输出表, 并后移总词位
  34. if(len(word)==1):
  35. wordList.append(word)
  36. sentence=sentence[len(word):len(sentence)]
  37. meet=True;
  38. else:
  39. #当词长不为1时, 词长减1(最后一位)
  40. word=word[0:len(word)-1]
  41. return wordList
  42. #主函数
  43. def main():
  44. strList,maxLen=load_dict('dict.txt')
  45. print("词表中最大词长度为:",maxLen)
  46. #输入句子
  47. sentence = input('请输入中文句子:')
  48. print('输入的句子为:',sentence)
  49. # sentence='迈向充满希望的新世纪'
  50. print('输入的句子为:',sentence)
  51. length=len(sentence)
  52. print('输入的句子长度:',length)
  53. print("****************开始解析**********************")
  54. wordl=segmentation(strList,maxLen,sentence)
  55. #打印分词结果
  56. for eachChar in wordl:
  57. print(eachChar,end = "/ ")
  58. print("")#换行
  59. print("****************解析完毕!*********************")
  60. #运行
  61. if __name__ == '__main__':
  62. main()
五、运行结果





六、总结

关于效率:

正向最大匹配法分词占用很大计算量,结果本人测试,100多个字的一段话一般2秒分完。1000个字的一段话,需要20几秒才能分完。以最大词长为20来计算的话,待分的句子为20个字,假设全部分成2字词,词表中有5万个词,则计算量约为22*5*50000=550万。如此可见,当待分词句子很长,最大词长很大时,计算量是惊人的。

关于分词准确度:

正向最大匹配法的缺陷在与精确度不能达到理想的状态。同时也不能解决词的歧义问题。(统计结果表明,单纯使用正向最大匹配的错误率为1/169,单纯使用逆向最大匹配的错误率为1/245。


(文章如有错误,敬请指正)


运行源码以及全部文档下载地址: http://download.csdn.net/detail/xn4545945/5182311


原创文章,转载请注明出处:http://blog.csdn.net/xn4545945





声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/374857
推荐阅读
相关标签
  

闽ICP备14008679号