漫话中文分词
此文已由作者赵斌授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
背景
美国小伙Tom在中国已经半年了,自认为中文已经不错,就想测试一下自己的水平到底有多高。于是,他收到了下面这样一份试题,请说出以下题目中两句话的区别在哪里:
1、冬天:能穿多少穿多少;夏天:能穿多少穿多少。
2、剩女的原因主要有两个,一个是谁都看不上,另外一个是谁都看不上。
3、单身人的来由:原来是喜欢一个人,现在是喜欢一个人。
4、地铁里一个女孩给男友打电话,"我已经到西直门了,你也出发吧。如果你到了,我还没到,你就等着吧。如果我到了,你还没到,你就等着吧。"
考完试后,老外的眼角是含着泪的,不知道是不是因为他爱这片土地爱得深沉。 看吧,这就是自然语言处理的魅力所在。完整的中文自然语言处理过程一般包括以下五种中文处理核心技术:分词、词性标注、命名实体识别、依存句法分析、语义分析。其中,分词是中文自然语言处理的基础,搜素引擎、文本挖掘、机器翻译、关键词提取、自动摘要生成等等技术都会用到中文分词,可以说分词是自然语言大厦的地基,下面就让我们从它开始谈起。
什么是中文分词?
中文分词就是将中文语句中的词汇按照使用时的含义切分出来的过程,也就是将一个汉字序列切分成一个个有单独含义的词语。自20世纪80年代以来,中文自动分词就一直是一个研究热点,由于中文语言的复杂性使之一直处于发展阶段。目前,分词主要包含细粒度分词和粗粒度分词两种,在不同的应用场景需要用到不同的粒度。细粒度分词是指将原始语句切分成最基本的词语,而粗粒度分词是指将原始语句中的多个基本词组合起来切成一个词,进而组成语义相对明确的实体。
原始串:浙江大学坐落在西湖旁边
细粒度:浙江/大学/坐落/在/西湖/旁边
粗粒度:浙江大学/坐落/在/西湖/旁边
为什么要中文分词
有人会问到:"为什么要进行中文分词呢?" 某人答:"因为搜索引擎要用,所以很重要。" 甚至有人认为:"中国之所以没有进行工业革命,就是因为中文没有自动分词。对于专业书籍来说,完全依靠人进行分词是很慢很困难的,直接影响到了知识的传播。"当然,最后还是要看官方给出的回答。
词是最小的能够独立活动的有意义的语言成分。
汉语是以字为基本的书写单位,词语之间没有明显的区分标记。
正确的分词是中文信息处理的基础与关键。
对于中文而言,词是承载语义的最小单元,由词构成语句,又由语句构成篇章。但是,中文文本是由连续的字序列构成,词与词之间是没有天然的分隔符。在自然语言处理领域,国外已经做出了很多卓有成效的研究,但是那些研究大多基于英文(存在天然的分隔符),也就是说是以正确切分出单词为前提的。于是,NLP对于中文而言要想取得较好的科研成果,就需要准确识别词与词之间的边界,也就是分词。接下来我们就以搜索为例,具体的阐述一下分词的重要性与必要性。大家都知道,目前的搜素引擎是基于一种叫做倒排索引的结构,以什么作为索引的key值,直接影响到整个搜索引擎的准确度、召回率以及性能。
1、如果不使用中文分词,可以采用单个汉字索引方式。例如,"网易",会先索引"网"字,再索引"易"字。搜索过程中,也是先寻找"网"字关联的所有文档,再寻找"易"字关联的所有文档,最后对所有被检索出的文档做"与"运算,同时"网","易"位置连续的文档才算符合要求。这种方式存在一个非常挑战性的问题,常用汉字总共3000左右,每次查询过程中进行“与”操作的计算量会相当大。对于大数据量的搜索引擎来讲,每天面临亿万级别的查询,这样的索引结构无疑是灾难性的。
2、为了优化上面提到的速度问题,还有另外一种索引结构也是可以避开中文分词的,那就是n元组合索引方式。用2元索引来说,"中国人",会先索引"中国",再索引"国人"。在搜索过程中,也是对"中国"和"国人"检索出的文章进行"与"操作。这样的搜索过程会大大减少在搜索过程中的计算量,但是仍会面临另外一个问题:准确度。有很多这样的例子,搜"北大"会检索出"东北大学",搜"的士"会出现"不想当将军的士兵不是好士兵"。对于大数据量的搜索引擎系统来说,这样的用户体验是极差的。 这个时候,就体现到分词的重要性了,我们往往使用有意义的词来进行代替以上两种方法来建立索引。
中文分词面临的挑战
在知道分词的重要性之后,那么我们会面临一个新的问题,如何才能把一个字序列准确的切分成词序列,就像下面的例子会有不止一种的切分方式。
原串:结婚的和尚未结婚的
切分一:结婚/的/和尚/未/结婚/的
切分二:结婚/的/和/尚未/结婚/的
还有更极端的例子,"中外科学名著"中,"中外"、"外科"、"科学"、"学名"、"名著"都是合理的词语。类似的例子数不胜数,"提高产品质量","鞭炮声响彻夜空"。在中文分词的世界里,最主要的挑战有两个:歧义词识别,未登录词识别。
歧义词
上文提到的歧义词例子,有学者试图通过逆向匹配来解决。但是,碰到这句"结合成分子"时,采用逆向匹配,则会分成"结合/成分/子时"。一般当一个字可以同时作为两个词的组成部分,当这两个词按序同时出现时,就可能会出现歧义现象。目前的歧义一般分为三种:交叉歧义,组合歧义,真歧义。 交叉歧义(字符串AJB,AJ和JB都是一个汉语词汇,会存在多种切分交叉在一起):"你说的确实在理","的确"和"确实"就是交叉型歧义片段。 组合歧义(字符串AB是一个词汇,A和B同时也是词汇,会存在不同语义下切分不同):"这个人手上有颗痣","目前人手紧缺"。前者是"人"/"手"两个实体词,后者是"人手"一个实体词。 真歧义(怎么切分都合理):"乒乓球拍卖完了",切分为以下两种情况都是合理的,"乒乓球拍/卖/完了","乒乓球/拍卖/完了"。
未登录词
所谓的未登录词是指在分词词典中没有收录,并且确实是大家公认的词语的那些词语,一般又叫做新词。最典型的未登录词就是人名词,"李胜利喜欢唱歌"中"李胜利"是个人名词,如果把"李胜利"这个基本词条收录到字典中去是能解决这个问题。但是,每时每刻都有新增的姓名,完整收录全部人名本身就是一个不现实的工程。除了人名词之外,还有机构名、地名等未登录词。在当下的互联网时代,人们还会不断的创造出一些新词出来,比如:"神马"、"不明觉厉"等。 新词是中文分词算法在召回层面上最主要的难题,也是评价一个分词系统好坏的重要标志。如果一个新词无法被分词系统识别,会导致很多噪音数据被召回,进而会影响后面的句法分析和语义分析等相关处理。黄昌宁等在中文信息学报上的《中文分词十年回顾》一文指出:新词带来的分词问题是歧义的10倍~20倍,所以说新词发现是分词面临的最大挑战。
中文分词方法
从上世纪80年代开始对中文自动分词进行研究,在过去的近40年中,中文分词的发展过程基本上可分为以下三个阶段,如下图所示:
机械分词法
中文自动分词第一阶段,从80年代到90年代中,以基于词典和人工规则的方法为主,典型的方法有:正向最大匹配,逆向最大匹配,最少词切分法,双向匹配法。以正向最大匹配为例,其分词策略为:从左到右尽量匹配词典中的最长词,假设词典中有{杭州,杭州研究院,网易,研究院},则句子"网易杭州研究院"的切分结果为"网易/杭州研究院"。 这种基于规则的机械匹配法缺乏歧义切分处理,上面提到的几种切分方法是从不同的角度来处理歧义问题,但是任何一种方法只能解决有限类别的歧义问题。随着词典的增大,词与词之间的交叉会变得更加严重,歧义带来的负面影响会更加严重。同时,基于规则的切分方法对于新词的切分是完全无能为力的。
基于频度统计的分词法
中文自动分词第二阶段,从90年代中到03年,分词算法开始引入基于语料库的统计学习方法,最典型的方法就是基于词典全切分加上最大概率路径。首先,介绍一下全切分方法,它是基于词的频度统计的分词方法的基础。全切分顾名思义就是获取原字序列的所有可能成词的切分结果,这样就不会遗漏可能正确的切分方式。将全切分的结构构件一个有向无环图,比如"杭州亚运会"的全切分有向无环图如下所示。
构成有向无环图之后,在此图中找到一条概率最大的路径,即寻找下面概率公式的最大值:
其中,w值是指用全切分方法切分出来的词语。 基于全切分最大概率路径的切分算法也是需要依赖词典,全切分在实际使用过程,一般会通过词典将所有成词的切分方式找出来构成有向无环图。第一阶段的中文分词相比,它也是无法完成识别新词,但是歧义词识别的问题基本被解决。在实际使用的工业分词系统中,词典中的词一般会带有词频属性。同时,还会有一份词与词之间的跳转频率表,最大概率的计算往往是基于词频和词之间的跳转频率进行的。
字标注统计学习法
从03年至今,中文分词由基于词的方法开始向基于字的方法转变。当前的方法都是首先根据语料训练分词模型,然后对每一个字进行标注,最后根据标注结果来进行分词。其实就是根据语料训练分类模型,对每一个字进行类别标注,最后根据类别进行分词。最典型的方法就是HMM和CRF,其中,CRF比HMM有更弱的上下文无关性假设,当然效果要好一些。 以CRF为例,它把分词看作是对一个字序列进行标注的过程,一般会标记为4种状态:词首(B)、词中(M)、词尾(E)、单独成词(S)。例如,对于一个输入序列"我来到网易杭州研究院"会标记为"我/S 来/B 到/E 网/B 易/E 杭/B 州/E 研/B 究/M 院/E",根据标注结果就得到最终的分词结果。CRF模型的最优函数形式如下所示:
其中,Z是归一化函数,f是特征函数,前面是特征对应的权重。 CRF分词的过程就是找到一个标注序列使得其最优函数达到最大值。由于CRF模型不是基于词典的,可以有效的识别新词。同时,其分词的准确率也已经达到工业界使用的要求。但是,CRF分词的效率和一致性会存在一定问题。一致性问题是指同一个待切分片段会随着上下文的不同可能做成完全不同的切分结果,所以在搜索业务中在召回层面使用是不合适的。当前CRF的主流用法是在线进行人名识别和歧义片段解析,并使用词典来保持分词结果的一致性,以及离线识别新词补充至词典。
分词在考拉海淘中的应用
目前考拉海淘使用的分词是基于ansj开源分词进行二次开发的版本,目的是优化ansj原有的分词策略以及增加适合电商的策略。
召回问题
通过日志以及用户反馈,我们发现对于同一商品往往存在不同表述,这可能会导致某种描述无法召回结果。例如,对于商品"扫地机器人"来说,有人会用"扫地机器"这样的query去查询,也有人会用"扫地机"去查询。但是按照最大概率路径分词策略,会把商品切分成"扫地"和"机器人"来进行建立索引。为了保证召回的准确性,底层NDIR是采用全匹配的方式来进行召回,也就是query中的所有词都必须出现在同一个文档中。对于上面的两种query,分词结果分别是"扫地/机器","扫地/机",自然就无法召回用户所希望的商品。 我们采用多路径切分的方式,来保证所有在词典的词语都出现在路径中,同时,对所有的路径进行索引建立。我们会把"扫地机器人"切分成"扫地/机器人"、"扫地/机器/人"、"扫地机/器/人"三条路径,这样就解决了无法召回的问题。
词性问题
当用户输入的query比较详细时,可能考拉并没有此款商品,却有同品牌或者其他相似的商品,这个时候就需要用到关键词提取。例如,query为"耐克黑色球鞋詹姆斯同款"时,因为无货而无法召回商品,当我们提取关键词"耐克黑色篮球鞋"时可能会召回商品,当然这个关键词提取的粒度是需要控制的。在ansj原有词典的基础上,我们补充了电商品牌词典和电商类词典,分词过程中会给出相应的标记为"耐克/brand 黑色/adj 球鞋/ecom 詹姆斯/nrf 同款/nz",根据词性是可以进行关键词初步识别的。
分词粒度问题
当词典较大时,会面临一个新的问题,那就是分词的粒度问题。对于query为"耐克鞋"来说,词典中是包含这个实体词的,分词的切分结果就是"耐克鞋"。但是,考拉用来建索引的商品描述中,这三个字是没有连续出现的,自然就没有"耐克鞋"对应的文档,这个时候就无法召回结果。那么,这时候你会说那就使用最小粒度的分词就解决这个问题了。比如,某一款商品可能有"参数表"这三个字,如果有最小粒度的分词策略,分词的结果为"参数/表"。很不幸,当query为"表"时,你会发现会召回莫名其妙的结果。目前,是使用词频表来进行粒度控制,基本可以解决绝大多数问题。
新词问题
分词器的词表一般是由基础词汇和各领域常用词汇来组成,可以应用于大多数基本的分词场景。当分词器专门应用于某个领域时,一份领域相关的词典是必不可少的。例如,有很多出问题的case是由于无法识别这个词造成的,像"马油"、"肌研"、"极润"这样的词,只能切分成单字,随之而来的就是一些不相关的商品被召回。目前的解决方案是从相关网站获取了一批电商词语当做基础电商词语,尽量减少词语的无法识别率。但是这种解决方案是不满足可持续发展战略的,只能用于分词的初级阶段。
未来的工作方向
根据考拉海淘搜索的现状,接下来会针对解决关键词提取/新词发现以及实体识别所带来的问题。打算开发一套term weight的关键词识别系统,利用词法依存关系以及词性等知识给切分后每一个词语进行一个打分,其应用场景会非常广泛。另外一个方向是解决新词发现所涉及的问题,会根据用户日志以及新商品的信息,利用词频统计以及CRF序列标注等方案来定期离线自动化补充新词。 相信我们的分词会越来越准确,我们的搜索也会越来越完善!
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 nkv客户端性能调优