2010年快到了,在最近这段时间里,我是时候维护下自己的博客了,大量资料堆砌着没有整理,有中文分词的、句法分析的、语义网的、本体的,大量的资料心得如果不固化在文字中,那么也会随着2009年的逝去而遗忘。废话不多说了,一点点开始总结吧。
中文分词,在80年代末、90年代初,我国学者就已经开始研究了,那时候的机器内存很小,基本停留在查基础词典然后匹配阶段,有向后最大匹配,向前最大匹配,双向扫描匹配,启发式匹配等等,这些都被后人称为机械式分词。就效率而言,已经非常高了,不亚于现在的中文分词,但是无法排除歧义,无法识别未登陆词。90年代末,兴起了统计学分词与语义分词2个学派,统计学分词现在已经非常成熟,成为主流;而语义分词因为其现实技术不到位,还在一步一步地往上爬,但是语义分词最终肯定会成为主流,至少和统计学分词平起平坐,这乃我的一家之言,呵呵。
我这里主要围绕统计学分词展开讨论与总结。(后面的术语可能会说错,但这里我打算深究所有的细节,毕竟只是总结思路)
首先我们从词库聊起,词库分为基础词库和训练词库
基础词库,存放大量的日常词语,在内存中,一般都是以词语的第一个词作为索引存放,比如:电灯、电脑、电视机这些以电开头的词存一块。这里有2个流派,一是以GBK编码存放,另一个是以UNICODE编码存放;前者紧凑,兼容性差;后者稀疏,但兼容性好。根据不同的业务,可以采用不同的编码。
这样的储存方式,好比将词库比作了HashMap,词语的第一个汉字就是hashcode,一次匹配到这个词所在的区块,然后可以根据2分查找来找出这个词是否存在。
训练词库里面存放N-gram模型,这个模型基于这样一种假设:文章中的一个词,必定与上文有关,或者下文有关。举个例子:
我今天非常愤怒。
如果是1阶N-gram模型,训练词库中就存放:
我|今天
今天|非常
非常|愤怒
愤怒|。
如果是2阶N-gram模型,训练词库中就存放:
我|今天|非常
今天|非常|愤怒
非常|愤怒|。
愤怒|。
有朋友问,你这不都分好词了吗?是的,但是这个是语料库中的内容。语料库就是人工分好词的训练样本,是人们手工一个一个去分词所得到的海量文章集,以这个语料库作为输入,输出N-gram模型的词库。
不仅要生成这样的模型,还需要去训练词库中每个结果的出现次数,便于日后根据这个统计值来计算分词。我们可以看到,N越大,词库记录的信息就越是丰富,将设常用汉字3000个,如果以1阶N-gram模型统计,那么需要9,000,000结果集,如果2阶就不得了了。因此,N虽然越大越好,但是随着而来的就是数据稀疏问题。
谈到数据稀疏问题,就要谈到平滑处理了。我们看下面一句话:
李宇春天后地位。
计算机看到这句话保管郁闷死,这里有2种分词方案:
李宇|春天|后|地位|。
李宇春|天后|地位|。
如果按照语义分词法,担保第一句就是一个病句,写个常用的句法分析就搞定,这个方法我觉得是最贴近人们的思维方式的,然而这个方法并不成熟,里面涉及很多问题到现在都是一个未知数,原因就在于自然语言的表达方式太过于丰富。这里不扯远了,我们聊聊统计学怎么来搞:
说穿了,很简单,就比谁的概率大,P(李宇/春天/后/地位/。) 和 P(李宇春/天后/地位/。)这2个概念谁大,计算机就按谁的切。这其实就是类似于人类的语感,熟读唐诗三百首,不会作诗也会吟。那么如何计算呢?
我们按照1阶N-gram来算:
P(李宇/春天/后/地位/。) = P(李宇/春天)* P(春天/后)* P(后/地位)* P(地位/。)
P(李宇春/天后/地位/。) = P(李宇春/天后)* P(天后/地位)* P(地位/。)
P(李宇春/天后)怎么算呢?P(李宇春/天后) = (李宇春/天后)出现的次数除以总样本的次数。这就是所谓的最大似然估计。
好了,回归到我们刚才说的平滑处理吧,通过刚才中间的讲述,聪明的读者一定会想到,如果(李宇春/天后)这样的组合在语料库中一次都没有出现,那么它的次数就为0!那岂不是它的概率也为0了吗?不错,不仅这个可能为0,大量现实中拿进去分词的句子中词的组合,都有可能为0,这就是所谓的数据稀疏问题,1阶已经如此了,更何况2阶呢?
接下来就是如何处理这样的稀疏问题了,因为我们知道(李宇春/天后) 这样的组合虽然在语料库中没有出现,但它在现实中肯定是存在的,既然存在就一定有概率,那么既然似然估计无能为力,我们只好手工去估计了,最简单的办法就是直接将所有为0的情况,都附一个概率,比如0.00001之类的,这个就会出现过大估计和过小估计。不过不管如何,总算是平滑处理了。
另一种较为流行的平滑处理,叫插入平滑处理。
P(李宇春/天后) = 0.7*P(李宇春/天后)* + 0.3*P(李宇春)
具体为什么,大家自己看吧。
就我刚才所讲的这些,配合一个良好的语料库和比较全面的基础词库,就已经可以分词了,还能排除歧义,准确率可以接近100%(不是我说的,呵呵)
接下来的任务就是未登陆词识别了,在日常我们处理的句子中,总有阿猫阿狗的人名一大堆,还有一些什么什么团、什么什么公司的,这些总不至于全部存入词库吧?因此,就需要未登陆词的识别。这项工作涉及到基于角色的隐马模型。所包含的原理算是2000年后,我国学者的重大突破。张华平等人为此做了很大的贡献。可惜,这些人啊,喜欢把理论知识用理论术语表达,论文、代码基本天书吧,关于这块日后撰文写清楚与大家分享。
平安夜快乐~
自然语言处理 N-gram, 中文分词, 统计学, 综述, 隐马模型