转:http://blog.csdn.net/lanxu_yy/article/details/29918015

为什么需要语言模型?

想象“语音识别”这样的场景,机器通过一定的算法将语音转换为文字,显然这个过程是及其容易出错的。例如,用户发音“Recognize Speech”,机器可能会正确地识别文字为“Recognize speech”,但是也可以不小心错误地识别为“Wrench a nice beach"。简单地从词法上进行分析,我们无法得到正确的识别,但是计算机也不懂语法,那么我们应该如果处理这个问题呢?一个简单易行的方法就是用统计学方法(马尔可夫链)从概率上来判断各个识别的正确可能性。

什么是语言模型?

首先,我们定义一个有限的字典V。V = {the, a, man, telescope ... },通过字典间有限或者无限次笛卡儿积,我们可以得到一个无限的字符串组合S,S可能包含:

1,the

2,a

3,the man

4,the man walks

...

其次,假设我们有一个训练数据集,数据集中包含了许多文章。通过统计数据集中出现的句子、其出现次数c(x)以及数据集句子总数N,我们可以计算出每个句子的出现频率。令x ∈ S,p(x) = c(x)/N表示x的出现频率,显然Σp(x) = 1。

综上所述,我们可以发现几个问题:

1)上述的语言模型只是理论上存在的,当训练数据集无限大的时候,数据集中的频率可以无限接近语法中实际的概率;

2)对于S中的大部分句子,p(x)应当等于0,因此S是一个非常稀疏的数据集,很难存储。

马尔可夫链

既然上面这个简单的语言模型不太完美,我们自然需要寻找其他的方法来获得语言模型,其中一个比较著名的算法就是马尔可夫链。假如考虑一个长度为n的句子可以利用一串随机变量来表示,即x1, x2, ... xn,其中xk ∈ V。那么,我们的目标是求p(X1 = x1, X2 = x2, ..., Xn = xn)。

显然,p(X1 = x1, X2 = x2, ..., Xn = xn) = p(X1 = x1) * p(X2 = x2 | X1 = x1) * p(X3 = x3 | X1 = x1, X2 = x2) * ... * p(Xn = xn | X1 = x1, X2 = x2, ... Xn-1 = xn-1)。当n过大的时候,条件概率的复杂度会大大地增加,是否能够找到一个近似的方法方便求出这些条件概率呢?答案是肯定的,我们需要做一个假设,即每个单词这个随机变量只与前k个随机变量相关。

  • 一阶马尔可夫链
一阶马尔可夫链中我们认为每个单词这个随机变量只与前一个随机变量相关,因此上述表达式可以简化为p(X1 = x1, X2 = x2, ..., Xn = xn) = p(X1 = x1) * p(X2 = x2 | X1 = x1) * p(X3 = x3 | X2 = x2) * ... * p(Xn = xn | Xn-1 = xn-1) = p(X1 = x1) * ∏p(Xk = xk | Xk-1 = xk-1)
  • 二阶马尔可夫链
二阶马尔可夫链中我们认为每个单词这个随机变量只与前两个随机变量相关,因此上述表达式可以简化为p(X1 = x1, X2 = x2, ..., Xn = xn) = p(X1 = x1) * p(X2 = x2 | X1 = x1) * p(X3 = x3 | X1 = x1, X2 = x2) * ... * p(Xn = xn | Xn-2 = xn-2, Xn-1 = xn-1) = p(X1 = x1) * p(X2 = x2 | X1 = x1) * ∏p(Xk = xk | Xk-2 = xk-2, Xk-1 = xk-1)
 
通常长度n不是固定的,并且为了表述方便,我们可以做一些细节的优化。
1)增加一个开始符号”*“,我们定义所有句子都是以”*“开始,即X-1 = X0 = *;
2)增加一个结束符号”STOP“,我们定义所有句子都是以”STOP“结束。
综上所述,马尔可夫链表达式可以简化为:
一阶马尔可夫链:p(X1 = x1, X2 = x2, ..., Xn = xn) = ∏p(Xk = xk | Xk-1 = xk-1)
二阶马尔可夫链:p(X1 = x1, X2 = x2, ..., Xn = xn) = ∏p(Xk = xk | Xk-2 = xk-2, Xk-1 = xk-1)
 

二阶马尔可夫的语言模型

有了二阶马尔可夫,我们可以重新定义一下语言模型:
1)一个有限的字典V
2)对于每个Trigram(三个连续的词)定义一个参数q(w | u, v),w∈ V ∪ {STOP},u, v ∈ V ∪ {*}
3)对于任意句子x1, x2, ... xn,其中x-1 = x0 = *,xn = STOP,xk(k = 1, 2, ..., n-1)∈ V,句子的出现概率p(x1, x2, ... xn) = ∏q(Xk = xk | Xk-2 = xk-2, Xk-1 = xk-1)
 
举个例来讲,对于句子the dog barks STOP,我们可以做如下分析:
p(the dog barks STOP) = q(the | *, *) * q(dog | *, the) * q(barks | the, dog) * q(STOP | dog, barks)
 

二阶马尔可夫的语言模型的计算

计算二阶马尔可夫的语言模型似乎变成了一个简单的统计问题,通过在训练数据集中统计连续三个词的出现次数c(u, v, w)和两个词的出现次数c(u, v),q(w | u, v) = c(u, v, w) / c(u, v)。

算法到了这里看起来挺完美了,如果有一个不错的训练数据集,我们就可以训练出语言模型了。但是上文我们还提到一个问题,即训练数据集的稀疏性。只有数据集无限大的时候我们才能保证所有可能出现的句子都被语言模型包含,否则我们无法获得可靠的语言模型。另外,倘若任意一个Trigram(三个连续的词)对应的q(w | u, v) = 0,我们将灾难性地获得句子的概率等于0。

现实生活中,我们无法获得无限大的训练数据集,因为我们希望找到一个近似的算法来是所有的Trigram(三个连续的词)对应的q(w | u, v)都不为0,同时尽可能地找到与事实接近的q(w | u, v)。一种常见的方法是利用Unigram(单个词)、Bigram(两个词)、Trigram(三个词)来做近似的计算。

Unigram:q'(w) = c(w) / c()

Bigram:q'(w | v) = c(v, w) / c(v)

Trigram:q'(w | u, v) = c(u, v, w) / c(u, v)

我们定义q(w | u, v) = k1 * q'(w | u, v) + k2 * q'(w | v) + k3 * q'(w),其中k1 + k2 + k3 = 1,ki >= 0。

首先,我们需要证明Σq(w | u, v) = 1。即Σq(w | u, v) = Σ[k1 * q'(w | u, v) + k2 * q'(w | v) + k3 * q'(w)] = k1 * Σq'(w | u, v) + k2 * Σq'(w | v) + k3 * Σq'(w) = k1 * 1 + k2 * 1 + k3 * 1 = k1 + k2 + k3 = 1。

其次,我们应该如果确定k1, k2与k3呢?利用类似交叉熵(Cross Entropy)的方法,我们可以让q(w | u, v)尽量接近训练集中的统计结果。假设c'(u, v, w)是从测试集中统计出的Trigram(三个词)的出现次数,L(k1, k2, k3) = Σc'(u, v, w) * log[q(w | u, v)]。满足L(k1, k2, k3)最大化的临界点便能确定k1, k2, k3。

二阶马尔可夫的语言模型的度量:复杂度(Perplexity)

假设我们有一个测试数据集(共M个句子),每个句子si对应一个概率p(si),因此测试数据集的概率积为∏p(si)。经过简化,我们可以得到log∏p(si) = Σlog[p(si)]。Perplexity = 2^-l,其中l = 1 / M Σlog[p(si)]。(类似熵的定义)

几个直观的例子:

1)假设q(w | u, v) = 1/ M,Perplexity = M;

2)|V| = 50000的数据集的Trigram模型,Perplexity = 74;

3)|V| = 50000的数据集的Bigram模型,Perplexity = 137;

4)|V| = 50000的数据集的Unigram模型,Perplexity = 955。

NLP | 自然语言处理 - 语言模型(Language Modeling)的更多相关文章

  1. 斯坦福大学自然语言处理第四课“语言模型(Language Modeling)”

    http://52opencourse.com/111/斯坦福大学自然语言处理第四课-语言模型(language-modeling) 一.课程介绍 斯坦福大学于2012年3月在Coursera启动了在 ...

  2. 用CNTK搞深度学习 (二) 训练基于RNN的自然语言模型 ( language model )

    前一篇文章  用 CNTK 搞深度学习 (一) 入门    介绍了用CNTK构建简单前向神经网络的例子.现在假设读者已经懂得了使用CNTK的基本方法.现在我们做一个稍微复杂一点,也是自然语言挖掘中很火 ...

  3. NLP 自然语言处理实战

    前言 自然语言处理 ( Natural Language Processing, NLP) 是计算机科学领域与人工智能领域中的一个重要方向.它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和 ...

  4. NLP教程(5) - 语言模型、RNN、GRU与LSTM

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/36 本文地址:http://www.showmeai.tech/article-det ...

  5. RNN and Language modeling in TensorFlow

    RNNs and Language modeling in TensorFlow From feed-forward to Recurrent Neural Networks (RNNs) In th ...

  6. flask 第六章 人工智能 百度语音合成 识别 NLP自然语言处理+simnet短文本相似度 图灵机器人

    百度智能云文档链接 : https://cloud.baidu.com/doc/SPEECH/index.html 1.百度语音合成 概念: 顾名思义,就是将你输入的文字合成语音,例如: from a ...

  7. Recurrent Neural Network Language Modeling Toolkit代码学习

    Recurrent Neural Network Language Modeling Toolkit  工具使用点击打开链接 本博客地址:http://blog.csdn.net/wangxingin ...

  8. 语言模型(Language Modeling)与统计语言模型

    1. n-grams 统计语言模型研究的是一个单词序列出现的概率分布(probability distribution).例如对于英语,全体英文单词构成整个状态空间(state space). 边缘概 ...

  9. 【NLP】Conditional Language Modeling with Attention

    Review: Conditional LMs Note that, in the Encoder part, we reverse the input to the ‘RNN’ and it per ...

随机推荐

  1. odoo多币种

    配置 启用多币种特性,并设置本位币     Gain exchange rate account 汇损收益科目,一般为财务费用下的二级科目 Loss exchange rate account 汇损损 ...

  2. redirect_uri 參数错误的解决的方法

    我通过java代码去获得用户的openid,一直报redirect_uri. 我页面代码的链接为: https://open.weixin.qq.com/connect/oauth2/authoriz ...

  3. 【每日Scrum】第三天(4.24) TD学生助手Sprint2站立会议

    站立会议 组员 昨天 今天 困难 签到 刘铸辉 (组长) 今天主要看了多事件处理的内容然后改了下界面, 和小楠重写架构,使代码更加简洁,并增加了几个界面 架构太难,数据库字段总出问题 Y 刘静 添加事 ...

  4. dsp-asic-fpga

    DSP是在模拟信号变换成数字信号以后进行高速实时处理的专用处理器,它采用的是哈佛设计,即数据总线和地址总线分开,使程序和数据分别存储在两个分开的空间,允许取指令和执行指令完全重叠,也就是说在执行上一条 ...

  5. 软考考点---CPU

    软考考点---CPU         中央处理器(CPU,Central Processing Unit)是一块超大规模的集成电路,是一台计算机的运算核心(Core)和控制核心( Control Un ...

  6. cURL实现Get和Post

    1.Get请求: //初始化 $ch = curl_init(); //设置选项,包括URL curl_setopt($ch, CURLOPT_URL, "http://www.jb51.n ...

  7. jquery live hover

    $("table tr").live({ mouseenter: function() { //todo }, mouseleave: function() { //todo } ...

  8. Java单元测试(Junit+Mock+代码覆盖率)---------转

    Java单元测试(Junit+Mock+代码覆盖率) 原文见此处 单元测试是编写测试代码,用来检测特定的.明确的.细颗粒的功能.单元测试并不一定保证程序功能是正确的,更不保证整体业务是准备的. 单元测 ...

  9. 如何设置SVN提交时必须输入注释

    在Windows环境 在SVN的Repositories路径,E:\Repositories\demo20170408\hooks: 创建pre-commit.bat批处理文件. 文件内容: @ech ...

  10. 前后端通吃的单元测试---mocha

    git clone https://github.com/shenggen1987/mocha-demo.git npm install front 前台测试代码 backend 后台测试代码 先安装 ...