个人学习nlp笔记:学习材料CS124、COSC572和《Speech and Language Processing》第三版
语言模型的任务是赋予句子一个概率,比如在机器翻译任务中,我们借由概率,选择一个"较好"的翻译,同样在拼写纠错和语音识别中也有很多应用。
将句子中的每个词当作一个变量,因此即将出现的单词w5的概率可用一个条件概率表示。
计算量太大,且需要数据集太多,因此我们可以引入马尔可夫假设,看作只有前几个单词对有影响。想想确实是这样。显然前几个是最重要的,后面的单词加入后,对应的数据集指数增加,相应得到的概率必然很小,不是决定性因素,同时数据集也不支持。
然而语言是不独立的,就算距离很远的单词也是会存在关系的,比如上文的 computer和crashed
计算例子,其中包括了p(w|*), 在trigram中应为 P(W|*,*)
同样,我们应该使用log,把概率相乘改为概率相加,这是为了防止编程时候的数值下溢(arithmetic underflow),同时相加的运算要快于相乘。
评估语言模型性能的最佳方法,在一个不在训练集中的数据中训,来与其他模型比较,这也叫做外在评估(Extrinsic/in-vivo evaluation)
缺点就是太浪费时间了,因此可以采用内部(intrinsic)评估的方式:perplexity
这个模型的直觉就是能给预测的单词赋予更高的概率的模型就是好模型
n-gram的概率矩阵是十分稀疏的,尤其在bigram和trigram中。
比如在WSJ数据集中,有
phrase | count |
---|---|
denied the allegations | 5 |
denied the speculation | 2 |
denied the rumors | 1 |
denied the report | 1 |
但是在测试集中没有出现,如
phrase | count |
---|---|
denied the offer | 0 |
denied the loan | 0 |
但是显然,下面两个也是可能出现的。因此我们要对这些P(w)=0进行处理,原因有二
①这些虽然为0,但依旧很可能出现
②任何一个为零,整个句子的概率就成了0,就算log化,log0也没法操作,同时计算perplexity也没法进行(分母为0咋整)。
有些时候在trigram或bigram上,不单单只有概率为0的问题,同样存在着诸如,出现了在模型中没有见过的词,这些词被称为未登录词(unknown words)或者是out of vocabulary (OOV) words,OOV词在测试集上的的出现概率被称为OOV rate。
一般解决这个问题有两种方法:
1.在文本标准化过程中,将所有未登录词标记为,再根据计数来估计概率
2.设置一个门槛,小于给定数V的单词全都当作
有些词出现在我们的单词表中,但是计数为0(比如一些bigram模型),此时,把一些常出现的词的概率分一点点给这些出现零次的词,这个方法就叫平滑或者贴现(discounting),书中介绍了4种平滑方法:
加一平滑法,加k平滑法以及简单退避法和Kneser-Ney平滑法。
非常直观,就是所有单词出现次数加1,然后总数加V(单词个数),当然,这个平滑的效果在n-gram上不是很好,但是在文本分类或者是一些概率0出现的不是那么多的领域,还是可以使用这个方法。因为我们改变了单词出现的次数,所以这实际上也是一种non-maximum likelihood的估计法
我们也可以用adjucted count的方法,实质是令 P m l e : = P a d j u s t e d P_{mle} := P_{adjusted} Pmle:=Padjusted。
上两张图分别是直接count加1和使用adjusted count的区别,实质上,这两种方法对高频率的单词概率的影响都是差不多大的。
实质和加1的方法差不多,其中K的选取可以用交叉验证选超参数的方法,虽然同样对语言模型效果不好,但是在文本分类等问题上有一定帮助。
如果在使用trigram或更高维度语言模型时,由于单词出现频数过小等原因,可能导致置信度不足,可以选择退到bigram或者unigram模型,这就是退避法(back off)的直观理解。而插值法(Interpolation)就是将trigram, bigram和unigram用赋权的方法线性组合,获得新的概率,一般插值法的表现更好。
两种插值法,在条件λ种,λ的大小和 w n w_{n} wn前面两个单词有关。
λ的估计,思路也是像选超参数一样选λ。
也可以用EM算法来获得局部最优的λ(Jelinek and Mercer, 1980)
卡茨退避法:
Good-Turing Smoothing其实就是之前 c a d j u s t e d c_{adjusted} cadjusted的方法
Kneser-Ney平滑方法在机器翻译和语音识别中都非常常见,其来源于另一种方法:absolute discounting interpolation。
在AP newswire上的训练集切分为两份,每份都为两千两百万个单词,可以发现,在频数2-9中,只需要减去0.75,我们就能的到和在第二份训练集差不多的count,而在0-1中不行。因此absolute discounting interpolation的直觉理解就是高频率的单词的估计较为可靠,而低频率不可靠,我们要对词频进去一个固定的数d,这个d要对高频率的单词计数影响较小。
absolute discounting interpolation:其实也可以单独设count为1时d为0.5等
在unigram中,对一些词可能没用很好办的处理,比如词伙或者是一些诸如Hong kong的词组,虽然Kong这个词出现的多,但是仅限于跟在Hong后面,因此需要对unigram得到的概率进行处理,用一个 P C O N T I N U A T I O N P_{CONTINUATION} PCONTINUATION来改进单独的 P ( w i ) P(w_{i}) P(wi)。
我们假设如果一次词在不同上下文中出现次数多,那么在新的内容中,它出现的可能也会更大,因此可得 P C O N T I N U A T I O N P_{CONTINUATION} PCONTINUATION的值基于它在不同上下文中出现次数,也就是它所完成的二元组类型的数量。
最终的bigram的KN平滑方法:
第一个max比较好理解,我们不想要一个负的概率。第二个项相当于被赋予了 C ( w i − 1 w i ) − d C(w_{i-1}w_{i})-d C(wi−1wi)−d去掉的概率。 λ ( w i − 1 ) λ(w_{i-1}) λ(wi−1)中前面的 d ∑ v C ( w i − 1 v ) \frac{d}{\sum_{v} C(w_{i-1}v)} ∑vC(wi−1v)d主要的功能还是标准化,而 ∣ { w : C ( w w i − 1 v ) } ∣ |{\{w:C(w_{wi-1}v)\}}| ∣{w:C(wwi−1v)}∣就相当于所有可以跟着 w i − 1 w_{i-1} wi−1的词的个数。
下面是一个推广到其他ngram模型的KN平滑:
其中,如果我们计算被插值的最高次序的ngram(本文例子中即trigram)或者较低次序的ngram(如应bigram和unigram),用 C N K C_{NK} CNK来代替普通的count,在最高次序的ngram中,直接使用count,但是较低的中,使用continuation count,也就是 ∣ { w : C ( w w i − 1 v ) } ∣ |{\{w:C(w_{wi-1}v)\}}| ∣{w:C(wwi−1v)}∣,也就是本文中的the number of unique single word context for *。后一项,即λ…表示的就是低一次序的ngram,这也就是为什么说他是迭代的原因。
在迭代到unigram时候,用一个空字符代替 w i − n + 1 i − 1 w_{i-n+1}^{i-1} wi−n+1i−1,因为unigram中和前一个字符没关系哈。这样的话,可知未登录词就为一个计算为0的字符,且概率服从权重为λ的均匀分布。
在使用网络数据时,我们可能会建立起巨大的语言模型,比如谷歌在06年做的一个数据集中就有上亿个单词,因此显然我们需要寻求优化的方法。我们可以用 64-bit的哈希值来表示数字,用4-8bit的位置存放概率。我们同样可以用修剪(prune)的方法来简化,比如用熵的方法衡量不重要的n-gram模型(Stolcke,1998),或者只储存大于一个阈值的单词。或者使用Bloom filters (Talbot and Osborne 2007, Church et al. 2007)方法来获得近似的语言模型等等。
简单退避法,就是在n-gram中若出现为0的情况下,退回(n-1)-gram模型中获得相关的值再乘以一个常数,如果还为0,继续往下迭代。
一些其他的语言模型
用于评估语言模型的复杂度(Perplexity)实际上是从交叉熵引变而来,交叉熵实际就是用来衡量信息不确定性的一个指标,log的下标一般为2,这样熵的单位就是bit了
交叉熵,用来度量分布的差异。
熵的概念还是理解不好,以后再遇到要搞定。
错误一般分为两种,一是直接的typo,错误的拼写导致得到一个不存在的词;二是得到一个存在的词,但是原因一可能是typo第二可能是发音相似而导致的错误。
噪声通道模型也就是, noisy channel model,其的直观理解是
给定这个模型,我们能通过其,找到最可能是原本正确的单词 w w w。其实就是一个贝叶斯推断的模型。
似然概率 P ( x ∣ w ) P(x|w) P(x∣w)又称作 c h a n n e l m o d e l channel\ model channel model和 e r r o r m o d e l error \ model error model。
一般其中的编辑距离可以是拼写相关的或是发音相关的距离,本文用的第一种。其次,在拼写错误中,80%的错误都在编辑距离1,几乎所有都在编辑距离1到2中。当然,同样像词之间少了空格或者破折号的这类错误也需要我们的关注。
以一个拼写错误 a c r e s s acress acress为例子:
其中先验概率 p ( w ) p(w) p(w)可通过语言模型获得,unigram或者trigram都行(trigram中应该是 p ( w i ∣ w i − k + 1 i − 1 ) p(w_{i}|w_{i-k+1}^{i-1}) p(wi∣wi−k+1i−1))。本文以unigram为例子。
而对于 p ( x ∣ w ) p(x|w) p(x∣w),也就是 e r r o r m o d e l error\ model error model的概率,也成为probability of edit,
更细节地,我们可以通过从sub、trans、del和ins的混淆矩阵获得 p ( x ∣ w ) p(x|w) p(x∣w),比如这八个由sub形成的混淆矩阵。
当然,一些现成的混淆矩阵数据集也是可以使用的:
地址:Roger Mitton and Peter Norvig,还有一种方法是通过EM算法的迭代得到混淆矩阵 Kernighan et al. (1990)。
但是显然unigram的结果非常的不可靠,让我们看看bigram中的结果:
在拼写错误中,有25%的错误是来自已登陆词。同样noisy channel也能处理typo形成已登录词的问题。
输入一个句子, X = { x 1 , . . . , x n } X=\{ x_{1},...,x_{n} \} X={x1,...,xn},生成候选的修正句子 C ( X ) C(X) C(X),选取最高概率的句子。如句子: O n l y t w o o f t h e w a p p l e s Only\ two\ of\ thew\ apples Only two of thew apples 。其候选的句子如下:
W ^ = arg max W ∈ c ( x ) P ( X ∣ W ) P ( W ) \hat{W} = \underset{W\in{c(x)}}{\arg\max} P(X|W)P(W) W^=W∈c(x)argmaxP(X∣W)P(W)
其中 p ( W ) p(W) p(W)可以用语言模型比如trigram得到,而 p ( W ∣ x ) p(W|x) p(W∣x)由noisy channel model得到。但是要注意,就算是未发生替换,我们也要计算其概率。
这样的操作可行,但也会导致诸如将不常出现但是正确的词替换为常用的词这类的过度纠正问题。所以我们需要知道,这是不是一个需要修改的词。
l o g p ( w ∣ x ) − l o g p ( x ∣ x ) logp(w|x)-logp(x|x) logp(w∣x)−logp(x∣x)
我们也可以使用更大的词典,这样很多网络用语能被正确的识别,同时我们有时候希望对语言模型和噪声通道赋予不一样的权重或者他们的范围是不对称的,此时我们可以加入一个超参数λ。
如果我们只想对特定的易混淆词组(piece and peace)或者语法纠正,像 among和between,我们可以用上下文信息进行有监督的训练来提供判断。