最简单的编码,我相信地球人都能想到,没错,就是每个词用一个数字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。
把已有文本的所有词去重后放一个袋子里,就是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,这是判断词的重要性算法,以后再说。
语言模型的目标是啥呢?其实就是让语言字符拼起来能是一句人话,咋判断哪个字符串是最像人话的呢,没错,概率!概率越大越可能拼对了。语言模型的本质是对语句的概率分布建模。数学语言就是:
给定任意的字符串 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,即由于语料的稀疏性,有些词序列找不到,所以需要对数据进行平滑处理,简单列几种数据平滑的方法:
优点:算法简单,解决了概率为0的问题
缺点:给训练语料中没有出现过的词分配了太多的概率空间,认为所有未出现的词概率相等也不合理。
N-gram语言模型的优点:
1.bigram,trigram 实现简单,能够很好地应用在一些经典场景中,例如检查拼写错误(极大似然句子概率)
2.常见搜索引擎的输入下拉帮助,就是通过n-gram来实现的
3.可解释性强,易于理解和调试。
4.易于增量实现和并行训练。
N-gram语言模型的缺点:
- 需要解决数据稀疏性的问题,需要利用平滑算法。
- 由于是离散型变量,没有办法度量词语之间相似度。
- 模型巨大,与|V| 词库大小呈指数增长。
讲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