一、什么是 N-gram?
在自然语言处理中,n-gram 是一种重要的文本表示方法。n-gram 是指给定文本中连续的 n n n 个项目,这些项目可以是声音、单词、字符或者像素等。n-gram 模型常常用于语言模型,以预测接下来的一个项目(比如一个单词)。
比如,我们需要计算 P ( w ∣ h ) P(w|h) P(w∣h),在给定历史 h h h 的情况下,某个单词 w w w 出现的概率。假设历史 h h h 是 “The water of Walden Pond is so beautifully”,我们想知道下一个单词是 “blue” 的概率:
P ( b l u e ∣ T h e w a t e r o f W a l d e n P o n d i s s o b e a u t i f u l l y ) P(blue|The \ water \ of \ Walden \ Pond \ is \ so \ beautifully) P(blue∣The water of Walden Pond is so beautifully)
一种估算这种概率的方法是直接通过相对频率计数:取一个非常大的语料库,计算我们看到"The water of Walden Pond is so beautifully"这句话的次数,然后计算这句话后面接"blue"这个词的次数。这实际上是在回答这样一个问题:“在我们看到历史h的次数中,有多少次是接着出现词w的”,具体如下:
C
(
T
h
e
w
a
t
e
r
o
f
W
a
l
d
e
n
P
o
n
d
i
s
s
o
b
e
a
u
t
i
f
u
l
l
y
b
l
u
e
)
C
(
T
h
e
w
a
t
e
r
o
f
W
a
l
d
e
n
P
o
n
d
i
s
s
o
b
e
a
u
t
i
f
u
l
l
y
)
\frac{C(The \ water \ of \ Walden \ Pond \ is \ so \ beautifully \ blue)}{C(The \ water \ of \ Walden \ Pond \ is \ so \ beautifully)}
C(The water of Walden Pond is so beautifully)C(The water of Walden Pond is so beautifully blue)
如果我们有足够大的语料库,我们可以计算这两个计数并根据上述公式估计概率。但是,即使是整个网络也不足以让我们对完整句子的计数进行良好的估计。这是因为语言具有创造性;新句子不断被创造出来,我们不能指望对像完整句子这样的大对象获得准确的计数。因此,我们需要更巧妙的方法来估计给定历史h的单词
w
w
w 的概率,或者整个单词序列
W
W
W 的概率。让我们从一些符号开始。首先,在本章中我们将继续提到单词,尽管在实践中我们通常是在像BPE(字节对编码)这样的标记上计算语言模型。为了表示特定随机变量Xi取值为 “the” 的概率,或者说
P
(
X
i
=
"
t
h
e
"
)
P(X_{i} = "the")
P(Xi="the"),我们将使用简化形式
P
(
t
h
e
)
P(the)
P(the)。我们用
w
1
w_{1}
w1到
w
n
w_{n}
wn 或
w
1
:
n
w_{1:n}
w1:n 表示
n
n
n 个单词的序列。因此,表达式
w
1
:
n
−
1
w_{1:n−1}
w1:n−1 表示字符串
w
1
,
w
2
,
…
,
w
n
−
1
w_{1}, w_{2}, \dots, w_{n−1}
w1,w2,…,wn−1。对于序列中每个单词具有特定值的联合概率
P
(
X
1
=
w
1
,
X
2
=
w
2
,
X
3
=
w
3
,
…
,
X
n
=
w
n
)
P(X_{1} = w_{1}, X_{2} = w_{2}, X_{3} = w_{3}, \dots, X_{n} = w_{n})
P(X1=w1,X2=w2,X3=w3,…,Xn=wn),我们将使用
P
(
w
1
,
w
2
,
…
,
w
n
)
P(w_{1}, w_{2}, \dots, w_{n})
P(w1,w2,…,wn)。那么,我们如何计算整个序列的概率,比如
P
(
w
1
,
w
2
,
…
,
w
n
)
P(w_{1}, w_{2}, \dots, w_{n})
P(w1,w2,…,wn)?我们可以做的一件事是利用概率的链式法则(chain rule of probability)来分解这个概率:
P
(
X
1
.
.
.
X
n
)
=
P
(
X
1
)
P
(
X
2
∣
X
1
)
P
(
X
3
∣
X
1
:
2
)
.
.
.
P
(
X
n
∣
X
1
:
n
−
1
)
=
Π
k
=
1
n
P
(
X
k
∣
X
1
:
k
−
1
)
P(X_{1}...X_{n}) = P(X_{1})P(X_{2}|X_{1})P(X_{3}|X_{1:2})...P(X_{n}|X_{1:n-1}) \\ =\Pi^{n}_{k=1}P(X_{k}|X_{1:k-1})
P(X1...Xn)=P(X1)P(X2∣X1)P(X3∣X1:2)...P(Xn∣X1:n−1)=Πk=1nP(Xk∣X1:k−1)
使用链式法则,我们可以得到:
P
(
w
1
:
n
)
=
P
(
w
1
)
P
(
w
2
∣
w
1
)
P
(
w
3
∣
w
1
:
2
)
.
.
.
P
(
w
n
∣
w
1
:
n
−
1
)
=
Π
k
=
1
n
P
(
w
k
∣
w
1
:
k
−
1
)
P(w_{1:n})=P(w_{1})P(w_{2}|w_{1})P(w_{3}|w_{1:2})...P(w_{n}|w_{1:n-1}) \\ = \Pi^{n}_{k=1}P(w_{k}|w_{1:k-1})
P(w1:n)=P(w1)P(w2∣w1)P(w3∣w1:2)...P(wn∣w1:n−1)=Πk=1nP(wk∣w1:k−1)
我们可以通过相乘一系列的条件概率来估计整个单词序列的联合概率。但是,使用链式法则似乎并没有真正解决问题!我们不知道如何计算在给定一长串前面单词的情况下,一个单词的确切概率,也就是 P ( w n ∣ w 1 : n − 1 ) P(w_{n}|w_{1:n−1}) P(wn∣w1:n−1)。正如之前提到的,我们不能简单地通过统计每个单词在某个语料库中出现在每个长字符串后面的次数来进行估计,因为语言是充满创造性的,任何特定的上下文可能之前都从未出现过!
二、马尔可夫假设
n-gram模型的基本想法是,与其根据一个词的整个上下文历史来计算其出现的概率,不如只考虑它前面的几个词。比如在bigram模型中,我们不再计算一个词在所有前面词语条件下的概率,而是通过只看前一个词的条件概率
P
(
w
n
∣
w
n
−
1
)
P(w_{n}|w_{n−1})
P(wn∣wn−1) 来进行近似计算。简单来说,就是只关注紧邻的前一个词,而不是所有前面的词。例如,之前的例子:
P
(
b
l
u
e
∣
T
h
e
w
a
t
e
r
o
f
W
a
l
d
e
n
P
o
n
d
i
s
s
o
b
e
a
u
t
i
f
u
l
l
y
)
P(blue|The \ water \ of \ Walden \ Pond \ is \ so \ beautifully)
P(blue∣The water of Walden Pond is so beautifully)
可以近似概率为:
P
(
b
l
u
e
∣
b
e
a
u
t
i
f
u
l
l
y
)
P(blue|beautifully)
P(blue∣beautifully)
当我们使用bigram模型来预测下一个单词的条件概率时,我们做出以下近似:
P
(
w
n
∣
w
1
:
n
−
1
)
≈
P
(
w
n
∣
w
n
−
1
)
P(w_{n}|w_{1:n-1}) \approx P(w_{n}|w_{n-1})
P(wn∣w1:n−1)≈P(wn∣wn−1)
上述的一个词的概率只取决于前一个词的假设被称为马尔可夫假设(Markov assumption)。马尔可夫模型是一类概率模型,它假设我们可以在不回溯太多的情况下预测未来某个单位的概率。我们可以将 bigram 模型(只考虑前一个词)推广到 trigram 模型(考虑前两个词),进而推广到 n-gram 模型(考虑前
n
−
1
n-1
n−1 个词)。下面我们来看一下这个
n
n
n 元模型用于近似序列中下一个词的条件概率的通用公式。这里我们用
N
N
N 表示 n-gram 模型的大小,所以,当
N
=
1
N = 1
N=1 表示 unigram;
N
=
2
N=2
N=2 表示 bigram 模型;
N
=
3
N=3
N=3 表示 trigram 模型。然后,我们可以用以下方法来近似给定整个上下文的情况下一个词的概率:
P
(
w
n
∣
w
1
:
n
−
1
)
≈
P
(
w
n
−
N
+
1
:
n
−
1
)
P(w_{n}|w_{1:n-1}) \approx P(w_{n-N+1:n-1})
P(wn∣w1:n−1)≈P(wn−N+1:n−1)
例如,根据单词的 bigram 假设,我们可以计算完整单词序列的概率:
P
(
w
1
:
n
)
≈
Π
k
=
1
n
P
(
w
k
∣
w
k
−
1
)
P(w_{1:n}) \approx \Pi^{n}_{k=1}P(w_{k}|w_{k-1})
P(w1:n)≈Πk=1nP(wk∣wk−1)
三、如何估计概率
我们如何估计 bigram 或 n-gram 的概率呢?一种直观的方法叫做 maximum likelihood estimation(MLE)。在 n-gram 模型中,我们通过从语料库中获取计数,然后对这些计数进行归一化,使它们介于0到1之间,从而得到参数的 MLE 估计。对于概率模型来说,归一化意味着将计数除以某个总计数,以确保结果概率在0到1之间,并且总和为1。
例如,要计算给定前一个词
w
n
−
1
w_{n−1}
wn−1后出现某个词
w
n
w_{n}
wn 的特定 bigram 概率,我们需要计算这个 bigram 的计数
C
(
w
n
−
1
w
n
)
C(w_{n−1}w_{n})
C(wn−1wn),然后用所有以相同第一个词
w
n
−
1
w_{n−1}
wn−1 开头的 bigram 计数之和来进行归一化:
P
(
w
n
∣
w
n
−
1
)
=
C
(
w
n
−
1
w
n
)
∑
w
C
(
w
n
−
1
w
)
P(w_{n}|w_{n-1})=\frac{C(w_{n−1}w_{n})}{\sum_{w}C(w_{n-1}w)}
P(wn∣wn−1)=∑wC(wn−1w)C(wn−1wn)
我们可以简化这个方程,因为以某个词
w
n
−
1
w_{n-1}
wn−1 开头的所有 bigram 计数之和,必须等于这个词
w
n
−
1
w_{n-1}
wn−1 的 unigram 计数:
P
(
w
n
∣
w
n
−
1
)
=
C
(
w
n
−
1
w
n
)
C
(
w
n
−
1
)
P(w_{n}|w_{n-1})=\frac{C(w_{n−1}w_{n})}{C(w_{n-1})}
P(wn∣wn−1)=C(wn−1)C(wn−1wn)
举个例子🌰
我们来通过一个由三句话组成的小语料库举个例子。首先,我们需要在每句话的开头加上一个特殊符号<s>
,这样可以为句子的第一个词提供 bigram 的上下文。同时,我们还需要在句子末尾加上一个特殊的结束符号</s>
。
<s> I am Sam </s>
<s> Sam I am </s>
<s> I do not like green eggs and ham </s>
以下是该语料库中一些 bigram 概率的计算:
P ( S a m ∣ a m ) = C ( a m S a m ) C ( a m ) = 1 2 = 0.5 P(Sam|am)=\frac{C(am \ Sam)}{C(am)}=\frac{1}{2}=0.5 P(Sam∣am)=C(am)C(am Sam)=21=0.5
P ( d o ∣ I ) = C ( I d o ) C ( I ) = 1 3 = 0.33 P(do|I)=\frac{C(I \ do)}{C(I)}=\frac{1}{3}=0.33 P(do∣I)=C(I)C(I do)=31=0.33
P ( I ∣ < s > ) = C ( < s > I ) C ( < s > ) = 2 3 = 0.67 P(I|<s>)=\frac{C(<s>I)}{C(<s>)}=\frac{2}{3}=0.67 P(I∣<s>)=C(<s>)C(<s>I)=32=0.67
解释:
C ( < s > ) C(<s>) C(<s>),也就是 w n − 1 = w_{n-1}= wn−1=<s>
的一共有三处,分别是<s> I
,<s> Sam
,以及<s> I
其中, C ( < s > I ) C(<s>I) C(<s>I)一共有两处,所以,概率为 2 3 \frac{2}{3} 32
对于一般情况下的最大似然估计(MLE)n-gram参数估计:
P
(
w
n
∣
w
n
−
N
+
1
:
n
−
1
)
=
C
(
w
n
−
N
+
1
:
n
−
1
w
n
)
C
(
w
n
−
N
+
1
:
n
−
1
)
P(w_{n}|w_{n-N+1:n-1})=\frac{C(w_{n-N+1:n-1} \ w_{n})}{C(w_{n-N+1:n-1})}
P(wn∣wn−N+1:n−1)=C(wn−N+1:n−1)C(wn−N+1:n−1 wn)
四、优缺点
优点
它考虑了词与词之间的顺序信息,从而能更好地捕捉到语义信息。
缺点
模型的数据稀疏性问题(随着n的增大,会出现许多从未在训练数据中出现过的n-gram),以及它无法捕捉到更长距离的依赖关系(超过n的范围)。
因此,在实际应用中,n-gram模型通常会与其他模型如词袋模型(Bag of Words)、TF-IDF等结合使用,以获得更好的效果。
PS:补充
处理 未见过的 n-gram(unseen n-grams)时的一些平滑技术。
Laplacian (Add-one) 平滑:
-
Unigram:
对于单个词的概率计算,使用加一平滑的方法公式为:
P a d d 1 ( w i ) = C ( w i ) + 1 M + ∣ V ∣ P_{add1}(w_i)=\frac{C(w_i)+1}{M+|V|} Padd1(wi)=M+∣V∣C(wi)+1这里, C ( w i ) C(w_i) C(wi)表示词 w i w_i wi在语料库中出现的次数, M M M是语料库中所有词的总数, ∣ V ∣ |V| ∣V∣是词汇表的大小,也就是不同词的总数。加一平滑通过在每个词的计数中加1来避免某些词的概率为零的情况。
-
Bigram:
对于两个连续词的概率计算,使用加一平滑的方法公式为:P a d d 1 ( w i ∣ w i − 1 ) = C ( w i − 1 , w i ) + 1 C ( w i − 1 ) + ∣ V ∣ P_{add1}(w_i|w_{i-1})=\frac{C(w_{i-1},w_i)+1}{C(w_{i-1})+|V|} Padd1(wi∣wi−1)=C(wi−1)+∣V∣C(wi−1,wi)+1
这里, C ( w i − 1 , w i ) C(w_{i-1}, w_i) C(wi−1,wi)表示词对 ( w i − 1 , w i ) (w_{i-1}, w_i) (wi−1,wi)在语料库中出现的次数, C ( w i − 1 ) C(w_{i-1}) C(wi−1)表示词 w i − 1 w_{i-1} wi−1出现的总次数。通过在词对的计数中加1,避免了某些词对组合的概率为零。
其他平滑方法:
-
Absolute discounting(绝对折扣法):通过从每个非零计数中减去一个常数来重新分配概率质量。
-
Kneser-Ney:一种更复杂的平滑方法,特别适用于处理低频n-gram,考虑了n-gram的出现背景。
这些平滑技术的目的是确保模型能够合理地处理未见过的n-gram,从而提高语言模型在新数据上的表现。
如果觉得这篇文章有用,就给个赞👍和收藏⭐️吧!也欢迎在评论区分享你的看法!
参考
- N-gram Language Models by Daniel Jurafsky & James H. Martin