计算机只能算数而无法直接理解人类语言,所以就需要将其翻译成数字以便于处理,这个翻译的过程就是 编码 。具体到每个字/词要编成啥样式、多大的数字,方法就很很多了,本篇俺就按发展历史介绍几种重要的传统文本表示方法。
1. One Hot编码
最简单的编码,我相信地球人都能想到,没错,就是每个词用一个数字ID表示,比如 【我:1,爱:2,你:3】,这样计算机见到 “我爱你”就知道是“123”,见到“321”就知道是“你爱我”。我们知道数字都是有大小的,这个时候就有问题了,大家都是汉字,凭什么你是3,我是1,所以,为了体现字字平等,天下大同,大家都是1,都是可以区分的1,怎么区分呢,三个词一商量,要不我就是100,爱是010,你是001,这样问题就解决了(当然谁是100,谁是010,都没有关系)。这就是大名鼎鼎的One Hot(独热编码)。
如图所示,一个字/词一个id/index,再转成one-hot向量。对于单词 A,它出现在词表中的位置为 k,它的向量就是“第 k 位为1,其他位置为0 ”的一个向量。
优点就很明显了:
1.可以处理非数值型的特征,在逻辑回归等传统机器学习算法上应用比较广泛
2.一定程度上可以扩充特征,比如性别这一属性,经one-hot后就成为男、女两个特征
当然缺点 也显而易见:
1.词与词是有语义关系的,one-hot显然没有考虑这种情况,每个词编码都是独立的;
2.词表有多长,每个词向量维度就有多长,造成维度灾难,计算量大,很容易OOM。
2. Bag-of-words(BOW:词袋模型)
把已有文本的所有词去重后放一个袋子里,就是BOW,没错,就是这么easy。但是怎么用呢?俺先来举个🌰:
假设一共有这两句话,那组成的词袋去重后就包含9个词:
这时候t1、t2的表征向量长度就是9,大小用每个词的词频来表示:
t1、t2的距离:
l
e
n
g
t
h
(
t
1
⃗
,
t
2
⃗
)
=
∣
∣
t
1
⃗
−
t
2
⃗
∣
∣
=
1
+
1
+
1
+
1
+
1
+
1
+
1
+
1
+
1
=
3
length(\vec{t1},\vec{t2})=||\vec{t1}-\vec{t2}||=\sqrt{1+1+1+1+1+1+1+1+1}=3
length(t1,t2)=∣∣t1−t2∣∣=1+1+1+1+1+1+1+1+1=3
BOW本质和one-hot是一样的,可以处理离散的非数值型数据,一定程度上扩充特征。但当文本很多时,句向量较长且很多为0,会得到一个稀疏矩阵;且词袋模型依赖词频,没有考虑词序等涉及语义的信息,文本的微小变动,也会造成很大影响,如“喜欢”前多加一个“不”字,语义完全相反但得出的结果仍然很相似。
提到文档和词频,自然就会想到TF-IDF,这是判断词的重要性算法,以后再说。
3. N-gram
语言模型的目标是啥呢?其实就是让语言字符拼起来能是一句人话,咋判断哪个字符串是最像人话的呢,没错,概率!概率越大越可能拼对了。语言模型的本质是对语句的概率分布建模。数学语言就是:
给定任意的字符串
w
1
n
=
w
1
w
2
w
3
.
.
.
w
n
w_{1}^{n}=w_1w_2w_3...w_n
w1n=w1w2w3...wn,计算该字符串出现的概率
p
(
w
1
n
)
p(w_{1}^{n})
p(w1n)
根据贝叶斯公式,联合概率分解:
p
(
w
1
n
)
=
p
(
w
1
w
2
w
3
.
.
.
w
n
)
=
p
(
w
2
n
∣
w
1
)
p
(
w
1
)
=
p
(
w
1
)
p
(
w
2
∣
w
1
)
p
(
w
2
∣
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_1w_2w_3...w_n)=p(w_{2}^n|w_1)p(w_1)=p(w_1)p(w_2|w_1)p(w_2|w_{1}^2)...p(w_n|w_{1}^{n-1})=\prod_{k=1}^{n}p(w_k|w_{1}^{k-1})
p(w1n)=p(w1w2w3...wn)=p(w2n∣w1)p(w1)=p(w1)p(w2∣w1)p(w2∣w12)...p(wn∣w1n−1)=k=1∏np(wk∣w1k−1)
其中:
p
(
w
3
∣
w
1
2
)
≈
c
o
u
n
t
(
w
1
w
2
w
3
)
c
o
u
n
t
(
w
1
w
2
)
p(w_3|w_{1}^2)\approx\frac{count(w_1w_2w_3)}{count(w_1w_2)}
p(w3∣w12)≈count(w1w2)count(w1w2w3)
表示在词
w
1
w
2
w_1w_2
w1w2一起出现的条件下,
w
1
w
2
w
3
w_1w_2w_3
w1w2w3排列出现的概率。
举个🌰: text → 好客山东欢迎您 \textbf{text}\rightarrow\textbf{好客山东欢迎您} text→好客山东欢迎您
p ( t e x t ) = p ( w 1 = 好 , w 2 = 客 , . . . , w 7 = 您 ) = p ( 好 ) p ( 客 ∣ 好 ) p ( 山 ∣ 好客 ) p ( 东 ∣ 好客山 ) . . . p ( 您 ∣ 好客山东欢迎 ) p(text)=p(w_1=好,w_2=客,...,w_7=您)=p(好)p(客|好)p(山|好客)p(东|好客山)...p(您|好客山东欢迎) p(text)=p(w1=好,w2=客,...,w7=您)=p(好)p(客∣好)p(山∣好客)p(东∣好客山)...p(您∣好客山东欢迎)
p ( 山 ∣ 好客 ) ≈ c o u n t ( 好客山 ) c o u n t ( 好客 ) p(山|好客)\approx\frac{count(好客山)}{count(好客)} p(山∣好客)≈count(好客)count(好客山)
这种方式存在的问题:
1.参数空间问题:从公式可以看出,随着字符串长度增加,参数会指数级暴增(条件概率 p ( w n ∣ w 1 n − 1 ) p(w_n|w_{1}^{n-1}) p(wn∣w1n−1)的可能性太多),几乎不可能正确的估计这些参数。
2.数据稀疏严重(零概率/OOV问题):对于非常多词对的组合,在语料库中都没有出现,依据最大似然估计得到的概率将会是0。而且当 c o u n t ( 好客山 ) = c o u n t ( 好客 ) count(好客山)=count(好客) count(好客山)=count(好客)时,也不能认为 p ( 山 ∣ 好客 ) = 1 p(山|好客)=1 p(山∣好客)=1
为了解决问题1,引入了马尔科夫假设:随意一个词出现的概率只与它前面出现的n-1个词有关。基于该假设的统计语言模型就是N-gram语言模型。
- 当n=1时,即一个词的出现与它周围的词是独立,称为unigram。[我,爱,自,然,语,言,处,理]
- 当n=2时,即一个词的出现仅与它前面的一个词有关时,称为bigram
- 当n=3时,即一个词的出现仅与它前面的两个词有关,称为trigram
参数的数量级是n取值的指数倍,所以尽管理论上n的取值越大,效果越好。但在实践中用的最多的是bigram和trigram了,高于四元的用的非常少,由于训练它须要更庞大的语料,并且数据稀疏严重,时间复杂度高,精度却提高的不多。
n | 模型参数 |
---|---|
1(unigram) | 2 ⋅ 1 0 5 2\cdot10^5 2⋅105 |
2(bigram) | 4 ⋅ 1 0 10 4\cdot10^{10} 4⋅1010 |
3(trigram) | 8 ⋅ 1 0 15 8\cdot10^{15} 8⋅1015 |
4(4gram) | 16 ⋅ 1 0 20 16\cdot10^{20} 16⋅1020 |
为了解决问题2,即由于语料的稀疏性,有些词序列找不到,所以需要对数据进行平滑处理,简单列几种数据平滑的方法:
- 加一平滑(拉普拉斯平滑):将每个计数+1,使得概率为0的词序列得到一个很小的概率
优点:算法简单,解决了概率为0的问题
缺点:给训练语料中没有出现过的词分配了太多的概率空间,认为所有未出现的词概率相等也不合理。 - 古德-图灵平滑(Good-turing Smoothing):用看见过1次的事情估计未看见的事件,并依次类推,用看见过2次的事件估计看见过1次的事件。
r
∗
=
(
r
+
1
)
n
r
+
1
n
r
,
n
r
:
出现了
r
次
n
元对的个数
r^*=(r+1)\frac{n_{r}+1}{n_r},n_r:出现了r次n元对的个数
r∗=(r+1)nrnr+1,nr:出现了r次n元对的个数
所以N-gram中N元对 w i − n + 1 i w_{i-n+1}^{i} wi−n+1i出现次数为r的概率为: P G T ( w i − n + 1 i ) = r ∗ ∑ r = 0 ∞ r ∗ P_{GT}(w_{i-n+1}^i)=\frac{r^*}{\sum_{r=0}^{\infty}r^*} PGT(wi−n+1i)=∑r=0∞r∗r∗
古德-图灵估计公式中缺乏利用低元模型对高元模型插值的思想,通常不单独使用,而作为其他平滑算法中的一个计算工具。 - 回退平滑(Katz smoothing):古德-图灵的改进版,当某一事件在样本中的概率大于阈值K(通常取0或1)时,运用最大似然估计的减值法来估计其概率。否则使用低阶的,即用 (n−1)gram的概率来替代n−gram的概率,这种替代受归一化因子
α
\alpha
α的作用。
P
K
A
T
Z
(
w
i
−
1
i
)
=
{
d
r
c
(
w
i
−
1
i
)
c
(
w
i
−
1
)
,
c
(
w
i
−
1
w
i
)
=
r
>
0
α
(
w
i
−
1
)
P
M
L
(
w
i
)
,
c
(
w
i
−
1
w
i
)
=
r
=
0
P_{KATZ}(w_{i-1}^i)=\begin{cases}d_r\frac{c(w^i_{i-1})}{c(w_i-1)},\quad c(w_{i-1}w_i)=r>0\\\alpha(w_{i-1})P_{ML}(w_i),\quad c(w_{i-1}w_i)=r=0\end{cases}
PKATZ(wi−1i)={drc(wi−1)c(wi−1i),c(wi−1wi)=r>0α(wi−1)PML(wi),c(wi−1wi)=r=0
其中 r r r表示出现次数, P M L ( w i ) P_{ML}(w_{i}) PML(wi)表示 w i w_i wi的最大似然估计概率,折扣率 d r d_{r} dr 近似等于 r ∗ r \frac{r^{*}}{r} rr∗,减值由古德-图灵估计方法预测。 - 线性插值平滑(Jelinek Mercer):利用低阶N-gram模型对高阶N-gram模型进行线性插值。
P
i
n
t
e
r
p
(
w
i
∣
w
i
−
n
+
1
i
−
1
)
=
λ
w
i
−
n
+
1
i
−
1
∗
P
M
L
(
w
i
−
1
∣
w
i
−
n
+
1
i
−
1
)
+
(
1
−
λ
)
∗
P
i
n
t
e
r
p
(
w
i
∣
w
i
−
n
+
2
i
−
1
)
P_{int\, erp}(w_i|w_{i-n+1}^{i-1})=\lambda_{w_{i-n+1}^{i-1}}*P_{ML}(w_{i-1}|w_{i-n+1}^{i-1})+(1-\lambda)*P_{int\, erp}(w_i|w_{i-n+2}^{i-1})
Pinterp(wi∣wi−n+1i−1)=λwi−n+1i−1∗PML(wi−1∣wi−n+1i−1)+(1−λ)∗Pinterp(wi∣wi−n+2i−1)
N-gram模型可以递归地定义为:由最大似然估计得到的N-gram模型和线性插值的 (N-1)-gram模型。
N-gram语言模型的优点:
1.bigram,trigram 实现简单,能够很好地应用在一些经典场景中,例如检查拼写错误(极大似然句子概率)
2.常见搜索引擎的输入下拉帮助,就是通过n-gram来实现的
3.可解释性强,易于理解和调试。
4.易于增量实现和并行训练。
N-gram语言模型的缺点:
- 需要解决数据稀疏性的问题,需要利用平滑算法。
- 由于是离散型变量,没有办法度量词语之间相似度。
- 模型巨大,与|V| 词库大小呈指数增长。
4. NNLM(神经网络语言模型)
讲N-gram的时候,我们已经提到链式概率法则:
p
(
w
1
n
)
=
p
(
w
1
)
p
(
w
2
∣
w
1
)
p
(
w
2
∣
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_2|w_{1}^2)...p(w_n|w_{1}^{n-1})=\prod_{k=1}^{n}p(w_k|w_{1}^{k-1})
p(w1n)=p(w1)p(w2∣w1)p(w2∣w12)...p(wn∣w1n−1)=k=1∏np(wk∣w1k−1)
根据马尔科夫假设,当前词只与前
m
m
m个词有关:
p
(
w
1
n
)
≈
∏
k
=
1
n
p
(
w
n
∣
w
n
−
m
+
1
n
−
1
)
p(w_1^n)\approx\prod_{k=1}^{n}p(w_n|w_{n-m+1}^{n-1})
p(w1n)≈k=1∏np(wn∣wn−m+1n−1)
w
n
:要预测的词
w
n
−
m
+
1
n
−
1
=
w
n
−
m
+
1
,
.
.
.
,
w
n
−
1
:
w
n
前面的历史词语
w_n:要预测的词 \quad w_{n-m+1}^{n-1}=w_{n-m+1},...,w_{n-1}:w_n前面的历史词语
wn:要预测的词wn−m+1n−1=wn−m+1,...,wn−1:wn前面的历史词语
对上式进行建模,常采用极大似然估计,将目标函数设为:
L
=
∑
l
o
g
p
(
w
n
∣
w
n
−
m
+
1
n
−
1
)
L=\sum log\:p(w_n|w_{n-m+1}^{n-1})
L=∑logp(wn∣wn−m+1n−1)对该函数进行最大化,可见概率
p
(
w
n
∣
w
n
−
m
+
1
n
−
1
)
p(w_n|w_{n-m+1}^{n-1})
p(wn∣wn−m+1n−1)已被视为
w
n
w_n
wn关于
w
n
−
m
+
1
n
−
1
w_{n-m+1}^{n-1}
wn−m+1n−1的函数:
p
(
w
n
∣
w
n
−
m
+
1
n
−
1
)
=
F
(
w
n
,
w
n
−
m
+
1
n
−
1
,
θ
)
,
θ
表示待定参数集
p(w_n|w_{n-m+1}^{n-1})=F(w_n,w_{n-m+1}^{n-1},\theta),\quad \theta表示待定参数集
p(wn∣wn−m+1n−1)=F(wn,wn−m+1n−1,θ),θ表示待定参数集这种方法相较于
N
−
g
r
a
m
N-gram
N−gram不需要先计算并保存所有的概率值,而是对函数
F
F
F进行优化得到最优的
θ
∗
\theta^*
θ∗就可以了,且
θ
∗
\theta^*
θ∗的量级远小于
N
−
g
r
a
m
N-gram
N−gram的参数量。
关键问题是函数F的构造,下面的NNLM就是通过神经网络来来构造F。
\textbf{关键问题是函数F的构造,下面的NNLM就是通过神经网络来来构造F。}
关键问题是函数F的构造,下面的NNLM就是通过神经网络来来构造F。
N
N
L
M
也是
w
o
r
d
2
v
e
c
算法的基础
\color{red}{NNLM也是word2vec算法的基础}
NNLM也是word2vec算法的基础
NNLM来源于Bengio等人2003年的论文《A neural probabilistic language model . Journal of Machine Learning Research》,该论文提出的神经概率语言模型也用到了词向量一词。NNLM是一个简单易懂的模型,4层结构输入层(Input Layer)、投影层(Projection Layer)、隐藏层(Hidden Layer)、输出层(Output Layer)
对于语料 C C C中的任意词 w w w, C o n t e x t ( w ) Context(w) Context(w)表示其前面的 n − 1 n-1 n−1个词,这样的二元组 ( w , C o n t e x t ( w ) ) (w,Context(w)) (w,Context(w))为一个样本,对于一句话中前面几个词,其前面不够 n − 1 n-1 n−1个词,填充几个向量就好了,它们也参与训练。
其实更多时候,我们将其视为三层的网络结构,看个人怎么理解:
Bengio还考虑了输出层和投影层之间边相连的情况,这样无非是二者之间多了一个权重矩阵,有没有都不影响对算法本质的理解,只是作者发现多加入一个权重矩阵,虽然效果没有提升,但收敛速度会加快,减少迭代次数。
给定语料 C C C和设定词向量的长度 l l l之后,投影层和输出层的规模就确定了 ( n − 1 ) ⋅ l \textbf (n-1)\cdot l (n−1)⋅l,因为输入层包含 C o n t e x t ( w ) Context(w) Context(w)中的 n − 1 n-1 n−1个词,而投影层的 X w X_w Xw则是由 n − 1 n-1 n−1个词向量首尾拼接起来的长向量,长度为 ( n − 1 ) ⋅ m (n-1)\cdot m (n−1)⋅m,计算过程为: { Z w = t a n h ( W X w + p ) Y w = U Z w + q \begin {cases}Z_w=tanh(W_{X_w}+p)\\Y_w=U_{Z_w}+q\end{cases} {Zw=tanh(WXw+p)Yw=UZw+q t a n h tanh tanh:双曲正切函数,作为隐藏层的激活函数。 𝑡 𝑎 𝑛 h 𝑥 = 𝑠 𝑖 𝑛 h 𝑥 𝑐 𝑜 𝑠 h 𝑥 = e x − e − x e x + e − x 𝑡𝑎𝑛ℎ\:𝑥=\frac{𝑠𝑖𝑛ℎ\:𝑥}{𝑐𝑜𝑠ℎ\:𝑥}=\frac{e^x-e^{-x}}{e^x+e^{-x}} tanhx=coshxsinhx=ex+e−xex−e−x
经过计算得到的 Y w = ( y w 1 , y w 2 , y w 3 , . . . , y w n ) T Y_w=(y_{w1},y_{w2},y_{w3},...,y_{wn})^T Yw=(yw1,yw2,yw3,...,ywn)T是长度为 N N N(词汇表的长度)的向量,其分量 y w i y_{wi} ywi还不能表示概率,如果要 y w i y_{wi} ywi表示当上文为 C o n t e x t ( w ) Context(w) Context(w)时下文正好是 D D D(词汇表)中的第 i i i个词时,还需要 s o f t m a x softmax softmax归一化,即 P ( w ∣ C o n t e x t ( w ) ) = e y w , i w ∑ i = 1 N e y w i P(w|Context(w))=\frac{e^{y_{w,i_w}}}{\sum_{i=1}^{N}e^{y_{wi}}} P(w∣Context(w))=∑i=1Neywieyw,iw i w i_w iw表示词 w w w在词典 D D D中的索引。
下面这张图则来自Benjio的论文:
该神经网络需要确定的参数就是我们前面提到的
θ
∗
\theta^*
θ∗,在投影层和隐藏层,其实参数量还是比较大的,后面的
w
o
r
d
2
v
e
c
word2vec
word2vec就有对这部分的优化工作。
与
N
−
g
r
a
m
N-gram
N−gram模型相比,NNLM的优点主要体现在2个方面:
①词语之间的相似性可以通过词向量来体现。举个🌰:如果
t
1
=
t1=
t1=“狗坐在沙发上看电视”这句话出现了
1000
1000
1000次,而
t
2
=
t2=
t2=“猫坐在沙发上看电视”只出现
1
1
1次,用
N
−
g
r
a
m
N-gram
N−gram的话,概率
p
(
t
1
)
p(t1)
p(t1)明显大于
p
(
t
2
)
p(t2)
p(t2),但
p
(
t
1
)
p(t1)
p(t1)、
p
(
t
2
)
p(t2)
p(t2)应该很相近才对。在神经网络语言模型中,有一个假定,就是
拥有了相似上下文的词语也应该有相似的语义
\color{red}{拥有了相似上下文的词语也应该有相似的语义}
拥有了相似上下文的词语也应该有相似的语义,同时概率函数关于词向量是光滑的,即词向量的一个小变化对概率的影响也是小变化。
②该词向量模型自带平滑功能,不会出现像
N
−
g
r
a
m
N-gram
N−gram那样概率为0的情况。
缺点:
①计算量巨大,主要在于两个大矩阵的乘法;
②静态词向量的通病:没有解决一词多义;
③网络的输入窗口为固定值,不能更改;
④整个网络的参数,也是随着词表的增大呈线性增长的。
可以看到,NNLM模型中的词向量是模型训练过程中,目标函数的辅助参数,训练结束后,其实只是模型的一个副产品,但这个副产品很重要。事实上,大部分情况下,词向量和语言模型都是捆绑在一起的,训练后二者同时得到。
参考链接:
1.https://blog.csdn.net/qq_42734492/article/details/109076898
2.https://zhuanlan.zhihu.com/p/265716548
3.https://zhuanlan.zhihu.com/p/111534577
4.https://cloud.tencent.com/developer/news/455980
5.https://blog.csdn.net/u010379324/article/details/79564605
6.https://blog.csdn.net/itplus/article/details/37969519