一周乱谈(第八周) - 中文分词

中文分词

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的方法来尝试解决分词的算法,也取得了不错的效果。

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

时间: 2024-11-10 07:47:37

一周乱谈(第八周) - 中文分词的相关文章

周总结(第八周)

行李收费计算表

每周进度条(第八周)

第八周进度条   第八周 所花时间 10 代码量(行)  1000 博客量(篇)  1 学到的知识 进一步完善二柱子的网页版 对HTML语言+JavaBean的掌握稍加熟练

中文分词

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

软件工程_东师站_第八周作业

一.PSP Date Type Job Start Interrupt(min) End Total(min) 20160417 助教 黄金点 20:00 5 21:00 55 20160418 助教 黄金点 19:00 12 21:00 108 20160419 助教 黄金点 18:45 100 23:00 155 20160420 助教 团队作业 10:00 35 11:20 45 20160425 结对编程 四则运算 19:00 5 19:30 25 ? 二.进度条 ? 代码行数 博客字数

《Linux内核设计与实现》第八周学习总结——第四章 进程调度

<Linux内核设计与实现>第八周学习总结——第四章 进程调度 第4章 进程调度35 调度程序负责决定将哪个进程投入运行,何时运行以及运行多长时间,进程调度程序可看做在可运行态进程之间分配有限的处理器时间资源的内核子系统.只有通过调度程序的合理调度,系统资源才能最大限度地发挥作用,多进程才会有并发行的效果. 调度程序没有太复杂的原理,最大限度地利用处理器时间的原则是只要有可以执行的进程,那么就总会有进程正在执行,但是只要系统中可运行的进程的数目比处理器的个数多,就注定某一给定时刻会有一些进程不

## 20155336 2016-2017-2《JAVA程序设计》第八周学习总结

20155336 2016-2017-2<JAVA程序设计>第八周学习总结 教材学习内容总结 第14章 NIO与NIO2 NIO简介 NIO使用频道来衔接数据结点,在处理数据时,NIO可以让你设定缓冲区容量,在缓冲区中对感兴趣的数据区块进行标记,像是标记读取位 置.数据有效位置,对于这些区块标记,提供了Clear().rewind().flip().compact()等高级操作. NIO2简介 NIO2文件系统API提供一组标准接口与类,应用程序开发者只要基于这些标准接口与类进行文件系统操作,

20172323 2018-2019-1 《程序设计与数据结构》第八周学习总结

20172323 2018-2019-1 <程序设计与数据结构>第八周学习总结 教材学习内容总结 本周学习了第12章优先队列与堆 12.1 堆 堆是具有两个附加属性的一棵二叉树,它是一棵完全树,对于每一结点,它小于或等于其左孩子和右孩子,这样定义下的堆是最小堆,如果对于每一结点,它大于或等于其左孩子和右孩子,那么它就是最大堆. 最小堆将其最小元素存储在该二叉树的根处,且其根的两个孩子同样也是最小堆. 操作 说明 addElement 将给定元素添加到该堆中 removeMin 删除堆的最小元素

20135302魏静静——linux课程第八周实验及总结

linux课程第八周实验及总结 实验及学习总结 1. 进程切换在内核中的实现 linux中进程切换是很常见的一个操作,而这个操作是在内核中实现的. 实现的时机有以下三个时机: 中断处理过程(包括时钟中断.I/O中断.系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule(): 内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度: 用户

第八周学习进度

本周学习进度   第八周   所花时间(包括上课时间)    10小时      代码量(行)   800       博客量   10       了解到的知识点 了解到了用户的场景分析,以及用户界面设计的作用