最近需要用到中文分词,本来想省事,用python的第三方库结巴分词,但看了下API,计算文本关键词的方法没有没有返回关键字对应的权值,翻了下文档应该是不还不支持,只好继续使用中科院的那套ICTCLAS分词组件,2013最新版已经改名为NLPIR,函数名前缀做了改变,少许函数的参数也有了变化,对于这种没有产品意识的产品来说,我已无力吐槽,我等屌丝只能跟着修改中间模块的源代码了。

转成Python调用常用的有三种模式:

python使用ctypes加载so文件:高耦合度,要去so文件里翻函数的链接符号,太繁琐,但也是最直接的方式。

通过swig将c++的声明文件转化为swig的表达方式,再通过g++编译成python可直接import的模块:无奈swig对一些复杂的C++数据结构还支持的不是很好,类似NLPIR中提供的NLPIR_ParagraphProcessA(NLPIR_API const result_t * NLPIR_ParagraphProcessA(const char *sParagraph,int *pResultCount,bool bUserDict=true);)无法很好的被swig转换,按照官网的一些建议折腾半天也没成功,有搞定的同学跟我说声儿。

使用boost.python库将NLPIR的声明文件进行转化,之后用g++编译为python可直接import的模块,由于boost是C++系的,对原始的数据结构兼容性好,本文选用该方法。

本文测试环境:

Ubuntu 10.04 x64 + NLPIR2013

首先安装boost.python开发包:

apt-get install libboost-python-dev

将官方提供的libNLPIR.so,NLPIR.h置于同一目录下,并在该目录下新建名为nlpir.cpp的文件,内容如下:

# Modified by pnig0s @ 20131214#include #include #include #include "NLPIR.h"using namespace boost::python;struct my_result{ int start; int length; std::string sPOS; int iPOS; int word_ID; int word_type; int weight;};bool ict_init(const char* pDirPath, int encode=0){ return NLPIR_Init(pDirPath);} bool ict_exit(){ return NLPIR_Exit();} unsigned int import_dict(const char *sFilename){ return NLPIR_ImportUserDict(sFilename);} const char * process_str(const char *sParag, int bTagged){ return NLPIR_ParagraphProcess(sParag, bTagged);} my_result& copy_result_t(my_result& re, const result_t& t){ re.start = t.start; re.length = t.length; re.sPOS = std::string(&t.sPOS[0]); re.iPOS = t.iPOS; re.word_ID = t.word_ID; re.word_type = t.word_type; re.weight = t.weight; return re;} list process_str_ret_list(const char *sParag){ int pResultCount = 0; const result_t* re = NLPIR_ParagraphProcessA(sParag, &pResultCount); list result; for (int i=0; i("result_t") .def_readonly("start", &my_result::start) .def_readonly("length", &my_result::length) .def_readonly("ipos", &my_result::iPOS) .def_readonly("word_id", &my_result::word_ID) .def_readonly("spos", &my_result::sPOS) .def_readonly("word_type", &my_result::word_type) .def_readonly("weight", &my_result::weight); def("ict_init", ict_init); def("ict_exit", ict_exit); def("import_dict", import_dict); def("process_str", process_str); def("process_str_ret_list", process_str_ret_list); def("process_file", process_file); def("process_str_ret_word_count", process_str_ret_word_count); def("add_user_word", add_user_word); def("get_keywords", get_keywords); def("save_user_dict", save_user_dict); def("del_user_word", del_user_word); def("set_pos_map", set_pos_map); enum_("POSMAP") .value("ICT_SECOND", ICT_SECOND) .value("ICT_FIRST", ICT_FIRST) .value("PKU_SECOND", PKU_SECOND) .value("PKU_FIRST", PKU_FIRST); enum_("CODE") .value("CHAR_GBK_CODE", CHAR_GBK_CODE) .value("CHAR_UTF8_CODE", CHAR_UTF8_CODE) .value("CHAR_BIG5_CODE", CHAR_BIG5_CODE) .value("CHAR_GBK_FANTI_CODE", CHAR_GBK_FANTI_CODE);}

g++ nlpir.cpp -shared -o nlpir.so -I/usr/include/python2.6 -lboost_python -L. -lNLPIR -m64 -DOS_LINUX -fPIC

我们只需要最终编译出来的nlpir.so,可以使用python直接import。ictclas一直以来对UTF-8的支持有先天缺陷,最新版虽然可以通过在init的时候指定UTF8_CODE支持UTF8文本的输入,但部分函数在处理UTF8编码的文本时还是存在问题,所以建议统一传入gb2312编码的文本,下面给出个用python封装过的例子:

#!/usr/bin/python# coding:utf-8# pnig0s 2013/12/14 import nlpir as icimport charset as csimport os curr_path = os.path.abspath(os.path.dirname(__file__)) class wordSeg: def __init__(self,userDict='',posMap=0): self.preText = '' self.rawCharset = '' self.resultDict = [] self.resultStr = '' self.Init = ic.ict_init self.Exit = ic.ict_exit self.ImportUserDict = ic.import_dict self.ProcessToList = ic.process_str_ret_list self.ProcessToStr = ic.process_str self.GenKeyWords = ic.get_keywords self.setPosMap = ic.set_pos_map self.ICT_FIRST = ic.POSMAP.ICT_FIRST self.ICT_SECOND = ic.POSMAP.ICT_SECOND self.PKU_FIRST = ic.POSMAP.PKU_FIRST self.PKU_SECOND = ic.POSMAP.PKU_SECOND self.GBK_CODE = ic.CODE.CHAR_GBK_CODE self.UTF8_CODE = ic.CODE.CHAR_UTF8_CODE self.BIG5_CODE = ic.CODE.CHAR_BIG5_CODE self.GBK_FANTI_CODE = ic.CODE.CHAR_GBK_FANTI_CODE self.init(userDict,posMap) def init(self,userDict= '',posMap= 0): if not self.Init(curr_path,self.GBK_CODE): print 'ICTCLAS init failed.' else: if userDict: if not self.ImportUserDict(curr_path+'/'+userDict): print 'Import user dict failed.' else: if posMap: if not self.setPosMap(posMap): print 'Set pos map failed.' def segment(self,rList= True,rKeyWords= True,rPOS= True): ''' 封装了ICTCLAS两种分词模式: rList = True时,返回分词结果的详细数据结构,其中rKeyWords指明以关键词模式返回或普通模式返回 rList = False时,返回所有分词片段组成的字符串,其中rPOS指明是否进行词性标注。 ''' if all((rList,self.preText)): optResult = [] self.preText = self.convertToGB(self.preText) splitResult = self.ProcessToList(self.preText) if rKeyWords: token_str = self.GenKeyWords(self.preText,len(splitResult),True) if token_str: token_list = token_str.split('#')[:-1] if vars().has_key('token_list') and token_list: for token in token_list: token = token.split('/') optResult.append({'spos':token[1], 'weight':float(token[2]), 'word_piece':self.decodeText(token[0])}) else: for rs in splitResult: optResult.append({'spos':rs.spos,'weight':float(0),'word_piece':self.decodeText(self.preText[rs.start:(rs.start+rs.length)])}) self.resultDict = optResult if not rList and self.preText: self.resultStr = self.decodeText(self.ProcessToStr(self.convertToGB(self.preText),1 if rPOS else 0)) def convertToGB(self,Text = ''): '''统一将文本编码转换为ICTCLAS要求的gb2312''' try: charset = cs.check(html=Text) except Exception,e: charset = 'ascii' self.rawCharset = 'gb2312' if charset == 'ascii': rc = Text.encode('gb2312','ignore') else: rc = Text.decode(charset,'ignore').encode('gb2312','ignore') return rc def decodeText(self,Text = ''): '''统一将文本编码转换为操作系统默认的utf8''' if self.rawCharset: return Text.decode(self.rawCharset,'ignore') def test(): ws = wordSeg('',posMap=0) ws.preText = '吃葡萄不吐葡萄皮,不吃葡萄倒吐葡萄皮。' ws.segment(rList=True,rKeyWords=False) for result in ws.resultDict: for key,value in result.iteritems(): print '%s:%s' % (key,value) ws.Exit() if __name__ == '__main__': test()

欢迎加入我爱机器学习QQ14群:336582044

微信扫一扫,关注我爱机器学习公众号

python语言常用的中文分词第三方库是_基于boost使用Python调用NLPIR(ICTCLAS2013)中文分词组件...相关推荐

  1. 不是python中用于开发用户界面的第三方库-python界面 | Tkinter图形界面开发库

    0 写在前面 未经允许,不得转载,谢谢~~ 毕设要在现有的基础上做一个可视化的界面,所以趁机也学习一波如何用python实现图形界面的开发. 本文主要学习并整理了: 简要介绍用于python图形界面开 ...

  2. 不是python中用于开发用户界面的第三方库-模拟试卷C

    原标题:模拟试卷C 一.单项选择题 1. 按照"后进先出"原则组织数据的数据结构是____ 队列 栈 双向链表 二叉树 2. 以下选项的叙述中,正确的是 循环队列有队头和队尾两个指 ...

  3. pip安装更新、第三方库对应的python解释器版本、pip安装第三方库,压缩包离线安装,pycharm快捷安装及pycharm中terminal的使用,timeout超时报错

    文章有点长,但是很详细,还望大家耐心看 之前在安装python的文章中已经给大家配置了pip环境变量(不了解的点这里去看看),这里就能直接在cmd窗口,不用切换路径,就能使用pip了. 首先 使用pi ...

  4. Python在指定环境下安装第三方库的报错解决办法

    Python在指定环境下安装第三方库的报错解决办法 在python安装第三方库时,如果直接打开cmd命令提示符,并输入下列安装命令,则会默认安装在base环境下 但base环境下的包新建的虚拟环境是无 ...

  5. Python下如何调用NLPIR(ICTCLAS2013)分词系统

    NLPIR汉语分词系统-Python下如何调用NLPIR(ICTCLAS2013) 在国内研究自然语言处理的人大概都知道ICTCLAS分词系统的大名.该系统是由张华平博士开发的基于层叠隐性马可夫链的分 ...

  6. python如何爬取图片到指定文件夹论文_基于Python的图片爬虫程序设计

    互联网中包含大量有价值的 数据,网络爬虫通过既定规则可 以自动地抓取互联网数据并下载 至本地存储.研究网络爬虫的工 作原理和基于 Python 网络信息爬 取技术模块功能,基于 Requests- B ...

  7. 中文分词第三方库_Python计算生态jieba库和random库的综合运用之爬山篇

    本篇文章会利用python语言中的第三方库jieba库和标准库random库来对文件中的相关元素进行操作. 实践中文片段:"今天是个好天气,大家一起去爬山."该句子分为上下两部分, ...

  8. 优秀的中文分词第三方库——jieba

    jieba库的使用 -中文文本需要通过分词获得单个的词语 -jieba是第三方库,需要额外安装: -pip install jieba jieba分词的三种模式 -精确模式:把文本精确地分开,不存在冗 ...

  9. python语言的计算生态规模有多大_【单选题】Python 语言的一个重要特点是它有较多的计算生态,简单理解为第三方提供的可用编程模块 / 函数库 / 组件,这个规模有多大?...

    [单选题]Python 语言的一个重要特点是它有较多的计算生态,简单理解为第三方提供的可用编程模块 / 函数库 / 组件,这个规模有多大? 更多相关问题 [问答题,简答题] 顾客关系管理系统如何给企业 ...

最新文章

  1. mysql 行锁 超时_技术分享 | MySQL 行锁超时排查方法优化
  2. Test tape drive on Command Line
  3. editplus的配置和使用
  4. 生成具有三态背景图片的按钮
  5. html pc端万年历插件,# pc端个性化日历实现
  6. 计算机wps基础知识试题,计算机一级WPS考试试题及答案
  7. 多智能体强化学习_基于多智能体强化学习主宰星际争霸游戏
  8. 正则表达式的\b与\B总结
  9. 密码学加密算法分类_密码学中的国际数据加密算法(IDEA)
  10. Dirichlet过程混合模型(DPMM)的Gibbs抽样程序
  11. 华为鸿蒙系统学习笔记4-方舟编译器源码下载及安装
  12. ps aux、ps -aux、ps -ef之间的区别
  13. C/C++[算法入门]..
  14. tensorflow中的tf.get_variable
  15. 猜姓氏c语言题目,猜姓氏的谜语及答案
  16. matlab 读取npy,在将mat中的mat数据转换为Python中使用的NPY数据时遇到的Pit问题,Matlab,转成,python,npy,坑...
  17. iphone里如何实现像图片浏览那样的自动隐藏和导航条和工具栏
  18. 最新表情包小程序+前后端去授权版/最火表情包小程序源码
  19. 学习笔记42—Win7下安装Linux双系统
  20. 利用Karabiner和键盘修饰键修改MAC键盘,实现打字时双手不离开字母和数字区

热门文章

  1. pathon学习日记
  2. sketch常用快捷键键盘对应
  3. android导出微信朋友圈怎么发文字,微信朋友圈怎么发纯文字?看完这篇文章,你就知道该怎么操作了...
  4. 日拱一卒,功不唐捐 | 每日思考俱乐部 专栏更新通知
  5. matplotlib中的imshow()绘图长宽比例失调,调整长宽比(备忘)
  6. (十二):为什么需要一个新的ORM框架
  7. 群接龙拼团小程序开发
  8. 关于offsetX、layerX、clientX、screenX以及pageX
  9. 东塔靶场之文件上传cms--pluck
  10. 微信小程序使用VANT filed 组件 input框内文字省略