⼈⼯智能机器学习之NLP和中⽂分词算法
前⾔:在⼈类社会中,语⾔扮演着重要的⾓⾊,语⾔是⼈类区别于其他动物的根本标志,没有语⾔,⼈类的思维⽆从谈起,沟通交流更是⽆源之⽔。
所谓“⾃然”乃是寓意⾃然进化形成,是为了区分⼀些⼈造语⾔,类似C++、Java等⼈为设计的语⾔。
NLP的⽬的是让计算机能够处理、理解以及运⽤⼈类语⾔,达到⼈与计算机之间的有效通讯。
01 什么是NLP
手机信号覆盖1. NLP的概念
NLP(Natural Language Processing,⾃然语⾔处理)是计算机科学领域以及⼈⼯智能领域的⼀个重要的研究⽅向,它研究⽤计算机来处理、理解以及运⽤⼈类语⾔(如中⽂、英⽂等),达到⼈与计算机之间进⾏有效通讯。
在⼀般情况下,⽤户可能不熟悉机器语⾔,所以⾃然语⾔处理技术可以帮助这样的⽤户使⽤⾃然语⾔和机器交流。从建模的⾓度看,为了⽅便计算机处理,⾃然语⾔可以被定义为⼀组规则或符号的集合,我们组合集合中的符号来传递各种信息。
这些年,NLP研究取得了长⾜的进步,逐渐发展成为⼀门独⽴的学科,从⾃然语⾔的⾓度出发,NLP基本可以分为两个部分:⾃然语⾔处理以及⾃然语⾔⽣成,演化为理解和⽣成⽂本的任务,如图所⽰。
悟空英语▲NLP的基本分类
⾃然语⾔的理解是个综合的系统⼯程,它⼜包含了很多细分学科,有代表声⾳的⾳系学,代表构词法的词态学,代表语句结构的句法学,代表理解的语义句法学和语⽤学。
⾳系学:指代语⾔中发⾳的系统化组织。
词态学:研究单词构成以及相互之间的关系。
句法学:给定⽂本的哪部分是语法正确的。
语义学:给定⽂本的含义是什么?
语⽤学:⽂本的⽬的是什么?
语⾔理解涉及语⾔、语境和各种语⾔形式的学科。⽽⾃然语⾔⽣成(Natural Language Generation,NLG)恰恰相反,从结构化数据中以读取的⽅式⾃动⽣成⽂本。该过程主要包含三个阶段:
⽂本规划:完成结构化数据中的基础内容规划
语句规划:从结构化数据中组合语句来表达信息流
实现:产⽣语法通顺的语句来表达⽂本
2. NLP的研究任务
NLP可以被应⽤于很多领域,这⾥⼤概总结出以下⼏种通⽤的应⽤:
机器翻译:计算机具备将⼀种语⾔翻译成另⼀种语⾔的能⼒。
情感分析:计算机能够判断⽤户评论是否积极。
81年属鸡的是什么命
智能问答:计算机能够正确回答输⼊的问题。
⽂摘⽣成:计算机能够准确归纳、总结并产⽣⽂本摘要。
⽂本分类:计算机能够采集各种⽂章,进⾏主题分析,从⽽进⾏⾃动分类。
舆论分析:计算机能够判断⽬前舆论的导向。
知识图谱:知识点相互连接⽽成的语义⽹络。
机器翻译是⾃然语⾔处理中最为⼈所熟知的场景,国内外有很多⽐较成熟的机器翻译产品,⽐如百度翻译、Google翻译等,还有提供⽀持语⾳输⼊的多国语⾔互译的产品。
情感分析在⼀些评论⽹站⽐较有⽤,⽐如某餐饮⽹站的评论中会有⾮常多拔草的客⼈的评价,如果⼀眼扫过去满眼都是⼜贵⼜难吃,那谁还想去呢?另外有些商家为了获取⼤量的客户不惜雇佣⽔军灌⽔,那就可以通过⾃然语⾔处理来做⽔军识别,情感分析来分析总体⽤户评价是积极还是消极。
智能问答在⼀些电商⽹站有⾮常实际的价值,⽐如代替⼈⼯充当客服⾓⾊,有很多基本⽽且重复的问题,其实并不需要⼈⼯客服来解决,通过智能问答系统可以筛选掉⼤量重复的问题,使得⼈⼯座席能更好地服务客户。
⽂摘⽣成利⽤计算机⾃动地从原始⽂献中摘取⽂摘,全⾯准确地反映某⼀⽂献的中⼼内容。这个技术可以帮助⼈们节省⼤量的时间成本,⽽且效率更⾼。
⽂本分类是机器对⽂本按照⼀定的分类体系⾃动标注类别的过程。举⼀个例⼦,垃圾邮件是⼀种令⼈头痛的顽症,困扰着⾮常多的互联⽹⽤户。2002年,Paul Graham提出使⽤“贝叶斯推断”来过滤垃圾
邮件,1000封垃圾邮件中可以过滤掉995封并且没有⼀个是误判,另外这种过滤器还具有⾃我学习功能,会根据新收到的邮件,不断调整。也就是说收到的垃圾邮件越多,相对应的判断垃圾邮件的准确率就越⾼。
舆论分析可以帮助分析哪些话题是⽬前的热点,分析传播路径以及发展趋势,对于不好的舆论导向可以进⾏有效的控制。
知识图谱(Knowledge Graph/Vault)⼜称科学知识图谱,在图书情报界称为知识域可视化或知识领域映射地图,是显⽰知识发展进程与结构关系的⼀系列各种不同的图形,⽤可视化技术描述知识资源及其载体,挖掘、分析、构建、绘制和显⽰知识及它们之间的相互联系。知识图谱的⼀般表现形式如图所⽰。
▲知识图谱图⽰
3. NLP相关知识的构成
3.1 基本术语
为了帮助读者更好地学习NLP,这⾥会⼀⼀介绍NLP领域的⼀些基础专业词汇。
(1)分词(gment)
词是最⼩的能够独⽴活动的有意义的语⾔成分,英⽂单词之间是以空格作为⾃然分界符的,⽽汉语是以字为基本的书写单位,词语之间没有明显的区分标记,因此,中⽂词语分析是中⽂分词的基础与关键。
中⽂和英⽂都存在分词的需求,不过相较⽽⾔,英⽂单词本来就有空格进⾏分割,所以处理起来相对⽅便。但是,由于中⽂是没有分隔符的,所以分词的问题就⽐较重要。
分词常⽤的⼿段是基于字典的最长串匹配,据说可以解决85%的问题,但是歧义分词很难。举个例⼦,“美国会通过对台售武法案”,我们既可以切分为“美国/会/通过对台售武法案”,⼜可以切分成“美/国会/通过对台售武法案”。
(2)词性标注(part-of-speech tagging)
基于机器学习的⽅法⾥,往往需要对词的词性进⾏标注。词性⼀般是指动词、名词、形容词等。标注的⽬的是表征词的⼀种隐藏状态,隐藏状态构成的转移就构成了状态转移序列。例如:我/r爱/v北京/ns天安门/ns。其中,ns代表名词,v代表动词,ns、v都是标注,以此类推。
(3)命名实体识别(NER,Named Entity Recognition)
命名实体是指从⽂本中识别具有特定类别的实体(通常是名词),例如⼈名、地名、机构名、专有名词等。
(4)句法分析(syntax parsing)
句法分析往往是⼀种基于规则的专家系统。当然也不是说它不能⽤统计学的⽅法进⾏构建,不过最初的时候,还是利⽤语⾔学专家的知识来构建的。句法分析的⽬的是解析句⼦中各个成分的依赖关系。
所以,往往最终⽣成的结果是⼀棵句法分析树。句法分析可以解决传统词袋模型不考虑上下⽂的问题。⽐如,“⼩李是⼩杨的班长”和“⼩杨是⼩李的班长”,这两句话,⽤词袋模型是完全相同的,但是句法分析可以分析出其中的主从关系,真正理清句⼦的关系。
伊人55(5)指代消解(anaphora resolution)
中⽂中代词出现的频率很⾼,它的作⽤的是⽤来表征前⽂出现过的⼈名、地名等。
例如,清华⼤学坐落于北京,这家⼤学是⽬前中国最好的⼤学之⼀。在这句话中,其实“清华⼤学”这个词出现了两次,“这家⼤学”指代的就是清华⼤学。但是出于中⽂的习惯,我们不会把“清华⼤学”再重复⼀遍。
(6)情感识别(emotion recognition)
所谓情感识别,本质上是分类问题,经常被应⽤在舆情分析等领域。情感⼀般可以分为两类,即正⾯、负⾯,也可以是三类,在前⾯的基础上,再加上中性类别。
⼀般来说,在电商企业,情感识别可以分析商品评价的好坏,以此作为下⼀个环节的评判依据。通常可以基于词袋模型+分类器,或者现在流⾏的词向量模型+RNN。经过测试发现,后者⽐前者准确率略有提升。
(7)纠错(correction)
⾃动纠错在搜索技术以及输⼊法中利⽤得很多。由于⽤户的输⼊出错的可能性⽐较⼤,出错的场景也⽐较多。所以,我们需要⼀个纠错系统。具体做法有很多,可以基于N-Gram进⾏纠错,也可以通过字典树、有限状态机等⽅法进⾏纠错。
(8)问答系统(QA system)
这是⼀种类似机器⼈的⼈⼯智能系统。⽐较著名的有:苹果Siri、IBM Watson、微软⼩冰等。问答系统往往需要语⾳识别、合成,⾃然语⾔理解、知识图谱等多项技术的配合才会实现得⽐较好。
3.2 知识结构
作为⼀门综合学科,NLP是研究⼈与机器之间⽤⾃然语⾔进⾏有效通信的理论和⽅法。这需要很多跨学科的知识,需要语⾔学、统计学、最优化理论、机器学习、深度学习以及⾃然语⾔处理相关理论模型知识做基础。
作为⼀门杂学,NLP可谓是包罗万象,体系化与特殊化并存,这⾥简单罗列其知识体系,知识结构结构图如图所⽰。
▲知识结构图⽰
⾃然语⾔的学习,需要有以下⼏个前置知识体系:
⽬前主流的⾃然语⾔处理技术使⽤python来编写。
统计学以及线性代数⼊门。
02 中⽂分词技术
1. 中⽂分词简介
“词”这个概念⼀直是汉语语⾔学界纠缠不清⽽⼜绕不开的问题。“词是什么”(词的抽象定义)和“什么是词”(词的具体界定),这两个基本问题迄今为⽌也未能有⼀个权威、明确的表述,更⽆法拿出令⼤众认同的词表来。主要难点在于汉语结构与印欧体系语种差异甚⼤,对词的构成边界⽅⾯很难进⾏界定。
⽐如,在英语中,单词本⾝就是“词”的表达,⼀篇英⽂⽂章就是“单词”加分隔符(空格)来表⽰的,⽽在汉语中,词以字为基本单位的,但是⼀篇⽂章的语义表达却仍然是以词来划分的。
因此,在处理中⽂⽂本时,需要进⾏分词处理,将句⼦转化为词的表⽰。这个切词处理过程就是中⽂分词,它通过计算机⾃动识别出句⼦的词,在词间加⼊边界标记符,分隔出各个词汇。
整个过程看似简单,然⽽实践起来却很复杂,主要的困难在于分词歧义。以NLP分词的经典语句举例,“结婚的和尚未结婚的”,应该分词
为“结婚/的/和/尚未/结婚/的”,还是“结婚/的/和尚/未/结婚/的”?这个由⼈来判定都是问题,机器就更难处理了。
此外,像未登录词、分词粒度粗细等都是影响分词效果的重要因素。
⾃中⽂⾃动分词被提出以来,历经将近30年的探索,提出了很多⽅法,可主要归纳为“规则分词”“统计
分词”和“混合分词(规则+统计)”这三个主要流派。
规则分词是最早兴起的⽅法,主要是通过⼈⼯设⽴词库,按照⼀定⽅式进⾏匹配切分,其实现简单⾼效,但对新词很难进⾏处理。
随后统计机器学习技术的兴起,应⽤于分词任务上后,就有了统计分词,能够较好应对新词发现等特殊场景。
然⽽实践中,单纯的统计分词也有缺陷,那就是太过于依赖语料的质量,因此实践中多是采⽤这两种⽅法的结合,即混合分词。
下⾯将详细介绍这些⽅法的代表性算法。
2. 规则分词饺子是怎么来的
基于规则的分词是⼀种机械分词⽅法,主要是通过维护词典,在切分语句时,将语句的每个字符串与词表中的词进⾏逐⼀匹配,找到则切分,否则不予切分。
按照匹配切分的⽅式,主要有正向最⼤匹配法、逆向最⼤匹配法以及双向最⼤匹配法三种⽅法。
2.1 正向最⼤匹配法
正向最⼤匹配(Maximum Match Method,MM法)的基本思想为:假定分词词典中的最长词有i个汉字字符,则⽤被处理⽂档的当前字串中的前i个字作为匹配字段,查找字典。若字典中存在这样的⼀个i字词,则匹配成功,匹配字段被作为⼀个词切分出来。如果词典中找不到这样的⼀个i字词,则匹配失败,将匹配字段中的最后⼀个字去掉,对剩下的字串重新进⾏匹配处理。
如此进⾏下去,直到匹配成功,即切分出⼀个词或剩余字串的长度为零为⽌。这样就完成了⼀轮匹配,然后取下⼀个i字字串进⾏匹配处理,直到⽂档被扫描完为⽌。
其算法描述如下:
从左向右取待切分汉语句的m个字符作为匹配字段,m为机器词典中最长词条的字符数。
查找机器词典并进⾏匹配。若匹配成功,则将这个匹配字段作为⼀个词切分出来。若匹配不成功,则将这个匹配字段的最后⼀个字去掉,剩下的字符串作为新的匹配字段,进⾏再次匹配,重复以上过程,直到切分出所有词为⽌。
⽐如我们现在有个词典,最长词的长度为5,词典中存在“南京市长”和“长江⼤桥”两个词。
1952年属龙的是什么命
现采⽤正向最⼤匹配对句⼦“南京市长江⼤桥”进⾏分词,那么⾸先从句⼦中取出前五个字“南京市长江”,发现词典中没有该词,于是缩⼩长度,取前4个字“南京市长”,词典中存在该词,于是该词被确认切分。再将剩下的“江⼤桥”按照同样⽅式切分,得到“江”“⼤桥”,最终分为“南京市长”“江”“⼤桥”3个词。
显然,这种结果还不是我们想要的。
2.2 逆向最⼤匹配法
逆向最⼤匹配(Rever Maximum Match Method,RMM法)的基本原理与MM法相同,不同的是分词切分的⽅向与MM法相反。逆向最⼤匹配法从被处理⽂档的末端开始匹配扫描,每次取最末端的i个字符(i为词典中最长词数)作为匹配字段,若匹配失败,则去掉匹配字段最前⾯的⼀个字,继续匹配。相应地,它使⽤的分词词典是逆序词典,其中的每个词条都将按逆序⽅式存放。
在实际处理时,先将⽂档进⾏倒排处理,⽣成逆序⽂档。然后,根据逆序词典,对逆序⽂档⽤正向最⼤匹配法处理即可。
由于汉语中偏正结构较多,若从后向前匹配,可以适当提⾼精确度。所以,逆向最⼤匹配法⽐正向最
⼤匹配法的误差要⼩。统计结果表明,单纯使⽤正向最⼤匹配的错误率为1/169,单纯使⽤逆向最⼤匹配的错误率为1/245。
⽐如之前的“南京市长江⼤桥”,按照逆向最⼤匹配,最终得到“南京市”“长江⼤桥”。当然,如此切分并不代表完全正确,可能有个叫“江⼤桥”的“南京市长”也说不定。
2.3 双向最⼤匹配法
双向最⼤匹配法(Bi-directction Matching method)是将正向最⼤匹配法得到的分词结果和逆向最⼤匹配法得到的结果进⾏⽐较,然后按照最⼤匹配原则,选取词数切分最少的作为结果。
据SunM.S.和Benjamin K.T.(1995)的研究表明,中⽂中90.0%左右的句⼦,正向最⼤匹配法和逆向最⼤匹配法完全重合且正确,只有⼤概9.0%的句⼦两种切分⽅法得到的结果不⼀样,但其中必有⼀个是正确的(歧义检测成功),只有不到1.0%的句⼦,使⽤正向最⼤匹配法和逆向最⼤匹配法的切分虽重合却是错的,或者正向最⼤匹配法和逆向最⼤匹配法切分不同但两个都不对(歧义检测失败)。这正是双向最⼤匹配法在实⽤中⽂信息处理系统中得以⼴泛使⽤的原因。
前⾯举例的“南京市长江⼤桥”,采⽤该⽅法,中间产⽣“南京市/长江/⼤桥”和“南京市/长江⼤桥”两种结果,最终选取词数较少的“南京市/长江⼤桥”这⼀结果。
下⾯是⼀段实现逆向最⼤匹配的代码。
#逆向最⼤匹配
class IMM(object):
def __init__(lf, dic_path):
lf.dictionary = t()
lf.maximum = 0
#读取词典
with open(dic_path, 'r', encoding='utf8') as f:
for line in f:
line = line.strip()
if not line:
continue
lf.dictionary.add(line)
lf.maximum = len(line)
def cut(lf, text):
result = []
index = len(text)
while index > 0:
word = None
for size in range(lf.maximum, 0, -1):
if index - size < 0:
continue
劳动用工合同范本piece = text[(index - size):index]
if piece in lf.dictionary:
word = piece
result.append(word)
index -= size
break
if word is None:
index -= 1
return result[::-1]
def main():
text = "南京市长江⼤桥"
tokenizer = IMM('./data/imm_dic.utf8')
print(tokenizer.cut(text))
运⾏main函数,结果为:
['南京市', '长江⼤桥']
基于规则的分词,⼀般都较为简单⾼效,但是词典的维护是⼀个很庞⼤的⼯程。在⽹络发达的今天,⽹络新词层出不穷,很难通过词典覆盖到所有词。
3. 统计分词
随着⼤规模语料库的建⽴,统计机器学习⽅法的研究和发展,基于统计的中⽂分词算法渐渐成为主流。
其主要思想是把每个词看做是由词的最⼩单位的各个字组成的,如果相连的字在不同的⽂本中出现的次数越多,就证明这相连的字很可能就是⼀个词。
因此我们就可以利⽤字与字相邻出现的频率来反应成词的可靠度,统计语料中相邻共现的各个字的组合的频度,当组合频度⾼于某⼀个临界值时,我们便可认为此字组可能会构成⼀个词语。
基于统计的分词,⼀般要做如下两步操作:
建⽴统计语⾔模型。
对句⼦进⾏单词划分,然后对划分结果进⾏概率计算,获得概率最⼤的分词⽅式。这⾥就⽤到了统计学习算法,如隐含马尔可夫(HMM)、条件随机场(CRF)等。
限于篇幅,本⽂只对统计分词相关技术做简要介绍。更多详细内容请参考《Python⾃然语⾔处理实战:核⼼技术与算法》⼀书第3章第3.3节。鬼刀手机壁纸
4. 混合分词
事实上,⽬前不管是基于规则的算法、还是基于HMM、CRF或者deep learning等的⽅法,其分词效果在具体任务中,其实差距并没有那么明显。在实际⼯程应⽤中,多是基于⼀种分词算法,然后⽤其他分词算法加以辅助。
最常⽤的⽅式就是先基于词典的⽅式进⾏分词,然后再⽤统计分词⽅法进⾏辅助。如此,能在保证词典分词准确率的基础上,对未登录词和歧义词有较好的识别。