统计语言模型
统计语言模型的意义是通过计算一个语句出现的概率来判断它合乎语法的可能性,记一个序列
S
=
(
w
1
,
w
2
,
⋯
,
w
n
)
S = (w_1,w_2,\cdots, w_n)
S=(w1,w2,⋯,wn),那么:
P
(
S
)
=
P
(
w
1
,
w
2
,
⋯
,
w
n
)
=
P
(
w
1
)
⋅
P
(
w
2
∣
w
1
)
⋅
P
(
w
3
∣
w
1
,
w
2
)
⋯
P
(
w
n
∣
w
1
,
w
2
,
⋯
,
w
n
−
1
)
\begin{aligned} P(S) &= P(w_1,w_2,\cdots, w_n)\\ &= P(w_1)\cdot P(w_2|w_1) \cdot P(w_3|w_1,w_2) \cdots P(w_n|w_1,w_2,\cdots, w_{n-1}) \end{aligned}
P(S)=P(w1,w2,⋯,wn)=P(w1)⋅P(w2∣w1)⋅P(w3∣w1,w2)⋯P(wn∣w1,w2,⋯,wn−1)
但是实际使用中P(w_n|w_1,w_2,\cdots, w_{n-1})的计算复杂度太高,而且一般越远的词对当前词的影响越小,所以为了简化模型,我们一般使用马尔科夫假设:任一词
w
i
w_i
wi出现的概率只与它前面的一个词
w
i
−
1
w_{i-1}
wi−1有关:
P
(
S
)
=
P
(
w
1
)
⋅
P
(
w
1
∣
w
2
)
⋯
P
(
w
n
∣
w
n
−
1
)
P(S) = P(w_1) \cdot P(w_1|w_2) \cdots P(w_n|w_{n-1})
P(S)=P(w1)⋅P(w1∣w2)⋯P(wn∣wn−1)
上述公式对应的语言模型叫作二元模型,使用的是一阶马尔科夫假设。根据大数定律,只要统计量足够,上式就可以通过统计频数计算:
P
(
w
i
∣
w
i
−
1
)
=
P
(
w
i
−
1
,
w
i
)
P
(
w
i
−
1
)
=
#
(
w
i
−
1
,
w
i
)
#
(
w
i
−
1
)
P(w_i|w_{i-1}) = \frac{P(w_{i-1},w_i)}{P(w_{i-1})} = \frac{\#(w_{i-1},w_i)}{\#(w_{i-1})}
P(wi∣wi−1)=P(wi−1)P(wi−1,wi)=#(wi−1)#(wi−1,wi)
实际当时,常用的除了上述二元模型还有三元模型:
P
(
S
)
=
P
(
w
1
)
⋅
P
(
w
1
∣
w
2
)
⋯
P
(
w
n
∣
w
n
−
2
,
w
n
−
1
)
P(S) = P(w_1) \cdot P(w_1|w_2) \cdots P(w_n|w_{n-2},w_{n-1})
P(S)=P(w1)⋅P(w1∣w2)⋯P(wn∣wn−2,wn−1)
因为N元模型的空间复杂度是 O ( ∣ V ∣ N ) O(|V|^N) O(∣V∣N),其中 ∣ V ∣ |V| ∣V∣是词典大小,一般有几万到几十万;而使用N元模型的时间复杂度是 O ( ∣ V ∣ N − 1 ) O(|V|^{N-1}) O(∣V∣N−1),因此N不能特别大。而且当N从1到2,再从2到3,模型的效果上升明显;但再往后,效果提升就不那么明显了,但资源的耗费却增加得非常快,所以一般很少使用四元以上的模型。
零概率问题和平滑方法
现在假如我们要训练一个三元中文模型,汉语词汇量大约是20万,那么这个三元模型将会有 ∣ V ∣ 3 = 8 × 1 0 15 |V|^3 = 8 \times 10^{15} ∣V∣3=8×1015量级的参数。而假如从互联网上刨去垃圾,有100亿个有意义的中文网页,每个网页平均有1000个词。依然也只有 1 0 13 10^{13} 1013量级的训练数据。因此,会有很多词的统计词频直接是零,但这并不意味着这些词出现的概率就真的是零。这种情况称之为“模型不平滑”,也叫零概率问题。解决上述问题常用的几种方法有:
拉普拉斯平滑
Add‐One 平滑
假定语料库的大小为N,词典的大小为V:
P
(
w
i
)
=
#
(
w
i
)
+
1
N
+
V
P
(
w
i
∣
w
i
−
1
)
=
#
(
w
i
,
w
i
−
1
)
+
1
#
(
w
i
−
1
)
+
V
P
(
w
i
∣
w
i
−
1
,
w
i
−
2
)
=
#
(
w
i
,
w
i
−
1
,
w
i
−
2
)
+
1
#
(
w
i
−
1
,
w
i
−
2
)
+
C
V
2
\begin{aligned} P(w_i) &= \frac{\#(w_i)+1}{N+V}\\ P(w_i|w_{i-1}) &= \frac{\#(w_i,w_{i-1})+1}{\#(w_{i-1})+V}\\ P(w_{i}|w_{i-1},w_{i-2}) &= \frac{\#(w_i,w_{i-1},w_{i-2})+1}{\#(w_{i-1},w_{i-2})+C_{V}^2} \end{aligned}
P(wi)P(wi∣wi−1)P(wi∣wi−1,wi−2)=N+V#(wi)+1=#(wi−1)+V#(wi,wi−1)+1=#(wi−1,wi−2)+CV2#(wi,wi−1,wi−2)+1
Add‐K 平滑
P
(
w
i
)
=
#
(
w
i
)
+
K
N
+
K
V
P
(
w
i
∣
w
i
−
1
)
=
#
(
w
i
,
w
i
−
1
)
+
K
#
(
w
i
−
1
)
+
K
V
P
(
w
i
∣
w
i
−
1
,
w
i
−
2
)
=
#
(
w
i
,
w
i
−
1
,
w
i
−
2
)
+
K
#
(
w
i
−
1
,
w
i
−
2
)
+
K
C
V
2
\begin{aligned} P(w_i) &= \frac{\#(w_i)+K}{N+KV}\\ P(w_i|w_{i-1}) &= \frac{\#(w_i,w_{i-1})+K}{\#(w_{i-1})+KV}\\ P(w_{i}|w_{i-1},w_{i-2}) &= \frac{\#(w_i,w_{i-1},w_{i-2})+K}{\#(w_{i-1},w_{i-2})+KC_{V}^2} \end{aligned}
P(wi)P(wi∣wi−1)P(wi∣wi−1,wi−2)=N+KV#(wi)+K=#(wi−1)+KV#(wi,wi−1)+K=#(wi−1,wi−2)+KCV2#(wi,wi−1,wi−2)+K
其中
K
K
K是可以使用优化的方法来寻找的参数。
插值平滑
上述拉普拉斯平滑的一个问题是:只要是未见词,估算的概率都是一样的(特别是对于高阶估计,更容易出现未见词),但这其实是不太合理的,因为即使是未见词,概率也会有高低之分。所以插值平滑的原理就是利用低阶统计量做插值,这样的话即使一些词的高阶统计量为0,也可以用低阶统计量去补充:
P
(
w
i
)
=
λ
P
^
(
w
i
)
+
(
1
−
λ
)
1
N
P
(
w
i
∣
w
i
−
1
)
=
λ
P
^
(
w
i
∣
w
i
−
1
)
+
(
1
−
λ
)
P
(
w
i
)
P
(
w
i
∣
w
i
−
1
,
w
i
−
2
)
=
λ
1
P
^
(
w
i
∣
w
i
−
1
,
w
i
−
2
)
+
λ
2
P
(
w
i
∣
w
i
−
1
)
+
λ
3
P
(
w
i
)
,
λ
1
+
λ
2
+
λ
3
=
1
\begin{aligned} &P(w_i) = \lambda \hat{P}(w_i) + (1-\lambda) \frac{1}{N}\\ &P(w_i|w_{i-1}) = \lambda \hat{P}(w_i|w_{i-1}) + (1-\lambda) P(w_i)\\ &P(w_i|w_{i-1},w_{i-2}) = \lambda_1 \hat{P}(w_i|w_{i-1},w_{i-2}) + \lambda_2 P(w_i|w_{i-1}) + \lambda_3P(w_i) , \quad \lambda_1 + \lambda_2 + \lambda_3 =1 \end{aligned}
P(wi)=λP^(wi)+(1−λ)N1P(wi∣wi−1)=λP^(wi∣wi−1)+(1−λ)P(wi)P(wi∣wi−1,wi−2)=λ1P^(wi∣wi−1,wi−2)+λ2P(wi∣wi−1)+λ3P(wi),λ1+λ2+λ3=1
其中
P
^
表
示
概
率
值
直
接
由
频
度
估
计
\hat{P}表示概率值直接由频度估计
P^表示概率值直接由频度估计。
古德-图灵估计
古德-图灵估计的原理是:
- 对于可靠的统计数据,我们选择相信
- 对于不可信的统计数据,我们对它打一定折扣
- 对于未看见的数据,把上述折扣出来的一小部分概率赋予给它
假定在语料库中出现r次的词有
N
r
N_r
Nr个,特别的,未出现的词数量为
N
0
N_0
N0那么有:
N
=
∑
r
r
N
r
N = \sum_r rN_r
N=r∑rNr
出现
r
r
r次的词的相对频度就是
r
N
\frac{r}{N}
Nr。当
r
r
r比较大的时候,我们认为此时的统计数据是可靠的,那么就可以以这个相对频度作为这些词的概率估计。
但是当
r
r
r比较小时,我们认为统计数据不可靠,也就是说出现
r
r
r次的那些词在计算它们的概率时要使用一个小一点的数,记为
d
r
d_r
dr:
d
r
=
(
r
+
1
)
⋅
N
r
+
1
/
N
r
d_r = (r+1) \cdot N_{r+1}/N_r
dr=(r+1)⋅Nr+1/Nr
那么显然有
∑
r
d
r
⋅
N
r
=
N
\sum_r d_r\cdot N_r = N
∑rdr⋅Nr=N。一般来说,语料库中出现r次的词数量
N
r
N_r
Nr与
r
r
r满足如下关系:
可以看出,当
r
r
r比较小时,
N
r
N_r
Nr下降得很快,满足
N
r
+
1
N
r
<
r
r
+
1
\frac{N_{r+1}}{N_r} < \frac{r}{r+1}
NrNr+1<r+1r,因此
d
r
<
r
d_r < r
dr<r,而
d
0
>
0
d_0 > 0
d0>0。这样就给未见词赋予了一个很小的非零值,从而解决了零概率问题。
Katz平滑
Katz平滑利用了古德-图灵估计对频数小于阈值的概率进行削减,然后削减出来的总量,按照频数为零的项的低阶gram的频度来分配:
P
(
w
i
)
=
{
r
N
i
f
r
≥
T
d
r
N
i
f
0
<
r
<
T
remain
N
i
f
r
=
0
P(w_i)=\left\{ \begin{aligned} & \frac{r}{N} & if \ r \geq T \\ &\frac{d_r}{ N} & \qquad if \ 0 < r < T \\ &\frac{\text{remain}}{N} & if \ r=0 \end{aligned} \right.
P(wi)=⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧NrNdrNremainif r≥Tif 0<r<Tif r=0
其中
remain
=
1
−
∑
w
i
s
e
e
n
P
(
w
i
)
\text{remain} = 1- \sum_{wi \ seen}P(w_i)
remain=1−∑wi seenP(wi)。
对于二元模型,同样有:
P
(
w
i
∣
w
i
−
1
)
=
{
r
#
(
w
i
−
1
)
i
f
r
≥
T
d
r
#
(
w
i
−
1
)
i
f
0
<
r
<
T
remain
∑
w
i
u
n
s
e
e
n
f
(
w
i
)
f
(
w
i
)
i
f
r
=
0
P(w_i|w_{i-1})=\left\{ \begin{aligned} & \frac{r}{\#(w_{i-1})} & if \ r \geq T \\ &\frac{d_r}{\#(w_{i-1})} & \qquad if \ 0 < r < T \\ &\frac{\text{remain}}{\sum_{w_i \ unseen}f(w_i)}f(w_i) & if \ r=0 \end{aligned} \right.
P(wi∣wi−1)=⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧#(wi−1)r#(wi−1)dr∑wi unseenf(wi)remainf(wi)if r≥Tif 0<r<Tif r=0
其中
remain
=
1
−
∑
w
i
s
e
e
n
P
(
w
i
∣
w
i
−
1
)
\text{remain} = 1- \sum_{wi \ seen}P(w_i|w_{i-1})
remain=1−∑wi seenP(wi∣wi−1),
f
(
w
i
)
f(w_i)
f(wi) 是频度。上面第二项的计算方法是:
- 最终折扣量与Good-Turing估计预测的减值量成正比例
- 全局二元语法分布中被折扣的计数总量等于根据Good-Turing估计应该分配给次数为零的二元语法的总数
记折扣量为
μ
r
\mu_r
μr,所以有公式:
1
−
μ
r
=
ρ
(
1
−
(
r
+
1
)
⋅
N
r
+
1
r
⋅
N
r
)
1 - \mu_r = \rho (1- \frac{(r+1)\cdot N_{r+1}}{r\cdot N_r})
1−μr=ρ(1−r⋅Nr(r+1)⋅Nr+1)
又因为Good-Turing估计分配给次数为零的二元语法的总数为
N
1
N_1
N1(why?):
所以有
∑
k
=
1
T
N
k
(
1
−
μ
r
)
r
=
N
1
\sum_{k=1}^T N_k (1-\mu_r) r = N_1
k=1∑TNk(1−μr)r=N1
上式的解即为:
μ
r
=
(
r
+
1
)
⋅
N
r
+
1
r
⋅
N
−
(
T
+
1
)
N
T
+
1
N
1
1
−
(
T
+
1
)
N
T
+
1
N
1
\mu_r = \frac{\frac{(r+1)\cdot N_{r+1}}{r\cdot N} - \frac{(T+1)N_{T+1}}{N_1}}{1 - \frac{(T+1)N_{T+1}}{N_1}}
μr=1−N1(T+1)NT+1r⋅N(r+1)⋅Nr+1−N1(T+1)NT+1
因此
d
r
=
μ
r
⋅
r
=
(
r
+
1
)
⋅
N
r
+
1
N
−
r
⋅
(
T
+
1
)
N
T
+
1
N
1
1
−
(
T
+
1
)
N
T
+
1
N
1
d_r = \mu_r \cdot r = \frac{\frac{(r+1)\cdot N_{r+1}}{ N} - r\cdot \frac{(T+1)N_{T+1}}{N_1}}{1 - \frac{(T+1)N_{T+1}}{N_1}}
dr=μr⋅r=1−N1(T+1)NT+1N(r+1)⋅Nr+1−r⋅N1(T+1)NT+1
困惑度(Perplexity)
困惑度 是语言模型的一个衡量标准。因为单纯序列的似然概率是一个难以理解、难以比较的数字。 毕竟,较短的序列比较长的序列更有可能出现, 因此评估模型产生长篇巨著《战争与和平》的可能性会比产生中篇小说《小王子》可能性要小得多。
一个好的语言模型应该能让我们准确地预测下一个词元。 所以我们可以通过一个序列中 所有的 n 个词元的交叉熵损失的平均值 来衡量:
1 n − ∑ t = 1 n log P ( x t ∣ x 1 , ⋯ , x t − 1 ) \frac{1}{n} - \sum_{t=1}^n \text{log }P(x_t|x_1, \cdots, x_{t-1}) n1−t=1∑nlog P(xt∣x1,⋯,xt−1)
其中 P P P 由语言模型给出, x t x_t xt 是在时间步 t t t 从该序列中观察到的实际词元。 这使得不同长度的文档的性能具有了可比性。 由于历史原因,自然语言处理的科学家更喜欢使用一个叫做困惑度(perplexity)的量。 简而言之,它是上式的指数:
exp ( 1 n − ∑ t = 1 n log P ( x t ∣ x 1 , ⋯ , x t − 1 ) ) \text{exp}\Big(\frac{1}{n} - \sum_{t=1}^n \text{log }P(x_t|x_1, \cdots, x_{t-1})\Big) exp(n1−t=1∑nlog P(xt∣x1,⋯,xt−1))
如果是使用神经网络来编码语言模型,那么神经网络的输出loss的均值的指数值,即为一个句子的困惑度。
- 在最好的情况下,模型总是完美地估计标签词元的概率为1。 在这种情况下,模型的困惑度为1。
- 在最坏的情况下,模型总是预测标签词元的概率为0。 在这种情况下,困惑度是正无穷大。
Reference:
数学之美,吴军
自然语言处理综论,冯志伟
数据平滑技术总结
统计语言模型之平滑方法详解