为了解决这个问题:我使用分词(词性标注)词典了,但是为什么某些词典词还是被切开了(词性没有按照字典标注)
官方解释为:ltp的分词(词性标注)模块 并非采用词典匹配的策略 ,外部词典以特征方式加入机器学习算法,并不能保证所有的词都是按照词典里的方式进行切分(标注)。 如果要完全按照词典匹配的方式切词(标注),您可以尝试对结果进行后处理。
为此我自己写了一个后处理模块,用来将切开了的词进行合并(保证同一句话中出现多次不能拆分的词,也能正确合并)。

主要思路如下:

  1. 构建一个强制分词词典
  2. 从强制分词词典生成正则表达式以加速词典查找过程
  3. 如果待分词的句子包含强制分词词典中的词,将切开的词进行合并,否则跳过。

测试了三种词查找方法的效率:

  • 将词拼接成形如(?:钢铁是怎样炼成的|钢铁侠)的正则表达式后编译,再用search效率最高。(事先编译需要消耗一定的时间,但是这个可以放在在初始化过程中,只用计算一次)
  • 遍历词典,用if word in sentence:来判断效率其次。
  • 遍历词典,用if sentence.find(word)>-1:来判断效率最低。

强制分词模块代码如下:

class ForceSegmentor(object):def __init__(self):self.forcelist = []def load(self, filepath):with open(filepath, 'r') as file:line = file.readline()while line:if ('#' in line):line = file.readline().strip()continueself.forcelist.append(ForceSegmentorItem(line))line = file.readline()self.compilelist = []y = 0xlen = 60stop = Falsewhile not stop:comstr = '(?:'for x in range(xlen):z = y * xlen + xif z > len(self.forcelist) - 1:stop = Truebreakif x > 0:comstr += '|'comstr += self.forcelist[z].get_text()comstr += ')'self.compilelist.append(re.compile(comstr.decode('utf8')))y += 1def find_in_dict(self,sentence):de_sentence = sentence.decode('utf8')for compilestr in self.compilelist:result=compilestr.search(de_sentence)if result:#找到句子中包含的字典中的词return result.group().encode('utf8')return Nonedef merge(self, sentence, words):# 有些词无法通过自定义分词词典直接正确划分,用该方法将属于强制词典的多个词合并# 例:“《钢铁是怎样炼成的》的主演是谁电影《钢铁是怎样炼成的》的主演是谁”得到# “《 钢铁是怎样炼成的 》 的 主演 是 谁 电影 《 钢铁是怎样炼成的 》 的 主演 是 谁”result = wordsfound_word=self.find_in_dict(sentence)if found_word:# 可能同一个词在这句话里出现多次indexs_start = []# 合并的词首尾距离index_distance = 0index_start = -1strm = ''for i, word in enumerate(words):wl = len(word)if (index_start == -1 and word == found_word[0:wl]):index_start = istrm += wordelif (index_start != -1):strm += wordif (strm == found_word):# 已经完全匹配indexs_start.append(index_start)index_distance = i - index_start + 1index_start = -1strm = ''elif (strm not in found_word):# 现在连接得到的多个词是错误的,重新开始匹配index_start = -1strm = ''result = []i = 0while (i < len(words)):word = words[i]if (i in indexs_start):result.append(found_word)i += index_distanceelse:result.append(word)i += 1return resultclass ForceSegmentorItem(object):def __init__(self, line):self.text = line.replace('\n', '')def get_text(self):return self.text

调用方法:

 ws = self.segmentor.segment(new_sentence.encode('utf8'))words = list(ws)#调用默认的ltp分词得到的分词结果forceSegmentor= ForceSegmentor()forceSegmentor.load('../init_data/cws.lex')words = forcesegmentor.merge(sentence, words)#强制分词以后的结果

附词典查找效率对比代码:

    def find_word(self):wlist=[]#测试大词典下的效果,forcelist词典本身70个词,wlist扩大10000倍for i in range(10000):wlist.extend(self.forcelist)import datetimesentence='《钢铁是怎样炼成的》的主演是谁电影《钢铁是怎样炼成的》的主演是谁'de_sentence= sentence.decode('utf8')begin = datetime.datetime.now()a=0for fi in wlist:fw = fi.get_text()if sentence.find(fw)>-1:a += 1end = datetime.datetime.now()k = end - beginprint 'find方法-找到次数:%s,耗时:%s' %(a, k.total_seconds())begin = datetime.datetime.now()a = 0for fi in wlist:fw = fi.get_text()if (fw in sentence):a+=1end = datetime.datetime.now()k=end-beginprint 'in方法-找到次数:%s,耗时:%s' %(a, k.total_seconds())compilelist=[]y=0xlen=60#每个编译语句中包含词的数量,根据词典大小调整可以进一步调高效率stop=Falsewhile not stop:comstr='(?:'for x in range(xlen):z=y*xlen+xif z>len(wlist)-1:stop=Truebreakif x>0:comstr+='|'comstr+=wlist[z].get_text()comstr+=')'compilelist.append(re.compile(comstr.decode('utf8')))y+=1begin = datetime.datetime.now()a = 0for compilestr in compilelist:result=compilestr.search(de_sentence)if result:g=result.group()a += 1end = datetime.datetime.now()k = end - beginprint '正则方法-找到次数:%s,耗时:%s' %(a, k.total_seconds())

结果:

find方法-找到次数:10000,耗时:0.169297
in方法-找到次数:10000,耗时:0.094882
正则方法-找到次数:10000,耗时:0.00471

ltp分词后处理——强制分词模块相关推荐

  1. 中文分词工具jieba分词器的使用

    1.常见的中文分词工具 中科院计算所的NLPIR 哈工大LTP 清华大学THULAC 斯坦福分词器 Hanlp分词器 jieba分词 IKAnalyzer 2.jieba分词算法主要有以下三种: 1. ...

  2. 《自然语言处理实战入门》 ---- 第4课 :中文分词原理及相关组件简介 之 汉语分词领域主要分词算法、组件、服务(上)...

    目录 0.内容梗概 1. 基于传统统计算法的分词组件 1.1 hanlp : Han Language Processing 1.2 语言技术平台(Language Technology Platfo ...

  3. 【NLP】为什么中文分词比英文分词更难?有哪些常用算法?(附代码)

    导读:人类文明的重要标志之一是语言文字的诞生.数千年来,几乎人类所有知识的传播都是以语言和文字作为媒介. 自然语言处理是使用计算机科学与人工智能技术分析和理解人类语言的一门学科.在人工智能的诸多范畴中 ...

  4. python分词_Python 结巴分词实现关键词抽取分析

    1 简介 关键词抽取就是从文本里面把跟这篇文档意义最相关的一些词抽取出来.这个可以追溯到文献检索初期,当时还不支持全文搜索的时候,关键词就可以作为搜索这篇论文的词语.因此,目前依然可以在论文中看到关键 ...

  5. 为什么中文分词比英文分词更难?有哪些常用算法?(附代码)

    导读:人类文明的重要标志之一是语言文字的诞生.数千年来,几乎人类所有知识的传播都是以语言和文字作为媒介. 自然语言处理是使用计算机科学与人工智能技术分析和理解人类语言的一门学科.在人工智能的诸多范畴中 ...

  6. 自然语言处理学习笔记2:分词工具及分词原理

    中文分词(Chinese Word Segmentation) 指的是将一个汉字序列切分成一个一个单独的词.分词就是将连续的字序列按照一定的规范重新组合成词序列的过程.我们知道,在英文的行文中,单词之 ...

  7. NLP考题:为什么中文分词比英文分词更难?有哪些常用算法?(附代码)

    导读:人类文明的重要标志之一是语言文字的诞生.数千年来,几乎人类所有知识的传播都是以语言和文字作为媒介. 自然语言处理是使用计算机科学与人工智能技术分析和理解人类语言的一门学科.在人工智能的诸多范畴中 ...

  8. ik分词和jieba分词哪个好_JiebaIK Analyzer——分词工具的比较与使用

    现有的分词工具包概览 现有的分词工具包种类繁多,我选取了几个比较常见的开源中文分词工具包进行了简单的调查.有感兴趣的同学可以通过下表中的Giuthub链接进行详细地了解. 常见开源的中文分词工具 接下 ...

  9. 详细介绍NLP中文分词原理及分词工具

    基于词表的分词方法 正向最大匹配算法FMM 从左到右扫描文本,得到词的最大匹配. 案例分析: 用正向最大匹配法对"秦皇岛今天晴空万里"进行中文分词,见下表. 词典 :"秦 ...

最新文章

  1. linux命令积累!
  2. 锚文本对网站SEO优化有什么帮助?
  3. redux react ajax,使用react-redux触发事件操作
  4. boost::is_convertible相关的测试程序
  5. keil中断函数的写法_在 KeilC里,中断子程序与函数有何不同?( )_学小易找答案
  6. django 日志配置
  7. Tomcat(三):日志
  8. 蔚来三元铁锂电池绕道超车
  9. Java中的泛型全解析(二)
  10. struts ValueStack 详解
  11. CNN卷积神经网络-tensorflow
  12. 当零售行业遇上小程序,该如何玩转全新商业模式
  13. layui 弹窗自适应高度_layui弹框自适应高度
  14. 【ROM制作工具】线刷包转卡刷包制作教程
  15. python写入文件取消自动换行
  16. PIL图像处理-二值化
  17. 十六进制和二进制相互转换(快速转换)
  18. 8.3 单位矩阵和逆矩阵
  19. 笔记本 - 常用快捷键 word 笔记
  20. PDF转word之后的结果事图片格式,如何改成.doc或.docx格式

热门文章

  1. 纪念中国人工智能学会成立40周年
  2. 区块链被正式纳入“新基建”,产业落地及生态共创成为行业共识
  3. 该死的Print Splooer
  4. arduino灯光装置_Arduino教程中级 项目一 点亮一盏灯
  5. 让我康康,还有谁不知道这些简单的vr全景制作“小心机”?
  6. SWIFT国际资金清算系统
  7. manifest.json 解析--手机web app开发笔记(三-2)
  8. 【陈工笔记】# LaTeX 中,图片如何不置顶? #
  9. 基于java的springboot电影院订票售票系统毕业设计springboot开题报告
  10. 如何用 Python 和 API 收集与分析网络数据?