zoukankan      html  css  js  c++  java
  • 【读书笔记】自然语言处理综述 -- 第四章 -- N元语法

    第四章 N元语法

    本章开篇的两句话很有意思,代表了当时两个学派的思想和矛盾。

    一句是"有史以来最伟大的语言学家"乔姆斯基说的:"句子的概率,在任何已知的对于这个术语的解释中,都是一个完全无用的概念"。
    他提出了形式语言,坚信可以通过语法规则来处理文字,对概率不屑一顾。

    而另一句是语言处理大师贾里尼克说的:"每当我开除一个语言学家,语言识别率就能提高一个百分比"。
    此前他曾有和语言学家不愉快的合作经历,加之当时概率学习方法取得了显著成果,因此也是心直口快,不留余地。

    这两位大师的故事在《数学之美》一书中专门有章节讲述,很有趣。在此不详述了,有兴趣的读者可以读读吴军的那本书。

    N元语法模型(N-gram):根据前N-1个词推测第N个单词。如bi-gram, tri-gram。
    可以给后面可能出现的单词指派一个条件概率,或者给后面可能出现的句子指派一个联合概率。

    这种概率预测器广泛应用于语音及手写体识别,机器翻译,拼写更正,无障碍系统等领域中,
    在自然语言处理研究的词类标注,自然语言生成,单词相似度计算等,以及匿名作者辨认,情感抽取,预测式文本输入等应用系统中都有重要作用。

    4.1 语料库中单词数目的计算

    文本语料库中标点符号要不要当做独立的单词来处理?

    (可以作为单词边界,也可以分析语义,如?, !, :等)

    语音语料库中的单词切断,有声停顿,在不同的应用中处理方法不同。

    还有单词首字母的大写,在词类标注中当做单独的单词,而在语音识别中不做区分。

    一些术语:

    词目:具有相同的词干和词义,且主要词类有相同的词汇形式;

    词形:一个单词全部的曲折(如复数)或派生形式;

    型(type): 语料库中不同单词的数目V,即词形的数目;

    例(token): 使用中全部单词的数目N,V > O((sqrt{N}));

    4.2 简单的(非平滑)N元语法

    计算下一个单词出现的概率通常用条件概率公式,但其中的联合概率通常不好计算,在此可以用链式规则,用多个条件概率相乘。
    但是字符串长了以后很难计算,所以假设不考虑所有的前置词,只考虑前若干个,从而可以得到近似的结果,这就是N元语法模型。而这种假设称为马尔科夫假设

    估计这种概率最简单的方法是最大似然估计法MLE,用相对频度(类似条件概率)来计算。
    对于给定的模型M,最后算出的参数集使训练集T的似然度P(T|M)达到最大。

    4.3 训练集和测试集

    概念:训练集,测试集,保留集,调试集(开发集),困惑度(perplexity)

    4.3.1 N元语法及对训练语料库的敏感性

    通过直观化技术,可以看到句子的连贯性随着N值的增大变得越来越好。

    此外,对比其他的英文语料训练集,会发现生成的句子甚至短语基本不会重叠覆盖,语料库的差异很大。
    因此语料库的选择通常不能从不同的文体的文本中选择,即使选择,也是要尽量平衡。

    4.3.2 未知词:开放词汇和封闭词汇

    封闭词汇:假设我们拥有包含所有词汇的词表(容量V)。

    未知词(表外词OOV)在测试集中出现的概率称为表外词率

    开放词汇:针对测试集中的表外词加一个伪词(pseudo-word),模型<UNK>。

    训练步骤:1. 选择词汇,2. 转换<UNK>,3.估计<UNK>概率。

    4.4 N元语法的评测:困惑度

    外在评测(现实评测,端对端):评测某种应用的总体性能。

    内在评测:与任何应用无关的评测方法,如困惑度(PP)。

    困惑度:单词归一化后的测试集的概率。(PP(W) = P(w_1w_2...w_N)^{-1/N})

    困惑度的最小化等价于测试集概率的最大化。

    加权平均转移因子:任何一个单词后面可能接的单词的数量的加权。

    N-gram中N的增大会降低困惑度,领域知识(如封闭词汇)也会降低困惑度。

    4.5 平滑

    最大似然估计法面临一个零概率的问题,所以我们采用了平滑方法。

    4.5.1 Laplace 平滑

    在归一化之前,所有的计数加一,(加一平滑)。(P_{Laplace}(w_i) = frac {c_i + 1} {N + V})

    或者用归一化因子(frac {N} {N+V}), (c_i^* = (c_i + 1) frac {N} {N + V}), 然后用N来归一化,得到(P_i^*)

    把平滑看成打折,相对折扣(d_c = frac {c^*} {c})

    因为矩阵中零值很多,所以加一平滑,通常使得折扣过大,所以此方法不是最好的。

    4.5.2 Good-Turing 打折法

    单元素:只出现过一次的单词或N元语法。

    Good-Turing打折法使用单元素的频率作为零计数的一元语法的频率。

    (N_c)是出现次数为c的N元语法数,看成是频率c出现的频率。(N_c)的最大似然估计MLE的计数是c。

    Good-Turing:用训练集中出现次数为c+1的事物的概率来估计出现次数为c的事物的概率。

    (c^* = (c+1) frac {N_{c+1}} {N_c}) (打折系数)

    具有零计数N_0的事物的概率(P_{GT}^*)称为遗漏量(P_{GT}^* = frac {N_1} {N})

    举例如下,鲤鱼10条,河鲈3条,白鱼2条,鳟鱼1条,鲑鱼1条,鳗鱼1条,鲶鱼和鲈鱼未观测到。

    概率估计如下。

    4.5.3 Good-Turing高级专题

    Good-Turing假设每个二元语法的分布都是二项式,且我们知道未见语法数(N_0), 因为给定了词汇容量V,所以(N_0 = V^2 -)看见的所有二元语法数。

    这个方法的缺陷是(N_{c+1})可能为0,解决方法是使用Simple Good-Turing算法,先对(N_c)进行平滑。

    还有就是可以假定较大的计数是可靠的,设定一个阈值。

    此外,也可以把计数较低(如1)的N元语法看成未见事件,使用Good-Turing打折,再使用平滑算法。

    还可以与其他回退、插值方法结合起来使用。

    4.6 插值法

    回退法:只有当阶数较高的N元语法中存在零计数时,才回退到阶数较低的N元语法中。

    插值法:从所有的N元语法估计中,把不同的概率估计混合起来,也就是加权。

    比如线性插值:(hat{P} (w_n | w_{n-2} w_{n-1}) = lambda_1 P (w_n | w_{n-2} w_{n-1}) + lambda_2 P (w_n | w_{n-1}) + lambda_3 P (w_n))(sum_i lambda_i = 1)

    此外,其他版本会计算(lambda)更加复杂一些,比如条件插值法,让三元语法比二元语法的(lambda)更高一些。

    此外,还可以采用保留语料库来学习(lambda), 还可以用EM算法来计算。

    4.7 回退法

    定义打折概率(P^*)和归一化因子(alpha). 三元语法计数为0,则算二元语法计数,并乘上(alpha),以此类推。

    Good-Turing是将未见概率均分给各事件,而Katz回退法能够根据一元,二元的信息,将概率在三元语法中较好地分摊。

    回退法使用打折概率而非MLE概率的原因是:MLE概率的总和为1,(sum_i P(w_i | w_j w_k) = 1),
    如果使用这个概率,当MLE为0时回退到阶数较低的模型,得到的概率量会加到公式中,此时会大于1。

    (alpha)保证所有低阶的N元语法概率量之和,等于通过高阶N元语法打折节省的概率量。

    4.8 实际问题:工具包和数据格式

    使用对数格式,避免下溢,加快计算。对数的相加替代概率的相乘,使得数不至于太小。

    回退N元语法模型一般用ARPA格式。

    工具包:SRILM,Cambridge-CMU. 工具包取一个原始的文本文件,并记录一些需要的参数,如N的阶数,打折类型等,输出是ARPA格式的语言模型。

    4.9 高级专题

    4.9.1 Kneser-Ney

    Kneser-Ney算法是一种绝对折扣的打折方法,从每一个计数中固定减去一个绝对折扣数d。

    某个句子的例子:有两个备选词,Francisco比glasses频率更高,但前者一般用在San Francisco中,所以预测值应为glasses。

    这种回退概率叫接续概率,曾经在较多的上下文中出现过的单词在新的上下文中会有更多出现的可能性。

    Kneser-Ney使用插值的形式比回退要好。

    已经证明,任何一个插值模型都可以表示为一个回退模型,因此只需要存储ARPA格式。

    4.9.2 基于类别的N元语法

    比如,训练数据中有"去伦敦","去北京","去上海",那么虽然没有"去杭州"一词,但根据聚类,也可以估计"去"之后的城市的似然度。

    变体如,IBM聚类,一种硬聚类,每个单词只属于一个类别。

    4.9.3 语言模型的自适应和网络应用

    自适应有点类似迁移学习,从领域之外的大量数据集上训练,使得训练得到的模型与某一领域内的小量数据自适应。这种数据来源一般是Web,可以用搜索引擎得到的网页计数。

    4.9.4 长距离信息的使用

    长距离,如四元,五元,但当超过六元语法之后,就不再有效果了。

    隐藏语言模型:在文本中一个单词被使用过一次,它有可能被再次使用。

    文本倾向于表达大致差不多的事情,特定主题用词类似,可以训练基于主题的语言模型。

    还有就是,后面出现的单词和前面的单词在语义上有相似性。这种模型使用潜伏语义索引

    如跳跃式的N元语法(skip N-gram),可变长N元语法。

    4.10 信息论背景

    一般困惑度是测试集概率的一个归一化版本,另一种研究困惑度的方法是建立在信息论交叉熵上的。

    (H(X) = - sum_{xin X}p(x)log_2 p(x)), 底数为2,熵用比特来度量。可以通过熵计算出表达信息需要比特数的下界。

    不仅可以计算单个变量的熵,还可以计算序列的熵。熵率定义为用这个序列的熵除以单词数。

    但语言是无限长的序列。Shannon-McMillan-Breiman定理指出,如果一个语言是正则的(平稳的,遍历的),那么可以取一个足够的长的序列来替代语言中所有可能的序列的总和,而这个序列中有很多短序列,按照它们各自的概率重复出现在长序列中。

    在平稳随机过程中,单词在时间t的分布,与在时间t+1的分布是相同的。比如马尔科夫模型以及n元语法模型,是平稳的。但是自然语言却不是,可能依赖于任意长的事件,且依赖于时间。

    4.10.1 交叉熵

    用于比较模型。比如用m作为p的近似模型。交叉熵为:

    (H(p, m) = lim_{ n ightarrow infty } - frac {1} {n} sum_{W in L} p(w_1, ...,w_n)logm(w_1,...,w_n))

    对于一个平稳过程,有(H(p, m) = lim_{ n ightarrow infty } - frac {1} {n} logm(w_1,...,w_n))

    交叉熵是熵的上界,(H(p) le H(p, m))

    这说明可以用一个简化的模型m来帮助我们根据概率p估计所取符号的一个序列的真正的熵。m越精确,(H(p, m))越接近(H(p))

    模型(M=P(w_i|w_{i-N+1} ... w_{i-1}))的交叉熵:(H(W)=-frac{1}{N}logP(w_1w_2...w_N)), 困惑度 Perplexity = (2^{H(W)}) = (P(w_1w_2...w_N)^{-frac {1} {N}})

    4.11 高级问题:英语的熵和熵率均衡性

    英语的真正的熵可以为我们的概率语法实验提供一个可靠下界,而且可以帮助理解语言中哪一部分提供的信息量最大。

    人们在说话时,总是力求保持均衡的熵率,信道传输也是一样的,用均衡的比特传输。

    句子的熵与在理解该句子的过程中付出的努力存在关系,这种关系可以用眼球跟踪数据的阅读时间来衡量。

    4.12 小结

    1)N元语法的优点在于他们可以使用丰富的词汇知识,缺点是在一些实际的应用中他们对训练语料库的依赖性太强。

    2)平滑算法常用的是回退法和插值法。

    3)不论是回退还是插值都需要打折,打折算法有Kneser-Ney, Witten-Bell, Good-Turing等。

    4)测试集上语言模型的困惑度(2^H)用于对不同的语言模型比较。

    4.13 文献和历史说明

    历史上,统计学习与规则学习争论不休。

    马尔科夫最早提出N元语法的数学原理,香农通过N元语法的计算来逼近英语的单词序列。马尔科夫模型成为了20世纪50年代普遍使用的单词序列模型。

    乔姆斯基后来发表了一系列有影响力的文章,并称"有限状态马尔科夫过程"不能作为人类语法知识的完美认知模型。后来统计学习方法陷入低谷。

    贾里尼克在70年代成功地在语音识别系统中使用了N元语法,才让统计学习方法又重新登上舞台。

    语言模型的平滑技术也经历了加一平滑,Good-Turing,Witten-Bell打折法,插值的Kneser-Ney算法等。

    当前语言研究集中在自适应的研究,基于句法与对话结构各种精细语言结构使用的研究以及超大规模N元语法的研究等问题上。

  • 相关阅读:
    python-创建一个登录判断的函数
    python-创建一个本地txt文本
    python-简单函数小例子 单位转换
    微信小程序性能测试之jmeter踩坑记录(四)
    手动添加Keil的固件包Packs
    使用Socket的简单Web服务器
    网络端口(port)
    Redis 5种主要数据类型和命令
    c# 索引器方法
    .net 获取类型的Type类型的几种方法
  • 原文地址:https://www.cnblogs.com/yanqiang/p/11725448.html
Copyright © 2011-2022 走看看