语言模型概述
语言模型是一个用于判断句子出现概率的数学模型。假设我们有一个句子
s
=
(
w
1
,
w
2
,
.
.
.
,
w
m
)
s=(w_1,w_2,...,w_m)
s=(w1,w2,...,wm)。其中
w
i
w_i
wi为句子中的第i个词语。根据古典概型,那么语言模型可表示为:
P
(
s
)
=
人
类
说
过
的
所
有
句
子
中
s
的
个
数
人
类
说
过
的
所
有
句
子
个
数
P(s) = \frac{人类说过的所有句子中s的个数}{人类说过的所有句子个数}
P(s)=人类说过的所有句子个数人类说过的所有句子中s的个数
统计语言模型
显然,上述语言模型公式中,分子和分母我们都不可能统计得到。但是可以换一种思路去计算。假设把每个词当成一个随机变量。这样,句子出现的概率分布则变成了这些词出现概率的联合概率分布。即
P
(
s
)
=
P
(
w
1
,
w
2
,
.
.
.
,
w
m
)
P(s)=P(w_1,w_2,...,w_m)
P(s)=P(w1,w2,...,wm)
根据乘法公式
P
(
w
1
,
w
2
,
.
.
.
,
w
m
)
=
P
(
w
1
)
P
(
w
2
.
.
.
w
m
∣
w
1
)
=
P
(
w
1
)
P
(
w
2
∣
w
1
)
P
(
w
3
.
.
.
w
m
∣
w
1
w
2
)
=
P
(
w
1
)
P
(
w
2
∣
w
1
)
P
(
w
3
∣
w
1
w
2
)
P
(
w
4
.
.
.
w
m
∣
w
1
w
2
w
3
)
.
.
.
=
p
(
w
1
)
∏
i
=
2
m
p
(
w
i
∣
w
1
w
2
.
.
.
w
i
−
1
)
\begin{aligned} P(w_1,w_2,...,w_m)&=P(w_1)P(w_2...w_m|w_1) \\ &= P(w_1)P(w_2|w_1)P(w_3...w_m|w_1w_2) \\ &= P(w_1)P(w_2|w_1)P(w_3|w_1w_2)P(w_4...w_m|w_1w_2w_3) \\ & ... \\ &= p(w_1) \prod_{i=2}^{m}p(w_i|w_1w_2...w_{i-1}) \end{aligned}
P(w1,w2,...,wm)=P(w1)P(w2...wm∣w1)=P(w1)P(w2∣w1)P(w3...wm∣w1w2)=P(w1)P(w2∣w1)P(w3∣w1w2)P(w4...wm∣w1w2w3)...=p(w1)i=2∏mp(wi∣w1w2...wi−1)
实际上精确计算上式也是不实际的。因为 p ( w 1 ) p(w_1) p(w1)和 p ( w i ∣ w 1 w 2 . . . w i − 1 ) p(w_i|w_1w_2...w_{i-1}) p(wi∣w1w2...wi−1)理论上也与人类历史上说过的词相关。但是我们通常会通过统计语料里面的词出现的频率来近似估计。这就是统计语言模型。即使用统计的方法计算 P ( s ) P(s) P(s)的过程。
模型简化
不难发现,对统计语言模型的计算需要计算大量条件概率
p
(
w
i
∣
w
1
w
2
.
.
.
w
i
−
1
)
p(w_i|w_1w_2...w_{i-1})
p(wi∣w1w2...wi−1)。它的含义是在前i-1个词出现的情况下,第i个词出现的概率
。 根据条件概率计算公式有:
p
(
w
i
∣
w
1
w
2
.
.
.
w
i
−
1
)
=
p
(
w
1
w
2
.
.
.
w
i
)
/
p
(
w
1
w
2
.
.
.
w
i
−
1
)
p(w_i|w_1w_2...w_{i-1})=p(w_1w_2...w_{i}) /p(w_1w_2...w_{i-1})
p(wi∣w1w2...wi−1)=p(w1w2...wi)/p(w1w2...wi−1) 。当
i
i
i比较大的时候,无论是
w
1
w
2
.
.
.
w
i
w_1w_2...w_{i}
w1w2...wi还是
w
1
w
2
.
.
.
w
i
−
1
w_1w_2...w_{i-1}
w1w2...wi−1在语料集上都很少出现甚至不出现。所以很多条件概率的值为0。
例如计算 p ( 在 ∣ 种 果 科 雪 园 ) p(在|种果科雪园) p(在∣种果科雪园)。也许整个语料集中"种果科雪园"从未出现。所以结果为0。这就是数据稀疏问题。
如果把每一个概率 p ( w 1 w 2 . . . w i ) p(w_1w_2...w_{i}) p(w1w2...wi)当作一个模型参数。那么,完整的条件概率计算参数数量将很多。如果只考虑10000个词,即词典大小为10000,那么考虑最大长度 m = 20 m=20 m=20的句子。则参数数量为 1000 0 20 = 1 0 80 10000^{20} =10^{80} 1000020=1080。如果一个参数使用4字节存储。光存储参数就得使用 4 × 1 0 68 4 \times 10^{68} 4×1068T。实际上完整模型根本无法使用了。因此有必要对原模型进行简化。
一般地,我们会假设第 i i i个词出现的概率,只与其前 n − 1 n-1 n−1个词语相关。n是一个根据实际需要而设的超参数。这样就为模型引入了独立性假设。这个假设并不合理,但是为了简化模型也只能先这么做。同时为了保证条件概率 i = 1 i=1 i=1时有意义,同时又为了保证句子内所有字符串的概率和为1。即 ∑ s p ( x ) = 1 \sum_sp(x)=1 ∑sp(x)=1。可在句子首尾增加两个标志。分别是:
- BOS
- EOS
BOS 表示 begin of sentence。EOS 表示 end of sentence。那么句子可被重新表达为
s
=
(
<
B
O
S
>
,
w
1
,
w
2
,
.
.
.
,
w
m
,
<
E
O
S
>
)
s=(<BOS>, w_1,w_2,...,w_m,<EOS>)
s=(<BOS>,w1,w2,...,wm,<EOS>)则原语言模型的
P
(
s
)
P(s)
P(s)可重新写为:
P
(
s
)
=
∏
i
=
1
m
+
1
p
(
w
i
∣
w
i
−
n
+
1
.
.
.
w
i
−
1
)
P(s) = \prod_{i=1}^{m+1}p(w_i|w_{i-n + 1}...w_{i-1})
P(s)=i=1∏m+1p(wi∣wi−n+1...wi−1)
当
i
=
1
i=1
i=1时,会出现
w
0
w_0
w0。即表示<BOS>。注意这里并不会去计算P(<BOS>)。因为P(<BOS>)始终为1。这就是n-gram语言模型也称N元语言模型。但这里加<EOS>只是为了表示句子已经结束。个人理解:如果判断非完整句子的概率,则只要加到m。
为了求取模型参数,可以使用最大似然进行参数估计。过程略复杂,这里空白的地方太小,写不下,略。最后的结果如下:
P
(
w
i
∣
w
i
−
n
+
1
.
.
.
w
i
−
1
)
=
c
(
w
i
−
n
+
1
.
.
.
w
i
)
∑
w
c
(
w
i
−
n
+
1
.
.
.
w
i
−
1
w
)
P(w_i|w_{i-n+1}...w_{i-1}) = \frac{c(w_{i-n+1}...w_i)}{\sum_wc(w_{i-n+1}...w_{i-1}w)}
P(wi∣wi−n+1...wi−1)=∑wc(wi−n+1...wi−1w)c(wi−n+1...wi)
其中 c ( ⋅ ) c(\cdot) c(⋅)函数表示统计词序列在语料集中出现的次数。
我们可以考虑一个二元语言模型,考虑词典大小为10000,考虑最大词序列长度m=20。则参数数量为
1000
0
2
=
1
0
8
10000^2=10^8
100002=108。如果一个参数使用4字节存储,将占用空间为
100
M
100M
100M。之就大大减少了参数数量。同时二元语言模型中词序列
w
i
w
i
−
1
w_iw_{i-1}
wiwi−1在语料集中大量存在, 部分解决了稀疏的问题。
概率平滑
上面提到二无语言模型部分解决了稀疏的问题,是因为如果词典比较大,词典中的非常用词在语料集中可能不出现。也会有很多的数据稀疏。如果词典中的某个词在语料集中没有出现,则 p ( w i w i − 1 ) = 0 p(w_iw_{i-1})=0 p(wiwi−1)=0。计算长序列的句子的概率时,如果包含这个词,也会导致 P ( s ) = ∏ i = 1 m + 1 p ( w i ∣ w i − 1 ) = 0 P(s)=\prod_{i=1}^{m+1}p(w_i|w_{i-1})=0 P(s)=∏i=1m+1p(wi∣wi−1)=0。
为了防止这种零概率的情况,因此要对参数进行平滑操作。
基本约束:
∑
w
i
p
(
w
i
∣
w
1
,
w
2
,
.
.
.
,
w
i
−
1
)
=
1
\sum_{w_i}p(w_i|w_1,w_2,...,w_{i-1})=1
∑wip(wi∣w1,w2,...,wi−1)=1
最经典是就是加1平滑。基本思想是为每种情况的统计值加一。计算过程如下。
p
(
w
i
∣
w
i
−
1
)
=
1
+
c
(
w
i
−
1
w
i
)
∑
w
i
[
1
+
c
(
w
i
−
1
w
i
)
]
=
1
+
c
(
w
i
−
1
w
i
)
∣
V
∣
+
∑
w
i
[
c
(
w
i
−
1
w
i
)
]
\begin{aligned} p(w_i|w_{i-1}) &= \frac{1+c(w_{i-1}w_i)}{\sum_{w_i}[1+c(w_{i-1}w_i)]} \\ &= \frac{1+c(w_{i-1}w_i)}{|V| + \sum_{w_i}[c(w_{i-1}w_i)]} \end{aligned}
p(wi∣wi−1)=∑wi[1+c(wi−1wi)]1+c(wi−1wi)=∣V∣+∑wi[c(wi−1wi)]1+c(wi−1wi)
其中|V|为语料的词汇量,即词典大小。
这种操作实际并没有数学上的解释。仅仅是为了解决零概率问题。
自适应语言模型
研究者还提出了许多新的语言模型。
基于缓存语言模型
这种语言模型主要是考虑了n-gram语言模型简化后缺少历史信息的问题。语言模型通过n-gram语言模型和历史信息线性插值求得。公式如下。
p
(
w
i
∣
w
1
.
.
.
w
i
−
1
)
=
λ
p
c
a
c
h
e
(
w
i
∣
w
1
.
.
.
w
i
−
1
)
+
(
1
−
λ
)
p
n
−
g
r
a
m
(
w
i
∣
w
i
−
n
+
1
.
.
.
w
i
−
1
)
p(w_i|w_1...w_{i-1})=\lambda p_{cache}(w_i|w_1...w_{i-1})+(1-\lambda)p_{n-gram}(w_i|w_{i-n+1}...w_{i-1})
p(wi∣w1...wi−1)=λpcache(wi∣w1...wi−1)+(1−λ)pn−gram(wi∣wi−n+1...wi−1)
p
c
a
c
h
e
(
w
i
∣
w
1
.
.
.
w
i
−
1
)
=
1
K
∑
j
=
i
−
K
i
−
1
I
{
w
j
=
w
i
}
p_{cache}(w_i|w_1...w_{i-1})=\frac{1}{K}\sum_{j=i-K}^{i-1}I_{\{w_j=w_i\}}
pcache(wi∣w1...wi−1)=K1j=i−K∑i−1I{wj=wi}
其中
λ
\lambda
λ是超参数。
I
I
I是指示器函数,如果
w
j
=
w
i
w_j=w_i
wj=wi情况出现过,则为1,否则为0。但是这种方法没有考虑词的距离,下面是改进后的版本:
p
c
a
c
h
e
(
w
i
∣
w
1
.
.
.
w
i
−
1
)
=
β
∑
j
=
i
−
K
i
−
1
I
{
w
j
=
w
i
}
e
−
α
(
i
−
j
)
p_{cache}(w_i|w_1...w_{i-1})=\beta\sum_{j=i-K}^{i-1}I_{\{w_j=w_i\}}e^{-\alpha(i-j)}
pcache(wi∣w1...wi−1)=βj=i−K∑i−1I{wj=wi}e−α(i−j)
其中alpha是衰减率,beta是归一化常数。
基于混合方法的语言模型
解决模型训练自不同领域语料,但测试语料是同一个语料的问题。为了在同一领域获取最佳性能。提出此方法。方法首先将模型分成
n
n
n个子模型
M
j
M_j
Mj。一个子模型就是一个主题或领域,然后由如下公式线性插值
p
(
w
i
∣
w
1
.
.
.
w
i
−
1
)
=
∑
j
=
1
n
λ
j
p
M
j
(
w
i
∣
w
1
.
.
.
w
i
−
1
)
p(w_i|w_1...w_{i-1})=\sum_{j=1}^{n}\lambda_jp_{M_j}(w_i|w_1...w_{i-1})
p(wi∣w1...wi−1)=j=1∑nλjpMj(wi∣w1...wi−1)
其中参数
λ
\lambda
λ可通过EM算法学习得到。
基于最大熵的语言模型
基本思想是通过结合不同信息源构建一个语言模型。
p
(
w
i
∣
w
1
.
.
.
w
i
−
1
)
=
exp
(
λ
i
f
(
w
i
,
w
1
.
.
.
w
n
−
1
)
)
∑
w
i
exp
(
λ
i
f
(
w
i
,
w
1
.
.
.
w
n
−
1
)
)
p(w_i|w_1...w_{i-1})=\frac{\exp(\lambda_if(w_i,w_1...w_{n-1}))}{\sum_{w_i}\exp(\lambda_if(w_i,w_1...w_{n-1}))}
p(wi∣w1...wi−1)=∑wiexp(λif(wi,w1...wn−1))exp(λif(wi,w1...wn−1))
例如
f
f
f可以是一个二无语言模型:
f
(
w
i
,
w
i
−
1
)
=
P
(
w
i
∣
w
i
−
1
)
f(w_i,w_{i-1})=P(w_i|w_{i-1})
f(wi,wi−1)=P(wi∣wi−1)
神经网络语言模型
为了解决以下两个问题:
- 数据稀疏导致参数训练不充分
- 忽略词语的语义相似性,从而无法共享信息
而解决的办法是使用基于分布式表示的N-gram语言模型:
p
(
w
∣
w
1
.
.
.
w
n
−
1
)
=
f
(
W
X
)
p(w|w_1...w_{n-1})=f(WX)
p(w∣w1...wn−1)=f(WX)
其中,
x
i
x_i
xi是
w
i
w_i
wi的稠密向量表示。
f
f
f是由神经网络搭建的非线性函数。使用神经网络强大之处大于,它可以对所有的历史信息
进行建模。
前馈神经网络语言模型
输出层每个神经元都相当于
p
(
x
∣
x
1
.
.
.
x
n
−
1
)
p(x|x_1...x_{n-1})
p(x∣x1...xn−1)。一般输出的维度与词典大小一样,并且最后使用
s
o
f
t
m
a
x
(
⋅
)
\mathbf{softmax}(\cdot)
softmax(⋅)函数把前面神经元的输出转换成概率。
循环神经网络语言模型
注意这里只对RNN最后一个隐状态状态(即t时刻)求取输出。这个输出就第
t
+
1
t+1
t+1个词的概率。词典中每个词都会有一个概率。因此输出维度与词典大小一样。
注意:这里
h
t
=
t
a
n
h
(
U
x
t
+
W
h
t
−
1
)
h_t=tanh(Ux_t+Wh_{t-1})
ht=tanh(Uxt+Wht−1)。
x
t
x_t
xt是
w
t
w_t
wt的 稠密向量表示。图中有误。
自我注意力机制语言模型
s , x 1 , x 2 s,x1,x2 s,x1,x2与参数矩阵W相乘后作为V。每个Q中的向量q与K交互后会得到 α 1 , α 2 , α 3 \alpha_1,\alpha_2,\alpha_3 α1,α2,α3权重。将这些权重与V加权平均得到当前查询q的查询结果。每个q都计算一遍就得到图上左上角的三个向量了。
个人理解:其实说它是语言模型有点牵强。可能Attention结束后,还得在之后拼接一个全连层,从而将特征转换成概率。
语言模型的应用
分词、依存句法等。