一周乱谈 - 中文分词
中文分词
NLP(Natural language processing)自然语言处理一直都是比较热门的领域,搜索和推荐基本都需要和nlp打交道,而中文nlp处理的第一步就是分词了,所以中文分词一直扮演者举足轻重的角色。当然了,分词的算法也是层出不穷,从最初的字典匹配到后来的统计模型,从HMM到CRF,分词精度在不断提高,下面简单介绍下基本的分词算法。
字典匹配
最简单的分词就是基于字典匹配,一个句子“乱谈中文分词”,如果字典中我有这三个词“乱谈”“中文”“分词”那么我自然就可以把句子进行分词了。基于字典匹配随之而来的问题就是有多个匹配的情况,比如有“北京”“北京大学”两个词,这时来了个句子“北京大学在哪里”,应该用“北京”去匹配还是用“北京大学”去匹配,于是人们提出了很多启发式的匹配方案,比如最经典的最大匹配,就是尽可能的匹配最长的词,还有类似分词后分出的词的个数尽量少等启发规则,于是有了mmseg算法,提出了一些比较好的启发规则,而且实际应用时效果也很不错,所以应用很广泛,具体细节大家自行搜索,这里不在赘述。
统计模型
很快基于字典的分词还是会暴露出很多的问题,最主要的问题就是歧义的问题,比如“武汉市长江大桥”,不同的分词可能会变成“武汉/市长/江大桥”和“武汉市/长江/大桥”,显然字典匹配是不能解决这样的歧义问题的,于是有了统计的分词算法。在我的这篇文章里介绍的就是一元模型的分词算法,对于一个句子序列a1a2a3...an变成最后的词序列A1A2A3...Am,一元模型是希望
argmaxΠmi=1P(Ai)
同样的n元模型即是
argmaxΠP(Ai|Ai−1,Ai−2...,Ai−n+1)
我的这篇文章是一元模型的求法,于是统计模型的诞生有些的解决了分词问题中的歧义问题。
隐马尔可夫模型HMM(Hidden Markov Model)
前面的n元模型能够解决歧义的问题,但是,却不能很好解决未登录词的问题,所谓未登录词,是指没有见过的词,或者说没有在我们字典中的词于是后来人们提出了基于字标注的分词,比如这样一句话“我喜欢天安门”就可以变成这样的标注“我s喜b欢e天b安m门e”通过s(single)b(begin)m(middle)e(end)这样的标注把分词问题转变为标注问题,当第一次提出字标注算法时,在分词大会上也是取得了惊人的准确率。
HMM隐藏马尔可夫链模型就是这样一个字标注的分词算法,假设原来的句子序列是a1a2a3...an,标注序列是c1c2...cn,那么HMM是要求这样的式子
argmaxΠP(ci|ci−1)∗P(ai|ci)
在我的SnowNLP这个项目里有去实现HMM的分词。
最大熵模型ME(Maximum Entropy)
我的这篇文章介绍了信息熵的概念,信息熵越大不确定性也就越大,信息熵最大时表示各种概率的均等分布,也就是个不偏不倚的猜测,最大熵模型一般就是在已知条件下,来求是的熵最大的情况,最大熵模型我们一般会有feature函数,给定的条件就是样本期望等于模型期望,即
p−(f)=Σp−(ai,ci)∗f(ai,ci)=p(f)=Σp(ci|ai)∗p−(ai)∗f(ai,ci)
在已知条件下就是求熵最大的情况
argmaxH(ci|ai)
H就是信息熵的函数,于是这样我们就求出了P(ci|ai),就知道了每个字a的标注c了,最大熵模型的一个好处是我们可以引入各种各样的feature,而不仅仅是从字出现的频率去分词,比如我们可以加入domain knowledge,可以加入已知的字典信息等。
最大熵马尔可夫模型MEMM(Maximum-entropy Markov model)
最大熵模型的一个问题就是把每个字的标注问题分裂来看了,于是就有聪明人把马尔可夫链和最大熵结合,搞出了最大熵马尔可夫模型,这样不仅可以利用最大熵的各种feature的特性,而且加入了序列化的信息,使得能够从整个序列最大化的角度来处理,而不是单独的处理每个字,于是MEMM是求这样的形式
argmaxΠP(ci|ci−1,ai)
条件随机场CRF(Conditional Random Field)
MEMM的不足之处就是马尔可夫链的不足之处,马尔可夫链的假设是每个状态只与他前面的状态有关,这样的假设显然是有偏差的,所以就有了CRF模型,使得每个状态不止与他前面的状态有关,还与他后面的状态有关,从最开始的图片也能看出,HMM是基于贝叶斯网络的有向图,而CRF是无向图。
P(Yv∣∣Yw,w≠v)=P(Yv,Yw,w∼v) where w~v means that w and v are neighbors in G.
上式是条件随机场的定义,一个图被称为条件随机场,是说图中的结点只和他相邻的结点有关。最后由于不是贝叶斯网络的有向图,所以CRF利用团的概念来求,最后公式如下
P(y|x,λ)=1Z(x)∗exp(Σλj∗Fj(y,x))
因为条件随机场既可以像最大熵模型那样加各种feature,又没有马尔可夫链那样的偏执假设, 所以近年来CRF已知是被公认的最好的分词算法StanfordNLP里就有良好的中文分词的CRF实现,在他们的这篇论文提到,他们把字典作为feature加入到CRF中,可以很好的提高分词的performance。
最近看到这篇论文,已经有人用deep learning的方法来尝试解决分词的算法,也取得了不错的效果。
总之现在的中文分词技术相对来说还是比较成熟了,所以如果没有必要用这些开源的分词实现已经足够了,不过鉴于学习的目的,自己去实现一个分词算法还是很有趣的。