目录

  • 概述
  • 从序列到图
  • Unigram 模型
  • Bigram 模型
  • 实现

概述

分词是NLP任务Pipeline中的重要步骤,一般来说都需要将句子切分成词之后,才能进一步把词进行向量化,最终输出各种各样的数学模型中,从而完成特定的NLP任务。中文不同于英文句子那样天然会用空格分割单词,所以中文句子切成独立的词相对困难,并且中文句子的词是上下文相关的,不同的分词方式会导致同一个句子出现不同含义。例如: 研究所取得的成就,这个句子切分成研究/所/取得/的/成就研究所/取得/的/成就含义是不一样的,在描述取得成就这件事上,前者主语是研究,而后者主语是研究所。至于哪种切分方式是正确的,则完全取决于上下文,在某个上下文中,如果大概率谈论的是研究所而非研究,那么我们则倾向于将句子切分成研究所/取得/的/成就。从这个角度来看,分词其实就是:将句子按照最合理(概率最大)的方式进行分词。

从序列到图

假设我们已经拥有一个足够大的词典DDD,和待切分的句子t\bm tt,从上文的叙述来看,分词的目的是将句子的字序列t=(t1t2t3...tn)\bm t=(t_1t_2t_3...t_n)t=(t1​t2​t3​...tn​)切分成词序列s=(w1w2w3...wj∣wj∈D)\bm s=(w_1w_2w_3...w_j|w_j \in D)s=(w1​w2​w3​...wj​∣wj​∈D),并且使得概率p(s)p(\bm s)p(s)最大。于是我们的算法的步骤无外乎三步:

  1. 找到一个切分序列si\bm s_isi​
  2. 计算该切分序列的概率p(si)p(\bm s_i)p(si​)
  3. 选择概率最高的切分序列作为切分结果

我们且不去想如何计算一个切分序列的概率p(si)p(\bm s_i)p(si​),现在先将注意力集中在如何寻找一个切分序列si\bm s_isi​上。我们当然可以穷举所有的切分序列,并且通过查询词典验证切分序列的合法性,然后过滤出来合法的切分序列,但这未免也太过低效了。寻找切分序列的问题可以转化成一个图问题来高效解决,这样通过图取表示切分序列的算法称之为N-最短路径法。具体的做法是:

  1. 对于字序列t=(t1t2t3...tn)\bm t=(t_1t_2t_3...t_n)t=(t1​t2​t3​...tn​),在序列首尾增加两个特殊字:<s>和<\s>分别表示开始和结束,形成新的字序列t=(t0t1t2...tm)\bm t=(t_0t_1t_2...t_m)t=(t0​t1​t2​...tm​)
  2. 对于字序列t=(t0t2t3...tm)\bm t=(t_0t_2t_3...t_m)t=(t0​t2​t3​...tm​)中的所有节点, 相邻的节点ti−1t_{i-1}ti−1​与tit_iti​之间建立一个有向边&lt;ti−1,ti&gt;&lt;t_{i-1},t_i&gt;<ti−1​,ti​>
  3. 如果子序列wj=(titi+1ti+2...tj)w_j=(t_{i}t_{i+1}t_{i+2}...t_j)wj​=(ti​ti+1​ti+2​...tj​)是词典DDD中的一个词,则生成节点twt_wtw​且建立有向边&lt;ti−1,tw&gt;&lt;t_{i-1}, t_w&gt;<ti−1​,tw​>和&lt;tw,tj+1&gt;&lt;t_w, t_{j+1}&gt;<tw​,tj+1​>

经过上述步骤的处理,我们就可以得到一个DAG(无环有向图),遍历这个DAG我们就可以得到所有切分序列。以上文研究所取得的成就为例,经过处理可以得到DAG如图:

< s>
<\s>
研究
研究所
取得
成就

Unigram 模型

好了,现在我们知道如何获取一个切分序列之后,考虑如何计算切分序列的概率p(s)p(\bm s)p(s),最简单的方法,我们假设sss中的每个词都是独立的,这种假设我们称之为一元模型,也就是unigram模型,那么有:
(1)p(s)=∏jp(wj)p(\bm s) = \prod_jp(w_j) \tag{1} p(s)=j∏​p(wj​)(1)
于是我们寻找最大概率的哪个切分序列,则可以转化为求lnp(s)=−∑jlnp(wj)lnp(\bm s)=-\sum_jlnp(w_j)lnp(s)=−∑j​lnp(wj​)最小的切分序列,其中词p(wj)p(w_j)p(wj​)的概率如何得到呢?如果有训练语料的化,可以从训练语料中统计得到,实验时我们可以选用人民日报1998年1月分词语料。但是如果没有训练语料则只能将每个词的概率都设为相等的常数了,因为根据最大熵原则,在没有额外信息的情况下,不乱假设就是最好的假设。

现在回过头来看研究所取得的成就对应的DAG,如果我们把DAG边的权重设置为后继节点词对应的负概率−lnp(wj)-lnp(w_j)−lnp(wj​),并且特别地令结束和起始节点的概率为常数,那么上述求最佳切分序列的N-最短路径法就可以转化称为求DAG最短路径问题了,最短路径可以通过维特比算法快速求解,这样比遍历切分序列再求最大概率值更加高效。

DAG边赋权后得到的新DAG如图:

-lnp(研)
-lnp(究)
-lnp(所)
-ln(取)
-lnp(得)
-lnp(的)
-lnp(成)
-lnp(就)
-lnp(<\s>)
-lnp(研究)
-lnp(所)
-lnp(研究所)
-lnp(取)
-lnp(取得)
-lnp(取得)
-lnp(的)
-lnp(成就)
-lnp(<\s>|成就)
< s>
<\s>
研究
研究所
取得
成就

这样只要我们找到了最短的路径就是概率最大的切分序列,也就是最合理的分词了。

Bigram 模型

现在我们回过头来看unigram模型的假设:句子中的字相互独立。这个假设实际上也就没有考虑字所在的上下文了,因为当一个我们去吃这个序列出现的时候,我们更倾向于猜测下一个字是而不是或者其它,这是因为我们有了句子上下文的知识。而在unigram眼里,这并不影响我们对下一个字的猜测。于是为了利用句子的上下文知识,我们重新将式(1)(1)(1)建模为:
(2)p(s)=p(w1,w2,w3,...,wj)=p(w1)p(w2∣w1)p(w3∣w1,w2)...p(wj∣w1,w2,...,wj−1)p(\bm s) = p(w_1, w_2, w_3, ...,w_j) = p(w_1)p(w_2|w_1)p(w_3|w_1,w_2)...p(w_j|w_1,w_2,...,w_{j-1}) \tag{2} p(s)=p(w1​,w2​,w3​,...,wj​)=p(w1​)p(w2​∣w1​)p(w3​∣w1​,w2​)...p(wj​∣w1​,w2​,...,wj−1​)(2)
当然,式子(2)(2)(2)是十分美好的,因为它可以利用句子的所有上下文来计算切分序列的概率,但这样计算的效率太低了,并且我们直觉上看,一个字与近的字强相关而与距离远的字弱相关,当我们看到我们去吃这个序列而做出了下一个字是的猜测,其实更多是因为去吃,而不是因为我们。于是我们大胆地假设:一个字的出现只与它前nnn个字相关。我们称这样的假设为n阶马尔科夫假设。在分词应用上中我们取一阶马尔科夫假设就表现得足够好了,我们也称这样一阶马尔科夫假设的模型为Bigram模型,相应地式子(2)(2)(2)可以写为:
(3)p(s)=∏jp(wj∣wj−1)p(\bm s) = \prod_j p(w_j|w_{j-1}) \tag{3} p(s)=j∏​p(wj​∣wj−1​)(3)
同样地,式子(3)(3)(3)中的p(wj∣wj−1)p(w_j|w_{j-1})p(wj​∣wj−1​)可以直接从训练语料中统计得到(也可以通过model based的方法得到)。于是我们重新给DAG的边定义权重为−lnp(wj∣wj−1)-lnp(w_j|w_{j-1})−lnp(wj​∣wj−1​)并且特别地令p(wj∣&lt;s&gt;)p(w_j|&lt;s&gt;)p(wj​∣<s>)和p(wj∣&lt;/s&gt;)p(w_j|&lt;/s&gt;)p(wj​∣</s>)为常数,就可以得到Bigram模型下的DAG了,在这个DAG上求最短路径就得到了最优的切分序列。

-lnp(研|< s>)
-lnp(究|研)
-lnp(所|究)
-ln(取|所)
-lnp(得|取)
-lnp(的|得)
-lnp(成|的)
-lnp(就|成)
-lnp(<\s>|就)
-lnp(研究|< s>)
-lnp(所|研究)
-lnp(研究所|< s>)
-lnp(取|研究所)
-lnp(取得|所)
-lnp(取得|研究所)
-lnp(的|取得)
-lnp(成就|的)
-lnp(<\s>)
< s>
<\s>
研究
研究所
取得
成就

实现

在实现上可以设计两个类: BigramLanguaModelDAG,其中类BigramLanguaModel负责从训练语料中统计得到lnp(wj∣wj−1)lnp(w_j|w_{j-1})lnp(wj​∣wj−1​)和词典,而DAG类负责从给定的BigramLanguaModel和待分词的字符串建立对应的有向图,并且求出最短路径。这里有我用C++实现的完整代码。在使用人民日报1998年1月分词语料数据集进行训练之后,得到的模型对研究所取得的成就分词结果为: 研究所/取得/的/成就

最后,请继续期待中文分词的第二弹:《让机器学会断句:基于序列标注的分词算法》

让机器学会断句:基于词典的Bigram分词算法相关推荐

  1. 基于词表的中文分词算法

    基于词表的中文分词算法 正向最大匹配法 对于输入的一段文本从左至右,以贪心的方式切分出当前位置上长度最大的词.正向最大匹配法是基于词典的分词方法,其分词原理是:单词的颗粒度越大,所能表示的含义越确切. ...

  2. NLP-基础任务-中文分词算法(1)-基于词典: 机械分词(词典字符串匹配):前向最大匹配、后向最大匹配、双向最大匹配【OOV:基于现有词典,不能进行新词发现处理】

    分词与NLP关系:分词是中文自然语言处理的基础,没有中文分词,我们对语言很难量化,进而很能运用数学的知识去解决问题.对于拉丁语系是不需要分词的. 拉丁语系与亚系语言区别 拉丁语言系不需要分词,因为他们 ...

  3. 基于字典的中文分词算法RMM

    引言:目前针对中文分词一般有基于字典,基于统计(HMM等),基于规则的分词方法,然而其中基于字典的中文分词是最基础,同时也是最高效的方式,但分词精度取决与字典的规模. 一.基于字典的中文算法简介 1. ...

  4. 基于字典的中文分词算法RMM,MM实现

    引言:目前针对中文分词一般有基于字典,基于统计(HMM等),基于规则的分词方法,然而其中基于字典的中文分词是最基础,同时也是最高效的方式,但分词精度取决与字典的规模. 一.基于字典的中文算法简介 1. ...

  5. NLP-基础任务-中文分词算法(3)-基于字:基于序列标注的分词算法【BiLSTM+CRF】

    CRF:条件随机场,一种机器学习技术.给定一组输入随机变量条件下,另一组输出随机变量的条件概率分布模型. 以一组词性标注为例,给定输入X={我,喜欢,学习},那么输出为Y={名词,动词,名词}的概率应 ...

  6. NLP-基础任务-中文分词算法(2)-基于词典:基于N-gram语言模型的分词算法【基于词典的分词方法】【利用维特比算法求解最优路径】【比机械分词精度高】【OOV:基于现有词典,不能进行新词发现处理】

    例子:"经常有意见分歧" 词典:["经常","有","意见","意","见",& ...

  7. 基于词典规则的中文分词(C语言实现)

    0 引 言 自然语言处理(Natural Language Processing, NLP)是以语言为对象,利用计算机技术来分析.理解和处理自然语言的一门学科,即把计算机作为语言研究的强大工具,在计算 ...

  8. NPL基于词典分词(一)

    前言 自然数据处理里很重要的一环节就是中文分词,它指的是将一段文本拆分为一系列单词的过程,这些单词顺序拼接后等于原文本.而中文分词算法大致分为基于词典规则与基于机器学习这两大派. 什么是词 在基于词典 ...

  9. 基于感知器的中文分词算法

    http://heshenghuan.github.io/2015/12/21/%E5%9F%BA%E4%BA%8E%E6%84%9F%E7%9F%A5%E5%99%A8%E7%9A%84%E4%B8 ...

最新文章

  1. 模型加速--LCNN: Lookup-based Convolutional Neural Network
  2. 前端之JavaScript 补充
  3. Intent对象详解(一)
  4. 金融运营智能化搞不定?百度智能云有妙方
  5. spring中事务控制的一组API
  6. 算法竞赛——快速排序
  7. 【Kafka】Kafka Record for partition topic at offset xx is invalid, cause: Record corrupt
  8. 装饰者模式 php,php装饰者模式简单应用案例分析
  9. QBlog V2.5 源码开放下载(ASP.NET 番外系列之开端)
  10. 入门SVN基础使用教程
  11. 弹性容器中 子元素的flex属性介绍
  12. 国际学术会议-英文演讲稿
  13. 【ps功能精通】3.图层和选取
  14. 无广告的免费视频存储空间并提供视频上传转码的功能,很不错的哦
  15. [TI TDA4 J721E]开发板网络调试功能及开机自动配置网络
  16. terraform 腾讯云_使用Terraform优化云成本的权威指南
  17. html鼠标手状态,css鼠标样式
  18. 在贷款行业中,运营商大数据精准获客,是否真实有效呢
  19. 以上是周末少先队活动照片,涉及到7个小队的同学参与拍照
  20. 探索学习:网红容器引擎Docker

热门文章

  1. 未来在哪里?我是这样看阿里大数据的
  2. 微信小程序:云开发表情包制作源码
  3. AD19滴泪添加与删除
  4. apache ii评分怎么评_APACHEII评分说明
  5. 普通程序员如何转向人工智能方向?
  6. python与分形0017 - 【教程】彩色色阶蛛网
  7. js禁止鼠标滑轮_js 禁止鼠标滑轮滚动的事件
  8. btcTrade_project
  9. 按Enter键调用登录按钮
  10. 微信小程序开发的适合领域