浅谈中文分词

HMM_and_CRF

NLP(Natural language processing)自然语言处理一直都是比较热门的领域,现在不管是搜索,推荐神马的基本都需要和nlp打交道,而中文的nlp处理的第一步就是分词了,所以中文分词一直扮演者举足轻重的角色。当然了,分词的算法也是层出不穷,从最初的字典匹配到后来的统计模型,从HMM到CRF,分词精度都在不断提高,下面我就简单介绍下基本的分词算法。

字典匹配

最简单的分词就是基于字典匹配,一个句子“浅谈中文分词”,如果字典中我有这三个词“浅谈”“中文”“分词”那么我自然就可以把句子进行分词了。基于字典匹配随之而来的问题就是有多个匹配的情况,比如有“北京”“北京大学”两个词,这时来了个句子“北京大学在哪里”,应该用“北京”去匹配还是用“北京大学”去匹配,于是人们提出了很多启发式的匹配方案,比如最经典的最大匹配,就是尽可能的匹配最长的词,还有类似分词后分出的词的个数尽量少等启发规则,于是有了mmseg算法,提出了一些比较好的启发规则,而且实际应用时效果也很不错,所以应用很广泛,具体细节大家自行搜索,这里不在赘述。

统计模型

很快基于字典的分词还是会暴露出很多的问题,最主要的问题就是歧义的问题,比如“武汉市长江大桥”,不同的分词可能会变成“武汉/市长/江大桥”和“武汉市/长江/大桥”,显然字典匹配是不能解决这样的歧义问题的,于是有了统计的分词算法。在我的这篇文章里介绍的就是一元模型的分词算法,对于一个句子序列\(a_1a_2a_3...a_n\)变成最后的词序列\(A_1A_2A_3...A_m\),一元模型是希望

\(argmax\Pi_{i=1}^{m}{P(A_i)}\)

同样的n元模型即是

\(argmax\Pi{P(A_i|A_{i-1},A_{i-2}...,A_{i-n+1})}\)

我的这篇文章是一元模型的求法,于是统计模型的诞生有些的解决了分词问题中的歧义问题。

隐马尔可夫模型HMM(Hidden Markov Model)

前面的n元模型能够解决歧义的问题,但是,却不能很好解决未登录词的问题,所谓未登录词,是指没有见过的词,或者说没有在我们字典中的词于是后来人们提出了基于字标注的分词,比如这样一句话“我喜欢天安门”就可以变成这样的标注“我s喜b欢e天b安m门e”通过s(single)b(begin)m(middle)e(end)这样的标注把分词问题转变为标注问题,当第一次提出字标注算法时,在分词大会上也是取得了惊人的准确率。

HMM隐藏马尔可夫链模型就是这样一个字标注的分词算法,假设原来的句子序列是\(a_1a_2a_3...a_n\),标注序列是\(c_1c_2...c_n\),那么HMM是要求这样的式子

\(argmax\Pi{P(c_i|c_{i-1})*P(a_i|c_i)}\)

在我的SnowNLP这个项目里有去实现HMM的分词。

最大熵模型ME(Maximum Entropy)

我的这篇文章介绍了信息熵的概念,信息熵越大不确定性也就越大,信息熵最大时表示各种概率的均等分布,也就是个不偏不倚的猜测,最大熵模型一般就是在已知条件下,来求是的熵最大的情况,最大熵模型我们一般会有feature函数,给定的条件就是样本期望等于模型期望,即

\(\overline{p}(f)=\Sigma{\overline{p}(a_i,c_i)*f(a_i,c_i)}=p(f)=\Sigma{p(c_i|a_i)*\overline{p}(a_i)*f(a_i,c_i)}\)

在已知条件下就是求熵最大的情况

\(argmaxH(c_i|a_i)\)

H就是信息熵的函数,于是这样我们就求出了\(P(c_i|a_i)\),就知道了每个字a的标注c了,最大熵模型的一个好处是我们可以引入各种各样的feature,而不仅仅是从字出现的频率去分词,比如我们可以加入domain knowledge,可以加入已知的字典信息等。

最大熵马尔可夫模型MEMM(Maximum-entropy Markov model)

最大熵模型的一个问题就是把每个字的标注问题分裂来看了,于是就有聪明人把马尔可夫链和最大熵结合,搞出了最大熵马尔可夫模型,这样不仅可以利用最大熵的各种feature的特性,而且加入了序列化的信息,使得能够从整个序列最大化的角度来处理,而不是单独的处理每个字,于是MEMM是求这样的形式

\(argmax\Pi{P(c_i|c_{i-1},a_i)}\)

条件随机场CRF(Conditional Random Field)

MEMM的不足之处就是马尔可夫链的不足之处,马尔可夫链的假设是每个状态只与他前面的状态有关,这样的假设显然是有偏差的,所以就有了CRF模型,使得每个状态不止与他前面的状态有关,还与他后面的状态有关,从最开始的图片也能看出,HMM是基于贝叶斯网络的有向图,而CRF是无向图。

\(P(Y_v|Y_w,w \neq v)=P(Y_v,Y_w,w \sim v)\) where w~v means that w and v are neighbors in G.

上式是条件随机场的定义,一个图被称为条件随机场,是说图中的结点只和他相邻的结点有关。最后由于不是贝叶斯网络的有向图,所以CRF利用团的概念来求,最后公式如下

\(P(y|x,\lambda)=\frac{1}{Z(x)}*exp(\Sigma{\lambda_j*F_j(y,x)})\)

因为条件随机场既可以像最大熵模型那样加各种feature,又没有马尔可夫链那样的偏执假设, 所以近年来CRF已知是被公认的最好的分词算法StanfordNLP里就有良好的中文分词的CRF实现,在他们的这篇论文提到,他们把字典作为feature加入到CRF中,可以很好的提高分词的performance。

最近看到这篇论文,已经有人用deep learning的方法来尝试解决分词的算法,也取得了不错的效果。

总之现在的中文分词技术相对来说还是比较成熟了,所以如果没有必要用这些开源的分词实现已经足够了,不过鉴于学习的目的,自己去实现一个分词算法还是很有趣的。

您可能喜欢:
我猜您可能还喜欢:
, ,

《浅谈中文分词》有 32 条评论

  1. NLP么,成功学的祖师吧。。。貌似说语言能改变人的习惯

  2. 分词的算法有很多种。但是我没接触过。

  3. 陶磊 | #3

    您好,看了您的项目snownlp,发现一个小问题:
    s = SnowNLP(u'陶磊')
    s.pinyin后'磊'返回的时unicode编码的字符串而不是拼音

  4. jason.ke | #5

    请问这个网站是用drupal的什么模版做的

  5. 楼主请教一个问题:SnowNLP中训练集合是否可以使用数据库去存储呢?如果使用数据库去存储,是不是会提高读写效率。我测试你的库的时候,总感觉有点慢

  6. 偶然经过贵站,盼望回访,xrpmoon

  7. abyssalfish | #9

    厉害,膜拜一下

  8. 静静地看着你在刷100offer的票~~

  9. 看了您的博文总结的非常好,您的博客非常不错。我也推荐一个程序员必备的搜索博客问答的网站 http://www.itdaan.com

  10. 南风 | #13

    博主,最近对NLP感兴趣,搜到你的大作,你的snowNLP也试用了,确实很不错。有个小问题想请教你,你seg 目录下来的data.txt是分词用的词典, 这个词典我是可以自己手工修改的,或者有什么更好的办法能针对特定的类别的文本进行训练?具体如何做能简单指点下么?
    谢谢

  11. 薇酱 | #15

    我竟然看到了原作者,最近正在学习snownlp,原来data.txt还是要先自己标注下啊。看起来非常好用,感谢~

Trackbacks/Pingbacks:

  1. lock free的理解 - IT牛人博客聚合
  2. 细说中文分词 - TALK IS CHEAP

发表评论