从0探索NLP——人言否?
语言模型在NLP中占有非常重要的地位,从传统‘基于统计概率的语言模型’到‘基于深度学习的语言模型’各类语言模型层出不穷。本文将介绍传统的语言模型。
数学基础
联合概率
即多个随机事件同时发生的概率。先以两个事件举例,比如随机事件A与随机事件B同时发生的概率,记作:
P
(
A
B
)
=
P
(
A
,
B
)
\mathbf{P(AB)}=\mathbf{P(A,B)}
P(AB)=P(A,B)
条件概率
假设在随机事件A发生的条件下,随机事件B发生的概率。记作:
P
(
B
∣
A
)
=
P
(
A
B
)
P
(
A
)
\mathbf{P(B|A)}=\frac{\mathbf{P(AB)}}{\mathbf{P(A)}}
P(B∣A)=P(A)P(AB)
链式法则
当联合概率中事件数量多于2个时,先以3个为例,结合条件概率公式:
P
(
A
,
B
,
C
)
=
P
(
A
∣
B
,
C
)
∗
P
(
B
,
C
)
=
P
(
A
∣
B
,
C
)
∗
P
(
B
∣
C
)
∗
P
(
C
)
\mathbf{P(A,B,C)}=\mathbf{P(A|B,C)}*\mathbf{P(B,C)}=\mathbf{P(A|B,C)}*\mathbf{P(B|C)}*\mathbf{P(C)}
P(A,B,C)=P(A∣B,C)∗P(B,C)=P(A∣B,C)∗P(B∣C)∗P(C)
推广到N个事件就是
P
(
X
1
,
.
.
.
,
X
n
)
=
P
(
X
n
∣
X
n
−
1
,
.
.
.
,
X
1
)
∗
P
(
X
n
−
1
∣
X
n
−
2
,
.
.
.
,
X
1
)
∗
.
.
.
∗
P
(
X
2
∣
X
1
)
∗
P
(
X
1
)
\mathbf{P(X_1,...,X_n)}=\mathbf{P(X_n|X_{n-1},...,X_1)}*\mathbf{P(X_{n-1}|X_{n-2},...,X_1)}*...*\mathbf{P(X_2|X_1)}*\mathbf{P(X_1)}
P(X1,...,Xn)=P(Xn∣Xn−1,...,X1)∗P(Xn−1∣Xn−2,...,X1)∗...∗P(X2∣X1)∗P(X1)
极大似然估计
统计语言模型
定义
直观上,统计语言模型是一种用来描述语料中词、句这些不同语法单元概率分布的模型,通过这个模型我们可以预测语句出现的概率。
实质上,由于“语言”具有前后顺序关系的特殊性,统计语言模型也可以说是描述词序列概率分布的模型,通过这个模型我们可以预测语句下一个出现的词。
简言之就是从语料中学习说话的方式,并判断‘人言否’?。
公式
“语句出现的概率”言外之意就是语句中所有词同时出现的概率。假设语料库C,语句D是由t个词w组成的,则句子概率表示为:
P
(
D
)
=
P
(
w
1
,
.
.
.
,
w
t
)
=
P
(
w
t
∣
w
1
,
.
.
.
,
w
t
−
1
)
∗
P
(
w
t
−
1
∣
w
1
,
.
.
.
,
w
t
−
2
)
∗
.
.
.
∗
P
(
w
2
∣
w
1
)
∗
P
(
w
1
)
\mathbf{P(D)}=\mathbf{P(w_1,...,w_t)}=\mathbf{P(w_t|w_1,...,w_{t-1})}*\mathbf{P(w_{t-1}|w_1,...,w_{t-2})}*...*\mathbf{P(w_2|w_1)}*\mathbf{P(w_1)}
P(D)=P(w1,...,wt)=P(wt∣w1,...,wt−1)∗P(wt−1∣w1,...,wt−2)∗...∗P(w2∣w1)∗P(w1)
马尔科夫假设
马尔可夫假设的原理是根据大量的数据分析后,根据已经存在的语料,语句中下一个词的出现仅依赖于它前面的n-1个词。即:
P
(
w
i
∣
w
1
,
.
.
.
,
w
i
−
1
)
≈
P
(
w
i
∣
w
i
−
n
+
1
,
.
.
.
,
w
i
−
1
)
≈
c
o
u
n
t
(
w
i
−
n
+
1
,
.
.
.
,
w
i
)
c
o
u
n
t
(
w
i
−
n
+
1
,
.
.
.
,
w
i
−
1
)
\mathbf{P(w_{i}|w_1,...,w_{i-1})}\approx\mathbf{P(w_{i}|w_{i-n+1},...,w_{i-1})}\approx\frac{\mathbf{count(w_{i-n+1},...,w_{i})}}{\mathbf{count(w_{i-n+1},...,w_{i-1})}}
P(wi∣w1,...,wi−1)≈P(wi∣wi−n+1,...,wi−1)≈count(wi−n+1,...,wi−1)count(wi−n+1,...,wi)
这里的count表示的是一种计数函数,最简单的计数函数就是“频次”,通过计算最大似然估计概率,约等于计算“频率”。
根据马尔科夫假设,统计语言模型公式可以进行化简,化简后的就是NGram,所以这里我可以理解为NGram就是采取何种精度对句子概率进行计算
评估
如何评价一个语言模型好坏,这里用到的是**“困惑度”**。
评估即判断哪个语言模型可以给测试集中(正确的)句子赋予较高的概率值。当语言模型训练完之后,测试集中的句子都是正常的句子,那么训练好的模型就是在测试集上的概率越高越好。公式如下
P
P
(
D
)
=
P
(
D
)
−
1
t
\mathbf{PP(D)}=\mathbf{P(D)^{-\frac{1}{t}}}
PP(D)=P(D)−t1
从1到N
1Gram(UniGram)
当统计语言模型公式根据马尔科夫假设化简的精度为1时,即N=1时,则公式为:
P
(
D
)
=
P
(
w
t
)
∗
P
(
w
t
−
1
)
∗
.
.
.
∗
P
(
w
2
)
∗
P
(
w
1
)
\mathbf{P(D)}=\mathbf{P(w_t)}*\mathbf{P(w_{t-1})}*...*\mathbf{P(w_2)}*\mathbf{P(w_1)}
P(D)=P(wt)∗P(wt−1)∗...∗P(w2)∗P(w1)
即每个词的概率直接相乘,这时根据联合概率公式的一个推论:“当事件A、B、C相互独立时满足”
P
(
A
,
B
,
C
)
=
P
(
A
)
∗
P
(
B
)
∗
P
(
C
)
\mathbf{P(A,B,C)}=\mathbf{P(A)}*\mathbf{P(B)}*\mathbf{P(C)}
P(A,B,C)=P(A)∗P(B)∗P(C)
可知,使用1gram模型我们默认了词与词之间是没有关系的,这显然是不科学的,比如:
“我爱吃比萨”
和
“我爱喝比萨”
因为‘吃’和‘喝’在语料中出现的概率都差不多,那这样的话,两句话的句子可能概率就差不多,‘宝友,这玩意可不兴喝呀’
2Gram(BiGram)
那我们尝试使用考虑一下前1个词的模型,即N=2,则公式为:
P
(
D
)
=
P
(
w
t
∣
w
t
−
1
)
∗
P
(
w
t
−
1
∣
w
t
−
2
)
∗
.
.
.
∗
P
(
w
2
∣
w
1
)
∗
P
(
w
1
)
\mathbf{P(D)}=\mathbf{P(w_t|w_{t-1})}*\mathbf{P(w_{t-1|w_{t-2}})}*...*\mathbf{P(w_2|w_1)}*\mathbf{P(w_1)}
P(D)=P(wt∣wt−1)∗P(wt−1∣wt−2)∗...∗P(w2∣w1)∗P(w1)
这样,由于**‘吃’+‘比萨’这个和‘喝’+‘比萨’**两个combo在出现次数有着很大的区别——应该很少人真的能写出‘喝比萨’吧,第二句就不是很合理了。
Ngram
将上述N=1、N=2的介绍推广,即考虑前N个词的语言模型——NGram。不过N越大越好吗?
首先,更大的N的确对下一个词是否应该出现有更多的约束信息,即具有更大的辨别力。但是,过大N会使得词的组合样本过少,可靠性降低。
举个例子,还是说:
“我 爱吃 比萨”
此时分词结果是3个词,我们把N指定为3,也许不会出什么问题,说“我爱吃比萨”的人应该有很多。
不过我们把句子丰富成:
“我 爱吃 奥尔良 烤 鸡肉 加 菲律宾 的 凤梨 的 薄底 夏威夷 比萨"
此时分词结果是13个词,我们把N就指定为13,如此“精确的”比萨在语料中出现的次数必然少之又少,用13Gram来评价这个句子的概率也就很低,但显然这句话没什么问题,所以样本过少那样本的参考价值或者说可靠性就会降低。
所以:
- 理论上,N越大越好。
- 经验上,3Gram(TriGram)用的最多。
- 尽管如此,原则上,能用2Gram解决,3Gram。
取概率对数
在计算中,为了避免数据溢出、提高性能,通常会对概率公式两边取log10后使用,并用加法运算替代乘法运算。以2Gram的公式为例
lg
(
P
(
D
)
)
=
lg
(
P
(
w
t
∣
w
t
−
1
)
)
+
lg
(
P
(
w
t
−
1
∣
w
t
−
2
)
)
+
.
.
.
+
lg
(
P
(
w
2
∣
w
1
)
)
+
lg
(
P
(
w
1
)
)
\lg(P(D))=\lg(P(w_t|w_{t-1}))+\lg(P(w_{t-1|w_{t-2}}))+...+\lg(P(w_2|w_1))+\lg(P(w_1))
lg(P(D))=lg(P(wt∣wt−1))+lg(P(wt−1∣wt−2))+...+lg(P(w2∣w1))+lg(P(w1))
平滑技术(Smoothing)
统计学模型能够实现的基础就是有足够多的样本,但究竟多少是’足够多‘呢?从’客观‘的角度讲,只要样本是在自然随机条件下产生的就是’足够多‘,但完全的自然随机又是很难做到的。从’有限‘的角度讲,因为样本总是有限的必然会有没涉及的或者涉及过少的样本,也就没有’足够多‘一说。
在大规模数据统计方法中,总会因为有限的训练语料产生样本数据稀疏问题,甚至有些样本干脆没出现过,进而导致零概率问题(即Zipf定律)。
扩展:语言统计学三大定律:Zipf law,Heaps law和Benford law
举例来说,假如语料库中没有“我爱吃比萨”的组合,即概率是0,我们能说这句话是有问题的嘛?假如已有的语料中有“我爱吃XXX”别的什么东西的组合,那我们是不是可以推测“我爱吃比萨”存在的自然概率?
为了解决这一问题,诞生了一系列处理方法,这些方法叫做’平滑技术‘,其基本思想就是“劫富济贫”——降低已出现NGram条件概率分布,降低的部分分给未出现的NGram以使条件概率分布非零,且经平滑后保证概率和小于等于1。
经典的平滑技术有以下几种**(以下技术公式说明均已3Gram为例,主要是理解方法)**
Add-one(Laplace)
加一平滑法,又称拉普拉斯平滑法,即通过在原公式上计数位置+1的方式保证每个NGram在训练语料中至少出现1次。
P
M
L
E
(
w
i
∣
w
i
−
2
,
w
i
−
1
)
≈
c
o
u
n
t
(
w
i
−
2
,
w
i
−
1
,
w
i
)
c
o
u
n
t
(
w
i
−
2
,
w
i
−
1
)
\mathbf{P_{MLE}{(w_{i}|w_{i-2},w_{i-1})}}\approx\frac{\mathbf{count(w_{i-2},w_{i-1},w_{i})}}{\mathbf{count(w_{i-2},w_{i-1})}}
PMLE(wi∣wi−2,wi−1)≈count(wi−2,wi−1)count(wi−2,wi−1,wi)
记2Gram的的个数是V
P L a p l a c e ( w i ∣ w i − 2 , w i − 1 ) ≈ c o u n t ( w i − 2 , w i − 1 , w i ) + 1 c o u n t ( w i − 2 , w i − 1 ) + V \mathbf{P_{Laplace}{(w_{i}|w_{i-2},w_{i-1})}}\approx\frac{\mathbf{count(w_{i-2},w_{i-1},w_{i})}+1}{\mathbf{count(w_{i-2},w_{i-1})}+\mathbf{V}} PLaplace(wi∣wi−2,wi−1)≈count(wi−2,wi−1)+Vcount(wi−2,wi−1,wi)+1
该方法简单暴力,不过暴力一般不是解决问题的最好手段,当V远大于**count(w_i-1)**时,平滑后的结果反而会“喧宾夺主”——更趋近于
1
V
\frac{1}{\mathbf{V}}
V1
而不是
c
o
u
n
t
(
w
i
−
2
,
w
i
−
1
,
w
i
)
c
o
u
n
t
(
w
i
−
2
,
w
i
−
1
)
\frac{\mathbf{count(w_{i-2},w_{i-1},w_{i})}}{\mathbf{count(w_{i-2},w_{i-1})}}
count(wi−2,wi−1)count(wi−2,wi−1,wi)
扩展:所以基于Laplace Law的优化还有,Lidstone’s law也叫Add-k Smoothing,就是把分子的1替换成[0,1]的数K,分母的V替换成KV。当K=0.5时又称为Jeffreys-Perks Law
Good-Turing
直接举个例子,假如在河里钓鱼,一共钓上来10条鱼分别是3条鲤鱼、2条鲫鱼、2条草鱼、1条鲢鱼、1条鲇鱼和1条鲟鱼,问:
- 下一条钓上来鲟鱼的概率是多少?
- 下一条钓上来的鱼是没掉过的鱼的概率是多少?
这里涉及到一个细节,一般的统计概率问题’箱子摸球‘啊、’掷骰子‘啊都会事先告诉你箱子里有几种球、骰子有几个面,就是为了限制样本种类。当样本种类也是未知时,即有语料中从未出现过的NGram时,概率问题怎么办?
记原本的自然的环境是X(河里所有的鱼),我们观测到的环境是X’(钓到的鱼),常规思路从X’角度看鲟鱼概率是1/10进而推测(认为)X中概率也是如此,第一问的答案是1/10。
这里引入一个新符号,记在X’中出现r次的样本有Nr种,那么这道题中N1=3(鲢鱼、鲇鱼、鲟鱼)、N2=2(鲫鱼、草鱼)、N3=1(鲤鱼)。
Good-Turing的思想就是,引入X’中出现0次的样本的概率,为了使得X’总概率和仍为1,对大于0次的样本的概率做对应调整。调整的方法是用出现r+1次的样本的种数代替X’中出现r次的样本的次数进而计算概率。
记X’的样本个数是V(钓10条鱼),出现r次的样本的次数为count_r*用公式表示就是:
c
o
u
n
t
r
∗
=
(
r
+
1
)
N
r
+
1
N
r
\mathbf{count_r^*}=(r+1)\frac{N_{r+1}}{N_r}
countr∗=(r+1)NrNr+1
进而得概率为
P
r
∗
=
c
o
u
n
t
r
∗
V
\mathbf{P_r^*}=\frac{\mathbf{count_r^*}}{V}
Pr∗=Vcountr∗
简单推一下P0和P1 。P0,没出现的鱼,因该是1减去所有出现次数的概率Pr*与次数种数Nr的乘积
P
0
∗
=
1
−
∑
r
>
0
N
r
P
r
∗
=
1
−
1
V
∑
r
>
0
N
r
c
o
u
n
t
r
∗
=
V
−
∑
r
>
0
(
r
+
1
)
N
r
+
1
V
=
V
−
(
V
−
1
∗
N
1
)
V
=
N
1
V
\begin{aligned} \mathbf{P_0^*}&=1-\sum_{r>0}{N_r\mathbf{P_r^*}} \\ &=1-\frac{1}{V}\sum_{r>0}{N_r\mathbf{count_r^*}} \\ &=\frac{V-\sum_{r>0}{(r+1)N_{r+1}}}{V} \\ &=\frac{V-(V-1*N_1)}{V} \\ &=\frac{N_1}{V} \end{aligned}
P0∗=1−r>0∑NrPr∗=1−V1r>0∑Nrcountr∗=VV−∑r>0(r+1)Nr+1=VV−(V−1∗N1)=VN1
又因为
P
0
∗
=
c
o
u
n
t
0
∗
V
\mathbf{P_0^*}=\frac{\mathbf{count_0^*}}{V}
P0∗=Vcount0∗
所以
c
o
u
n
t
0
∗
=
N
1
\mathbf{count_0^*}=N_1
count0∗=N1
即“用X’中出现1次的样本的种数代替X’中出现0次的样本的次数”
P
1
∗
=
c
o
u
n
t
1
∗
V
=
(
1
+
1
)
N
2
N
1
V
\mathbf{P_1^*}=\frac{\mathbf{count_1^*}}{V}=\frac{(1+1)\frac{N_2}{N_1}}{V}
P1∗=Vcount1∗=V(1+1)N1N2
那这道钓鱼的题举例子,第一问
P
1
∗
(
鲟鱼
)
(
1
+
1
)
N
2
N
1
V
=
(
1
+
1
)
2
3
10
=
0.1333
\mathbf{P_1^*(鲟鱼)}\frac{(1+1)\frac{N_2}{N_1}}{V}=\frac{(1+1)\frac{2}{3}}{10}=0.1333
P1∗(鲟鱼)V(1+1)N1N2=10(1+1)32=0.1333
第2问,没出现的概率为
P
0
∗
=
N
1
V
=
3
10
=
0.3
\mathbf{P_0^*}=\frac{N_1}{V}=\frac{3}{10}=0.3
P0∗=VN1=103=0.3
同样的,这个平滑方式也有弊端,首先每一个r都依赖于r+1,但实际情况中r不一定是连续的,这里选用的方法是找到一个线性拟合函数来补充,又称Simple Good-Turing,函数是
N
r
=
a
+
b
log
(
r
)
\mathbf{N_r}=a+b\log(r)
Nr=a+blog(r)
当然实际使用中,对于r>0的也不是全都要做Good-Turing处理,在NGram的频率足够大的时候(>gtmax),尤其计算的概率是一个可信的结果,即观测概率近似于自然概率,所以不需要处理。对于r>0但也没那么大的时候,才做处理,折掉一部分概率给r=0的。看来到哪最难的都是中产阶级啊。所以最终Good-Turing应该是
P
(
w
i
∣
w
i
−
1
,
w
i
−
2
)
=
{
P
M
L
E
,
c
o
u
n
t
(
w
i
−
2
,
w
i
−
1
,
w
i
)
≥
g
t
m
a
x
c
o
u
n
t
r
∗
(
w
i
−
2
,
w
i
−
1
,
w
i
)
c
o
u
n
t
(
w
i
−
2
,
w
i
−
1
,
w
i
)
−
A
1
−
A
∗
P
M
L
E
,
g
t
m
a
x
>
c
o
u
n
t
(
w
i
−
2
,
w
i
−
1
,
w
i
)
≥
1
P
0
∗
,
c
o
u
n
t
(
w
i
−
2
,
w
i
−
1
,
w
i
)
=
0
\mathbf{P{(w_{i}|w_{i-1},w_{i-2})}}=\left\{ \begin{aligned} &\mathbf{P_{MLE}}&&,count(w_{i-2},w_{i-1},w_{i})\ge{gtmax} \\ &\frac{\frac{count_r^*(w_{i-2},w_{i-1},w_{i})}{count(w_{i-2},w_{i-1},w_{i})}-A}{1-A}*\mathbf{P_{MLE}}&&,gtmax>count(w_{i-2},w_{i-1},w_{i})\ge{1} \\ &\mathbf{P_0^*}&&,count(w_{i-2},w_{i-1},w_{i})=0 \end{aligned} \right.
P(wi∣wi−1,wi−2)=⎩
⎨
⎧PMLE1−Acount(wi−2,wi−1,wi)countr∗(wi−2,wi−1,wi)−A∗PMLEP0∗,count(wi−2,wi−1,wi)≥gtmax,gtmax>count(wi−2,wi−1,wi)≥1,count(wi−2,wi−1,wi)=0
其中的A是
A
=
(
g
t
m
a
x
+
1
)
N
g
t
m
a
x
+
1
N
1
\mathbf{A}=(gtmax+1)\frac{N_{gtmax+1}}{N_1}
A=(gtmax+1)N1Ngtmax+1
这个gtmax是一个可控的参数,一般取7 。
Backoff (Katz)
不管是Add-one,还是Good Turing平滑技术,对于未出现的NGram都"一视同仁"的处理,这样难免存在不合理。虽然实现了“因为存在’我爱吃XX‘所以不能否认’我爱吃比萨‘的存在’”,但把所有没出现的“我爱吃XX”的概率视为一样,显然是有瑕疵的,同样都是没出现的,“我爱吃比萨”的概率怎么的也得比“我爱吃老八晓憨包”高啊。
回退补偿,其思想就是用低阶NGram的概率推测高阶NGram的概率。因为在大规模统计中出现1Gram中未收录的情况(出现语料中从未出现的字或词)很少见,2GRam又是由1Gram构成的,以此类推我们有机会“利用低元已出现的NGram观测概率对高元未出现NGram的自然概率估算”。
估算方式是:
- 将NGram的第一个Gram去掉构成低阶的“(N-1)Gram”
- 将NGram的最后一个Gram去掉构成“前缀”
- 计算“前缀”的回退权重BoW与“(N-1)Gram”的概率乘积
公式表示,其在r>0时的处理方式和Good-Turing一致,但在r=0时
P
k
a
t
z
(
w
i
∣
w
i
−
n
+
1
,
.
.
.
,
w
i
−
1
)
=
B
o
W
(
w
i
−
n
+
1
,
.
.
.
,
w
i
−
1
)
∗
P
(
w
i
∣
w
i
−
n
+
2
,
.
.
.
,
w
i
−
1
)
\mathbf{P_{katz}{(w_{i}|w_{i-n+1},...,w_{i-1})}}=BoW(w_{i-n+1},...,w_{i-1})*P(w_{i}|w_{i-n+2},...,w_{i-1})
Pkatz(wi∣wi−n+1,...,wi−1)=BoW(wi−n+1,...,wi−1)∗P(wi∣wi−n+2,...,wi−1)
以3Gram举例就是
P
k
a
t
z
(
w
i
∣
w
i
−
2
,
w
i
−
1
)
=
B
o
W
(
w
i
−
2
,
w
i
−
1
)
∗
P
(
w
i
∣
w
i
−
1
)
\mathbf{P_{katz}{(w_{i}|w_{i-2},w_{i-1})}}=BoW(w_{i-2},w_{i-1})*P(w_{i}|w_{i-1})
Pkatz(wi∣wi−2,wi−1)=BoW(wi−2,wi−1)∗P(wi∣wi−1)
那么BoW究竟是怎么计算的呢,接下介绍。记自然语料中(客观的环境X)w_i的取值——即以“前缀”开头的所有NGram的最有一个Gram,为w_x。那么"全部以前缀开头的NGram的自然概率(P_katz)和为1":
∑
w
x
P
k
a
t
z
(
w
x
∣
w
i
−
2
,
w
i
−
1
)
=
1
(1)
\sum_{w_x}{P_{katz}(w_x|w_{i-2},w_{i-1})}=1\tag{1}
wx∑Pkatz(wx∣wi−2,wi−1)=1(1)
再记观测预料中,所有使得r>0的w_x为w_pos,所有使得r=0的w_x为w_nag:
- 已知语料里出现的一定是w_pos
- 但w_pos不一定全出现在已知语料里
- w_nag一定不在已知语料里
图
根据上(1)式:
∑ w p o s P k a t z ( w p o s ∣ w i − 2 , w i − 1 ) + ∑ w n a g P k a t z ( w n a g ∣ w i − 2 , w i − 1 ) = 1 ∑ w p o s P ( w p o s ∣ w i − 2 , w i − 1 ) + ∑ w n a g B o W ( w i − 2 , w i − 1 ) ∗ P ( w n a g ∣ w i − 1 ) = 1 \begin{aligned} \sum_{w_{pos}}{P_{katz}(w_{pos}|w_{i-2},w_{i-1})}+\sum_{w_{nag}}{P_{katz}(w_{nag}|w_{i-2},w_{i-1})}&=1 \\ \sum_{w_{pos}}{P(w_{pos}|w_{i-2},w_{i-1})}+\sum_{w_{nag}}{BoW(w_{i-2},w_{i-1})*P(w_{nag}|w_{i-1})}&=1 \end{aligned} wpos∑Pkatz(wpos∣wi−2,wi−1)+wnag∑Pkatz(wnag∣wi−2,wi−1)wpos∑P(wpos∣wi−2,wi−1)+wnag∑BoW(wi−2,wi−1)∗P(wnag∣wi−1)=1=1
提出BoW并移项,得到
B
o
W
(
w
i
−
2
,
w
i
−
1
)
=
1
−
∑
w
p
o
s
P
(
w
p
o
s
∣
w
i
−
2
,
w
i
−
1
)
∑
w
n
a
g
P
(
w
n
a
g
∣
w
i
−
1
)
=
1
−
∑
w
p
o
s
P
(
w
p
o
s
∣
w
i
−
2
,
w
i
−
1
)
1
−
∑
w
p
o
s
P
(
w
p
o
s
∣
w
i
−
1
)
\begin{aligned} \mathbf{BoW}(w_{i-2},w_{i-1})&=\frac{1-\sum_{w_{pos}}{P(w_{pos}|w_{i-2},w_{i-1})}}{\sum_{w_{nag}}{P(w_{nag}|w_{i-1})}} \\ &=\frac{1-\sum_{w_{pos}}{P(w_{pos}|w_{i-2},w_{i-1})}}{1-\sum_{w_{pos}}{P(w_{pos}|w_{i-1})}} \end{aligned}
BoW(wi−2,wi−1)=∑wnagP(wnag∣wi−1)1−∑wposP(wpos∣wi−2,wi−1)=1−∑wposP(wpos∣wi−1)1−∑wposP(wpos∣wi−2,wi−1)
Interpolation
插值平滑技术。在上面的介绍中,回退只有在“灵【yang】感【ben】不多”的情况下才会“借【qiu】鉴【zhu】”更短的上文,插值则不一样,不管多少他每次都会综合多个层次,这对于数据量少时减少过拟合很有用。
还是以3Gram为例描述公式的最简单形式:
P
i
n
t
(
w
i
∣
w
i
−
2
,
w
i
−
1
)
=
λ
1
P
(
w
i
)
+
λ
2
P
(
w
i
∣
w
i
−
1
)
+
λ
3
P
(
w
i
∣
w
i
−
2
,
w
i
−
1
)
λ
1
+
λ
2
λ
3
=
1
\mathbf{P_{int}}{(w_{i}|w_{i-2},w_{i-1})}=\lambda_{1}\mathbf{P}(w_{i})+\lambda_{2}\mathbf{P}(w_{i}|w_{i-1})+\lambda_{3}\mathbf{P}(w_{i}|w_{i-2},w_{i-1}) \\ \lambda_{1}+\lambda_{2}\lambda_{3}=1
Pint(wi∣wi−2,wi−1)=λ1P(wi)+λ2P(wi∣wi−1)+λ3P(wi∣wi−2,wi−1)λ1+λ2λ3=1
此时的λi是个常数,可以通过经验或者一些算法来确定。不过这里又犯了“一概而论”的错误——常数,意味着不管其他阶NGram估计是否可靠,都会以同样的权重加入计算。所以,进化这个“最简单形式”的方法就是让λi成为一个历史函数
λ
i
(
w
i
−
2
,
w
i
−
1
,
w
i
)
\lambda_{i}(w_{i-2},w_{i-1},w_{i})
λi(wi−2,wi−1,wi)
小结
前面已经介绍了很多平滑思想,这些思想一步一步递进:
- 暴力但直接的Add-One,诠释了我们的目的就是“劫富济贫”
- 首先考虑高低阶关系的Good-Turing,为后面的方法提供了思路基础
- 引入低阶来解决问题的Back-off
- 一视同仁的插值
他们在解决一些问题的同时提出新的问题,再实际应用中前两个方法更多是提供“精神支持”,后两个 则是“上阵父子兵”。
计数打折(Discounting)
结合上面的平滑思想,在实际使用中我们往往“从根本上解决问题”——概率计算离不开计数,对概率下砍刀不如直接对计数打折。
计数打折思想没有脱离平滑,对于出现次数比较多的NGram计数我们其实已经得到了一个对这个Gram相对比较好的估计了,那么当我们从这个计数值中减去一个较小的Discounting后应该影响不大,而减掉的计数可以加到那些未出现的NGram上。
Absolute Discounting
该方法由Church & Gale 设计,思路灵感来源于一个统计实验。实验准备了两个2200W词的语料库,一个叫训练库,一个叫留存库,先统计出现在训练库中次数为r次的2Gram,再统计这些2Gram在留存库中出现的次数并取平均值。
训练库中出现次数 | 留存库中出现次数 | 差值 |
---|---|---|
0 | 0.0000270 | | |
1 | 0.448 | 0.552 |
2 | 1.25 | 0.75 |
3 | 2.24 | 0.76 |
4 | 3.23 | 0.77 |
5 | 4.21 | 0.79 |
6 | 5.23 | 0.77 |
7 | 6.21 | 0.79 |
8 | 7.21 | 0.79 |
9 | 8.26 | 0.74 |
对比发现,除了r=0和r=1以外,剩下的差值都约为0.75 。于是他们便提出,在常规NGram概率分子上减去一个折扣系数d:
P
A
b
s
D
i
s
(
w
i
∣
w
i
−
1
)
=
c
o
u
n
t
(
w
i
−
1
,
w
i
)
−
d
c
o
u
n
t
(
w
i
−
1
)
+
λ
(
w
i
−
1
)
P
(
w
i
)
\mathbf{P_{AbsDis}}(w_{i}|w_{i-1})=\frac{\mathbf{count}(w_{i-1},w_{i})-d}{\mathbf{count}(w_{i-1})}+\lambda(w_{i-1})\mathbf{P}(w_{i})
PAbsDis(wi∣wi−1)=count(wi−1)count(wi−1,wi)−d+λ(wi−1)P(wi)
这个方法像Good-Turing一样使用到了出现次数,也像回退一样加了一个上文概率与权重的乘积,而这个权重不是常数,而是像插值一样和上下文有关的。
Kneser-Ney Smoothing
如何确定Absolute Discounting中的d和λ,目前最有效的就是Kneser-Ney平滑方法。
他定义d的确是一个常数,不过是一个和NGram阶数、NGram出现次数有关的函数的结果,记作
d
(
n
,
r
)
或
c
o
u
n
t
d
i
s
(
n
,
r
)
d(n,r) 或count_{dis}(n,r)
d(n,r)或countdis(n,r)
而λ是一个和d有关的函数
λ
(
w
i
−
n
+
1
,
.
.
.
,
w
i
−
1
)
=
d
c
o
u
n
t
(
w
i
−
n
+
1
,
.
.
.
,
w
i
−
1
)
∗
c
o
u
n
t
(
w
p
o
s
:
c
o
u
n
t
(
w
i
−
n
+
1
,
.
.
.
,
w
i
−
1
,
w
p
o
s
)
)
=
∑
r
=
1
c
o
u
n
t
d
i
s
(
n
,
r
)
∗
c
o
u
n
t
(
w
p
o
s
:
c
o
u
n
t
a
d
j
(
w
i
−
n
+
1
,
.
.
.
,
w
i
−
1
,
w
p
o
s
)
=
r
)
∑
w
p
o
s
c
o
u
n
t
a
d
j
(
w
i
−
n
+
1
,
.
.
.
,
w
i
−
1
,
w
p
o
s
)
\begin{aligned} \lambda(w_{i-n+1},...,w_{i-1})&=\frac{d}{count(w_{i-n+1},...,w_{i-1})}*count(w_{pos}:count(w_{i-n+1},...,w_{i-1},w_{pos})) \\ &=\frac{\sum_{r=1}count_{dis}(n,r)*count(w_{pos}:count_{adj}(w_{i-n+1},...,w_{i-1},w_{pos})=r)}{\sum_{w_{pos}}count_{adj}(w_{i-n+1},...,w_{i-1},w_{pos})} \end{aligned}
λ(wi−n+1,...,wi−1)=count(wi−n+1,...,wi−1)d∗count(wpos:count(wi−n+1,...,wi−1,wpos))=∑wposcountadj(wi−n+1,...,wi−1,wpos)∑r=1countdis(n,r)∗count(wpos:countadj(wi−n+1,...,wi−1,wpos)=r)