1. 语言模型
在这一部分中,我们讨论的语言模型主要是统计语言模型,除此之外,我们在今后的文章中还会对神经网络语言模型进行介绍。
所谓语言模型,就是利用数学的方法描述语言规律。而统计语言模型,就是用句子
S
S
S出现的概率
P
(
S
)
P(S)
P(S)来刻画句子的合理性(而不进行语言学分析处理),这是统计自然语言处理的基础模型。
假设句子
S
=
w
1
,
w
2
,
.
.
.
,
w
n
S=w_1,w_2,...,w_n
S=w1,w2,...,wn,其中,
w
i
w_i
wi可以暂时看作句子中的第
i
i
i个词(在后面会进行具体介绍)。由于自然语言是上下文相关的信息传递方式,可以很自然地讲句子
S
S
S出现的概率定义如下:
P
(
S
)
=
P
(
w
1
)
P
(
w
2
∣
w
1
)
.
.
.
P
(
w
n
∣
w
1
,
w
2
,
.
.
.
w
n
−
1
)
P(S) = P(w_1)P(w_2|w_1)...P(w_n|w_1,w_2,...w_n-1)
P(S)=P(w1)P(w2∣w1)...P(wn∣w1,w2,...wn−1)
特别地,当
i
=
1
i=1
i=1时,
P
(
w
1
∣
w
0
)
=
P
(
w
1
)
P(w_1|w_0) = P(w_1)
P(w1∣w0)=P(w1),概率定义与条件概率相同。
在统计语言模型中,输入是句子
S
S
S,输出是句子
S
S
S的概率
P
(
S
)
P(S)
P(S),模型参数是各个
P
P
P,即
P
(
w
i
∣
w
1
,
w
2
,
.
.
.
,
w
i
−
1
)
P(w_i|w_1,w_2,...,w_{i-1})
P(wi∣w1,w2,...,wi−1)。
w i w_i wi被称为统计基元,可以是字、词、短语、词类等等,通常以“词”代替;
w
i
w_i
wi由
w
1
,
w
2
,
.
.
.
w
i
−
1
w_1,w_2,...w_{i-1}
w1,w2,...wi−1决定,由特定一组
w
1
,
w
2
,
.
.
.
w
i
−
1
w_1,w_2,...w_{i-1}
w1,w2,...wi−1构成的一个序列称为
w
i
w_i
wi的历史。
说到这里,相信大家已经发现了一个很现实却很重要的问题:在这个模型中,参数的数量也太多了!
假设我们的统计基元个数为 L L L(在这里可以将其理解为词汇表),那么一句话中的第 i i i个基元就有 L ( i − 1 ) L(i-1) L(i−1)种不同的历史情况。我们必须考虑到这所有不同的历史情况下产生第 i i i个基元的概率,于是,对于长度为 m m m的句子,模型中有 L m L^m Lm个自由参数 P ( w m ∣ w 1 … w m − 1 ) P(w_m|w_1…w_{m-1}) P(wm∣w1…wm−1)。
这样算来,这会是一个很可怕的参数数量,假设 L = 5000 L = 5000 L=5000(词汇表中的词数有5000不过分吧), m = 3 m = 3 m=3,模型中的自由参数就达到了1250亿!这还仅仅是对应着一个三个词的句子,而汉语中平均每句话中有22个词,这将是一个天文数字。
要解决这个问题,就要减少历史基元的个数,也就是减少决定 w i w_i wi的历史词的数目。
等等!看到这里,是不是有点熟悉,这不就是大名鼎鼎的马尔可夫链嘛!(不熟悉马尔可夫链的朋友们可以自行百度一下~)
没错,我们称其为马尔可夫方法:假设任意一个词 w i w_i wi出现的概率只与它前面的 w i − 1 w_{i-1} wi−1有关,将原模型简化为二元模型:
P ( S ) = P ( w 1 ) P ( w 2 ∣ w 1 ) . . . P ( w i ∣ w i − 1 ) . . . P ( w n ∣ w n − 1 ) P(S) = P(w_1)P(w_2|w_1)...P(w_i|w_{i-1})...P(w_n|w_{n-1}) P(S)=P(w1)P(w2∣w1)...P(wi∣wi−1)...P(wn∣wn−1)
在此基础上,提出 n n n元文法(n-gram):一个词由它前面的 n − 1 n-1 n−1个词决定(注意,是 n − 1 n-1 n−1哦,不是 n n n)。
-
一元文法(1-gram): n = 1 , P ( w i ∣ w 1 , w 2 , . . . , w i − 1 ) = P ( w i ) n=1,P(w_i|w_1,w_2,...,w_{i-1}) = P(w_i) n=1,P(wi∣w1,w2,...,wi−1)=P(wi),出现在每一位上的基元 w i w_i wi独立于历史;
-
二元文法(2-gram): n = 2 , P ( w i ∣ w 1 , w 2 , . . . , w i − 1 ) = P ( w i ∣ w i − 1 ) n=2,P(w_i|w_1,w_2,...,w_i-1) = P(w_i|w_{i-1}) n=2,P(wi∣w1,w2,...,wi−1)=P(wi∣wi−1),1阶马尔可夫链;
-
三元文法(3-gram): n = 3 , P ( w i ∣ w 1 , w 2 , . . . , w i − 1 ) = P ( w i ∣ w i − 2 , w i − 1 ) n=3,P(w_i|w_1,w_2,...,w_{i-1}) = P(w_i|w_{i-2},w_{i-1}) n=3,P(wi∣w1,w2,...,wi−1)=P(wi∣wi−2,wi−1),2阶马尔可夫链;
……
以此类推。
理论上讲, n n n元文法中的n越大越好(越能保留句子词之间的相关性),但是正如上文所说, n n n越大也就意味着需要估计的参数越多。一般来讲, n = 3 n=3 n=3用得相对较多, n = 4 n=4 n=4的时候参数就已经太多了。
值得注意的是,即使采用n较大的高阶模型,也无法覆盖全部的语言现象(因为现阶段,对于人类来讲,语言依然是一个谜)。
了解了语言模型之后,问题来了:如何估计语言模型的参数呢?(用于计算 P ( S ) P(S) P(S)的各个 P ( w i ∣ w i − n + 1 , . . . , w i − 1 ) P(w_i|w_{i-n+1},...,w_{i-1}) P(wi∣wi−n+1,...,wi−1)值
利用极大似然估计(Maximum Likelihood Evaluation,MLE)。
从个人理解的角度出发,我认为利用极大似然估计在语料中统计语言模型参数的过程,可以形象化地概括为两个字:数(三声)数(四声)。
极大似然估计的过程大致如下:
假设我们的语料库中只有三句话(语料库的概念将在后面进行介绍):
- John read Moby Dick
- Mary read a different book
- She read a book by Cher
现在,我们想要估计2-gram模型中,‘John read a book’ 这句话出现的概率。
P ( ‘ J o h n r e a d a b o o k ’ ) = P ( J o h n ∣ < B O S > ) P ( r e a d ∣ J o h n ) P ( a ∣ r e a d ) P ( b o o k ∣ a ) P ( < E O S > ∣ b o o k ) P(‘John\ read\ a\ book’ ) = P(John|<BOS>)P(read|John)P(a|read)P(book|a)P(<EOS>| book) P(‘John read a book’)=P(John∣<BOS>)P(read∣John)P(a∣read)P(book∣a)P(<EOS>∣book),其中 < B O S > <BOS> <BOS>和 < E O S > <EOS> <EOS>分别表示句子的开始符和结束符。
我们可以从语料中(1,2,3一共三句话)统计得到:
P ( J o h n ∣ < B O S > ) = 1 / 3 P(John|<BOS>) = 1/3 P(John∣<BOS>)=1/3,因为 < B O S > <BOS> <BOS>出现了三次(每个句子的开始),后面接John的有一次——即,John出现在句首;
P ( r e a d ∣ J o h n ) = 1 / 1 P(read|John) = 1/1 P(read∣John)=1/1,因为John出现了一次,后面接read的有一次;
P ( a ∣ r e a d ) = 2 / 3 P(a|read) = 2/3 P(a∣read)=2/3,因为read出现了3词,后面接a的有一次;
P(book|a) = 1/2,因为a出现了2次,后面接book的有一次;
P ( < E O S > ∣ b o o k ) = 1 / 2 P(<EOS>| book) = 1/2 P(<EOS>∣book)=1/2,因为book出现了2次,book出现在句子结尾(后面接 < E O S > <EOS> <EOS>)的有1次。
因此, P ( S ) = 1 / 18 P(S) = 1/18 P(S)=1/18。
通过这个小小的例子,我们可以发现,语言模型可以预测句子的下一个词(已知前面的词),也可以计算一句话出现的概率,决定哪一个词序列出现的概率大。
下面,我们再举一个例子:
还是上面的语料库,还是使用2-gram,我们想要求‘Cher read a book’的概率。
看起来没什么问题啊,按着上面的套路做就可以了啊,但是在实际计算的时候我们发现: P ( C h e r ∣ < B O S > ) = 0 P(Cher|<BOS>) = 0 P(Cher∣<BOS>)=0,Cher这个词根本就没有出现在句首过!
这也就意味着,无论后面几个概率值是多少,我们计算出来的整个句子出现的概率都是0。
这个问题被称为零概率问题,是由数据稀疏(匮乏)造成的。
那么遇到了这个问题,该如何解决呢?
进行数据平滑。
数据平滑的方法有很多种,在这里不一一进行赘述,有兴趣的朋友可以自行百度了解。
总之,数据平滑之后,不会出现上面例子中出现的零概率问题,我们就可以安安心心地用语言模型计算一句话出现的概率啦~
到这里,对语言模型的介绍就基本结束了,我们还剩下一些边边角角的问题需要解决:比如,如何评价语言模型。
目前,语言模型的评价一般有两种方法:
-
实用方法:通过查看该模型在实际应用(如机器翻译)中的表现来评价,优点是直观、实用,缺点是缺乏针对性、不够客观。
-
理论方法:为了评价语言模型,提出了一个“困惑度”的概念,方法如下:
平滑过后的n-gram模型句子的概率为(与语言模型中的描述相同): P ( S ) = P ( w 1 ) . . . P ( w i ∣ w i − n + 1 , . . . , w i − 1 ) . . . P(S) = P(w_1)...P(w_i|w_{i-n+1},...,w_{i-1})... P(S)=P(w1)...P(wi∣wi−n+1,...,wi−1)...
假设测试语料 T T T由 k k k个句子 t 1 , t 2 , . . . , t k t_1,t_2,...,t_k t1,t2,...,tk构成,那么整个测试集 T T T的概率为: p ( T ) = P ( t 1 ) P ( t 2 ) . . . P ( t k ) p(T) = P(t_1)P(t_2)...P(t_k) p(T)=P(t1)P(t2)...P(tk)
定义模型对于测试预料的交叉熵为:
H p ( T ) = − 1 W t l o g 2 p ( T ) H_p(T) = \frac{- 1}{W_t}log_2p(T) Hp(T)=Wt−1log2p(T)
其中,分母项为测试语料 T T T中的词数(可以理解为测试文本集的单词表)。
定义模型的困惑度为:
P
P
p
(
T
)
=
2
H
p
(
T
)
PP_p(T)=2^{H_p(T)}
PPp(T)=2Hp(T)
困惑度越低,模型评价越高。
在这里,多说几句题外话:
对于一个模型而言,最重要的部分有四个:输入、输出、参数、对应关系(函数)。
对于任何一个模型而言,把握住这四个基本要素,相信会帮助大家理解得更加透彻(特别是今后我们会提到的神经网络)。
2. 语料库(corpus)
语料库是什么?
语料库就是,存放在计算机里的原始语料文本 或 经过加工后带有语言学信息标注的语料文本。为了方便理解,我们可以将其看作一个数据库,我们从中提取语言数据,以便对其进行分析、处理。
语料库有三点特征:
- 语料库中存放的是在实际使用中真是出现过的语言材料。
- 语料库是以计算机为载体承载语言知识的基础资源,但并不等于语言知识。
- 真实语料需要经过分析、处理和加工,才能成为有用的资源。(这一点尤为重要,在NLP知识的学习中,需要对语言原材料进行一系列的处理才能够使用)
在这里,不对语料库进行系统的介绍,仅需要了解“我们可以从中提取语言数据来用”就可以啦~
如果有朋友对语料库的分类和现阶段一些著名的语料库感兴趣,可以自行百度了解~
3. 参考文献
[1] https://blog.csdn.net/echoKangYL/article/details/86626714