中文分词技术属于自然语言处理技术范畴,中文分词是其他中文信息处理的基础,比如搜索引擎只是中文分词的一个应用。
中文分词指的是将一个汉字序列切分成一个个单独的词。分词就是将------>连续的字序列------>按照一定的规范------>重新组合成词序列------>的过程。
大家都知道,对于英文而言,单词之间是有固定的空格作为自然分界符的,中文只能是以句段通过明显分分界符来简单划界,而词没有一个形式上的分界符。
机器翻译,语音合成,自动分类,自动摘要,自动校对,搜索引擎这些都要用到中文分词。
中文分词就是让计算机在词与词之间加上边界标记。当前研究所面临的问题和困难主要体现在三个方面:分词的规范、歧义词的切分和未登录词识别。
(1) 分词的规范。
中文因其自身语言特性的局限,字(词)的界限往往很模糊,关于字(词)的抽象定义和词边界的划定尚没有一个公认的、权威的标准。曾经有专家对母语是汉语者进行了调查,结果显示,对汉语文本中“词”的认同率仅有 70% 左右。正是由于这种不同的主观分词差异,给汉语分词造成了极大的困难。尽管在 1992 年国家颁布了《信息处理用现代词汉语分词规范》,但是这种规范很容易受主观因素影响,在处理现实问题时也不免相形见绌。
(2) 歧义词切分。
中文中的歧义词是很普遍的,歧义词即同一个词有多种切分方式,该如何处理这种问题呢?普遍认为中文歧义词有三种类型。
⊚ 交集型切分歧义,汉语词如AJB 类型,满足AJ 和JB 分别成词。如“大学生”一种切分方式“大学/生”,另一种切分方式“大/学生”。你很难去判定哪种切分正确,即使是人工切分也只能依据上下文,类似的有“结合成”“美国会”等。
⊚ 组合型切分歧义,汉语词如AB,满足A、B、AB 分别成词。如“郭靖有武功高超的才能”中的“才能”,一种切分为“郭靖/有/武功/高超/的/才能”,另一种切分“中国/什么/时候/才/能/达到/发达/国家/水平”显示是不同的切分方式。
⊚ 混合型切分歧义,汉语词包含如上两种共存情况。如“郭靖说这把剑太重了”,其中“太重了”是交集型字段,“太重”是组合型字段。
(3) 未登录词(新词)识别。
未登录词又称新词。这类词通常指两个方面,一是词库中没有收录的词,二是训练语料没有出现过的词。未登录词主要体现在以下几种。
⊚ 新出现的网络用词。如“蓝牙”“蓝瘦香菇”“房姐”“奥特”“累觉不爱”等。
⊚ 研究领域名称:特定领域和新出现领域的专有名词。如“苏丹红”“禽流感”“埃博拉”“三聚氰胺”等。
⊚ 其他专有名词:诸如城市名、公司企业、职称名、电影、书籍、专业术语、缩写词等。如“成都”“阿里巴巴”“三少爷的剑”“NLP”“川大”等。
(1) 基于字符串匹配的分词方法。
基本思想是基于词典匹配,将待分词的中文文本根据一定规则进行切分和调整,然后跟词典中的词语进行匹配,匹配成功则按照词典的词分词,匹配失败则通过调整或者重新选择,如此反复循环即可。代表方法有基于正向最大匹配和基于逆向最大匹配及双向匹配法。
(2) 基于理解的分词方法。
基本思想是通过专家系统或者机器学习神经网络方法模拟人的理解能力。前者是通过专家对分词规则的逻辑推理并总结形成特征规则,不断迭代完善规则,其受到资源消耗大和算法复杂度高的制约。后者通过机器模拟人类理解的方式,虽然可以取得不错的效果,但是依旧受训练时间长和过拟合等因素困扰。
(3) 基于统计的分词方法。
关于统计的中文分词方法的基本思想如下所示:
⊚ 基于隐马尔可夫模型的中文分词方法。基本思想是通过文本作为观测序列去确定隐藏序列的过程。该方法采用Viterbi 算法对新词识别,效果不错,但具有生成式模型的缺点,需要计算联合概率,因此随着文本增大,存在计算量大的问题。
⊚ 基于最大熵模型的中文分词方法。基本思想是学习概率模型时,在可能的概率分布模型中,认为熵最大的进行切分。该方法可以避免生成模型的不足,但是存在偏移量的问题。
⊚ 基于条件随机场模型的中文分词方法。基本思想主要来源于最大熵马尔可夫模型,主要关注的字跟上下文标记位置有关,进而通过解码找到词边界。因此需要大量训练语料,而训练和解码又非常耗时。
总的来说,基于词典和统计的方法分词速度比较快,但是在不同领域取得的效果差异很大,还存在构造费时费力、算法复杂度高、移植性差等缺点。
基于统计的中文分词,虽然其相较于规则的方法取得了不错的效果,但也存在模型训练时间长、分词速度慢等问题。
HanLP 是由一系列模型与算法组成的Java 工具包,目标是普及自然语言处理在生产环境中的应用。HanLP 具备功能完善、性能高效、架构清晰、语料时新、可自定义等特点。在提供丰富功能的同时,HanLP 内部模块坚持低耦合、模型坚持惰性加载、服务坚持静态提供、词典坚持明文发布,使用起来非常方便,同时自带一些语料处理工具,帮助用户训练自己的语料
代码所示:
"""
author:jjk
datetime:2018/11/5
coding:utf-8
project name:Pycharm_workstation
Program function: python调用HanLP分词(中文)
"""
import jpype
from jpype import *
# 调用HanLP的java包,如下路径下载并解压c盘即可:
# 启动JVM,Linux需替换分号;为冒号:
startJVM(getDefaultJVMPath(),
"-Djava.class.path=F:/Pycharm/Pycharm_workstation/NLP and actual combat/chapter eight\hanlp-1.6.8.jar;"
"F:/Pycharm/Pycharm_workstation/NLP and actual combat/chapter eight", "-Xms1g", "-Xmx1g")
# 默认分词
print("=" * 30 + "HanLP分词" + "=" * 30)
paraStr1 = '中国科学院计算技术研究所的宗成庆教授正在教授自然语言处理课程'
HanLP = JClass('com.hankcs.hanlp.HanLP')
print(HanLP.segment(paraStr1))
# 标准分词
print("=" * 30 + "标准分词" + "=" * 30)
StandardTokenizer = JClass('com.hankcs.hanlp.tokenizer.StandardTokenizer')
print(StandardTokenizer.segment(paraStr1))
# NLP分词NLPTokenizer会执行全部命名实体识别和词性标注
print("=" * 30 + "NLP分词" + "=" * 30)
NLPTokenizer = JClass('com.hankcs.hanlp.tokenizer.NLPTokenizer')
print(NLPTokenizer.segment(paraStr1))
# 索引分词
print("=" * 30 + "索引分词" + "=" * 30)
IndexTokenizer = JClass('com.hankcs.hanlp.tokenizer.IndexTokenizer')
termList = IndexTokenizer.segment(paraStr1) # 获取分词内容
for term in termList:
print(str(term) + " [" + str(term.offset) + ":" + str(term.offset + len(term.word)) + "]")
# 极速索引分词
print("=" * 30 + " 极速词典分词" + "=" * 30)
SpeedTokenizer = JClass('com.hankcs.hanlp.tokenizer.SpeedTokenizer')
print(NLPTokenizer.segment(paraStr1))
# 自定义分词
paraStr2 = '攻城狮逆袭单身狗,迎娶白富美,走上人生巅峰'
print("=" * 30 + " 自定义分词" + "=" * 30)
CustomDictionary = JClass('com.hankcs.hanlp.dictionary.CustomDictionary')
CustomDictionary.add('攻城狮')
CustomDictionary.add('单身狗')
HanLP = JClass('com.hankcs.hanlp.HanLP')
print(HanLP.segment(paraStr2))
# 命名实体标识和词性标注
print("=" * 20 + "命名实体识别与词性标注" + "=" * 30)
NLPTokenizer = JClass('com.hankcs.hanlp.tokenizer.NLPTokenizer')
print(NLPTokenizer.segment(paraStr1))
# 关键字提取
f = open("paraStr3.txt", "rb") # 读取文本
string = f.read().decode("utf-8")
# paraStr3="水利部水资源司司长陈明忠9月29日在国务院新闻办举行的新闻发布会上透露,根据刚刚完成了水资源管理制度的考核,有部分省接近了红线的指标,有部分省超过红线的指标。对一些超过红线的地方,陈明忠表示,对一些取用水项目进行区域的限批,严格地进行水资源论证和取水许可的批准。"
print("=" * 30 + "关键词提取" + "=" * 30)
print(HanLP.extractKeyword(string, 8))
# 获取文字---自动生成摘要
ff = open("paraStr0.txt", "rb") # 读取文本
string2 = ff.read().decode("utf-8")
print("=" * 30 + "自动摘要" + "=" * 30)
print(HanLP.extractSummary(string2, 5))
# 地方名识别
paraStr4 = ["武胜县新学乡政府大楼门前锣鼓喧天", "蓝翔给宁夏固原市彭阳县红河镇黑牛沟村捐赠了挖掘机"]
print("=" * 30 + "地名识别" + "=" * 30)
HanLP = JClass('com.hankcs.hanlp.HanLP')
segment = HanLP.newSegment().enablePlaceRecognize(True)
for sentence in paraStr4:
print(HanLP.segment(sentence))
# 依存句法分析
paraStr5 = "徐先生还具体帮助他确定了把画雄鹰、松鼠和麻雀作为主攻目标。"
print("=" * 30 + "依存句法分析" + "=" * 30)
print(HanLP.parseDependency(paraStr5))
jpype.shutdownJVM()
玻森实验室开发的一款分词工具。
以哈工大社会计算与信息检索研究中心研发的“语言技术平台(LTP)”为基础,为用户提供高效精准的中文自然语言处理云服务。
中科院分词系统。
简易中文分词系统缩写。SCWS 由hightman 开发,并以BSD 许可协议开源发
布,源码托管在GitHub。
一个开源的、基于Java 语言开发的轻量级的中文分词工具包。
(1) 支持三种分词模式。
⊚ 精确模式,试图将句子最精确地切开,适合文本分析;
⊚ 全模式,把句子中所有的可以成词的词语都扫描出来,速度非常快,但是不能解决歧义;
⊚ 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。
(2) 支持繁体分词
(3) 支持自定义词典
安装:命令窗口下:
获取分词工具
链接:https://pan.baidu.com/s/117i8BG_pslFpXFEgfJNCfw
提取码:9jzf
⊚ jieba.cut 方法接受三个输入参数:需要分词的字符串;cut_all 参数用来控制是否采用全模式;HMM 参数用来控制是否使用HMM 模型。
⊚ jieba.cut_for_search 方法接受两个参数:需要分词的字符串;是否使用HMM 模型。该方法适合用于搜索引擎构建倒排索引的分词,粒度比较细。
⊚ 待分词的字符串可以是Unicode 或UTF-8 字符串、GBK 字符串。注意:不建议直接输入GBK 字符串,可能无法预料地错误解码成UTF-8。
⊚ jieba.cut 和jieba.cut_for_search 返回的结构都是一个可迭代的generator,可以使用for循环来获得分词后得到的每一个词语(Unicode)。
⊚ jieba.lcut 和jieba.lcut_for_search 直接返回list。
⊚ jieba.Tokenizer(dictionary=DEFAULT_DICT) 新建自定义分词器,可用于同时使用不同词典。jieba.dt 为默认分词器,所有全局分词相关函数都是该分词器的映射。
"""
author:jjk
datetime:2018/11/6
coding:utf-8
project name:Pycharm_workstation
Program function: 结巴分词
"""
import jieba
import time
start_time = time.time()
# 默认是精确模式
seg_list = jieba.cut("我是倒霉贾,我来自昆明理工大学",cut_all=True)
print("全模式:" + "/ ".join(seg_list)) # 全模式
seg_list = jieba.cut("我是倒霉贾,我来自昆明理工大学",cut_all=False)
print("精确模式:" + "/ ".join(seg_list)) # 精确模式
seg_list = jieba.cut_for_search("我是倒霉贾,我来自昆明理工大学")# 搜素引擎模式
print("搜索引擎模式:",", ".join(seg_list))
stop_time = time.time()
time_sum = stop_time-start_time
print("一共耗时:",time_sum)
载入词典
⊚ 开发者可以指定自己自定义的词典,以便包含jieba 词库里没有的词。虽然jieba 有新词识别能力,但是自行添加新词可以保证更高的正确率。
⊚ 用法:jieba.load_userdict(file_name) # file_name 为文件类对象或自定义词典的路径。
⊚ 词典格式和dict.txt 一样,一个词占一行;每一行分词语、词频(可省略)和词性(可省略)三部分,用空格隔开,顺序不可颠倒。file_name 若为路径或二进制方式打开的文件,则文件必须为UTF-8 编码。
(1) 基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图(DAG)。
(2) 采用了动态规划查找最大概率路径,找出基于词频的最大切分组合。
(3) 对于未登录词,采用基于汉字成词能力的HMM 模型,使用Viterbi 算法。
(1)基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图(DAG)。
生成句子中汉字所有可能成词情况所构成的有向无环图。DAG 根据我们生成的前缀字典来构造一个这样的DAG,对一个sentence DAG 是以{key:list[i,j…], …} 的字典结构存储,其中key 是词在sentence 中的位置,list 存放的是在sentence 中以key 开始且词sentence[key:i+1]在前缀词典中以key 开始i 结尾的词的末位置i 的列表,即list 存放的是sentence 中以位置key 开始的可能词语的结束位置,这样通过查字典得到词,以及开始位置+ 结束位置列表。
例如:
句子“抗日战争”生成的DAG中{0:[0,1,3]} 这样一个简单的DAG, 就是表示0位置开始, 在0,1,3位置都是词。就是说0-0,0-1,0-3 即“抗”,“抗日”,“抗日战争”这三个词在dict.txt中是词。
(2)采用动态规划查找最大概率路径,找出基于词频的最大切分组合。基于上面的DAG 利用动态规划查找最大概率路径,理解DP 算法(动态规划算法)很容易就能明白了。根据动态规划查找最大概率路径的基本思路就是对句子从右往左反向计算最大概率。依次类推,最后得到最大概率路径,得到最大概率的切分组合(这里满足最优子结构性质,可以利用反证法进行证明)。代码实现中有个小诀窍,即概率对数(可以让概率相乘的计算变成对数相加,防止相乘造成下溢,因为在语料、词库中,每个词的出现概率平均下来还是很小的浮点数)。
(3)对于未登录词,采用基于汉字成词能力的HMM 模型,使用Viterbi 算法;未登录词其实就是词典dict.txt 中没有记录的词。这里采用了HMM 模型,HMM 是一个简单强大的模型HMM 在实际应用中主要用来解决3 类问题。
⊚ 评估问题(概率计算问题):即给定观测序列O=O1,O2,O3…Ot 和模型参数λ=(A,B, π \pi π),怎样有效计算这一观测序列出现的概率(Forward-backward 算法)。
⊚ 解码问题(预测问题):即给定观测序列O=O1,O2,O3…Ot 和模型参数λ=(A,B, π \pi π),怎样寻找满足这种观察序列意义上最优的隐含状态序列S (Viterbi 算法, 近似算法)。
⊚ 学习问题:即HMM 的模型参数λ=(A,B, π \pi π) 未知,如何求出这3 个参数以使观测序列 O=O1,O2,O3…Ot 的概率尽可能大(即用极大似然估计的方法估计参数,Baum-Welch,EM 算法)。
模型的关键相应参数λ=(A,B, π \pi π),经过作者对大量语料的训练,得到了finalseg 目录下的三个文件(初始化状态概率( π \pi π)即词语以某种状态开头的概率,其实只有两种,要么是B,要么是S。这个就是起始向量,就是HMM 系统的最初模型状态,对应文件prob _ start.py。
隐含状态概率转移矩A 即字的几种位置状态(用BEMS 四个状态来标记,B 是开始begin 位置;E 是end,是结束位置;M 是middle,是中间位置;S 是single,单独成词的位置)的转换概率,对应文件prob _ trans.py;
观测状态发射概率矩阵B 即位置状态到单字的发射概率,比如p(“狗”|M)表示一个词的中间现“狗”这个字的概率,对应文件prob_emit.py)。
至于结巴分词的用法,博主就不在这里一一详述了,以下的参考链接已经很好的说明了它的用法!!!
1、https://blog.csdn.net/meiqi0538/article/details/80218870
2、https://blog.csdn.net/meiqi0538/article/details/80213431
结束语:
对于中文分词,是其他中文信息处理的基础,比如搜索引擎只是中文分词的一个应用。在内容中博主也阐述了何为中文分词,中文分词的用途,特点以及难点,中文分词常用的方法以及中文分词的工具。自然语言处理是一个交叉学科,真的是很难,学的东西很多,一个小小的分支就够博主深入研究到毕业啦,,,能看到此处,都是好孩纸加油吧骚年!!!
说到中文分词的工具,你可能会想了解以下博文:
https://blog.csdn.net/Jiajikang_jjk/article/details/83750758
https://blog.csdn.net/Jiajikang_jjk/article/details/83756760
https://blog.csdn.net/Jiajikang_jjk/article/details/83782825