词向量相关
-

词袋模型
将自然语言文本的每个词作为一个特征。因此对应的特征向量即这些特征的组合。基于这种思想的模型就是词袋模型(Bag of Words),也叫向量空间模型(Vector Space Model)。
one-hot
设词典的大小为n(词典中有n个词),假如某个词在词典中的位置为k,则设立一个n维向量,第k维置1,其余维全都置0。这个思想就是one-hot编码,中文叫独热编码。
“我/喜欢/你”;
“你/喜欢/你/的/狗狗”;
“你/是/狗狗”。
这个词典依次包含[我,喜欢,你,的,是,狗狗]。
根据one-hot编码,
“我”:[1,0,0,0,0,0],
“喜欢”:[0,1,0,0,0,0],
以此类推。一个样本的特征向量即该样本中的每个单词的one-hot向量直接相加。这三个样本的特征向量便会表示为:
我喜欢你:[1,1,1,0,0,0]
你喜欢你的狗狗:[0,1,2,1,0,1]
你是狗狗:[0,0,1,0,1,1]
缺点:
1.维度灾难
涉及到的单词很多时,词典会变得超大,动辄几千上万维。因此每个样本的特征向量也会变得极其稀疏(大部分维度的值为0)。
2.语义的忽略word-embedding
中文叫词向量,也叫词嵌入。实质就是将单词编码成低维实数向量。(专业的说法是将单词映射到一个低维空间,就像一个嵌入的过程,因此叫word-embedding)
比如“狗”或许会被编码成[0.192, 0.221, -0.442, …]
语义关系的表示:比如我们的词向量限制为2维。那么词“猫”、“狗”、“开心”、“惊讶”、“手机”映射成词向量后在向量空间中可能是这样子的:余弦相似度:度量夹角来计算向量之间距离。
向量运算:语义相近被编码到邻近区域且支持简单的语义运算
“中国”+“首都”=“北京”;
“王子”-“公主”=“男”-“女“;Word2vec
From: Mikolov T, Chen K, Corrado G S, et al. Efficient Estimation of Word Representations in Vector Space[C]. international conference on learning representations, 2013.
Word2vec即简单化的神经网络。
输入是one-hot vector,Hidden Layer没有激活函数,也就是线性的单元。Output Layer维度跟Input Layer的维度一样,用的是Softmax回归。
CBOW(Continuous Bag-of-Words Model):通过上下文预测当前值,训练输入是某个特征词的上下文相关的词对应的词向量,输出这特定的一个词的词向量。
Skip-gram (Continuous Skip-gram Model):用当前词来预测上下文,输入是特定的一个词的词向量,输出是特定词对应的上下文词向量。
CBOW
1 输入层:上下文单词的one-hot. {假设单词向量空间dim为V,上下文单词个数为C}
2 所有onehot分别乘以共享的输入权重矩阵W. {VN矩阵,N为自己设定的数,初始化权重矩阵W}
3 所得的向量 {因为是onehot所以为向量} 相加求平均作为隐层向量, size为1N.
4 乘以输出权重矩阵W’ {NV}
5 得到向量 {1V} 激活函数处理得到V-dim概率分布 {PS: 因为是onehot嘛,其中的每一维斗代表着一个单词}
6 概率最大的index所指示的单词为预测出的中间词(target word)与true label的onehot做比较,误差越小越好(根据误差更新权重矩阵)所以,需要定义loss function(一般为交叉熵代价函数),采用梯度下降算法更新W和W’。
训练完毕后,输入层的每个单词与矩阵W相乘得到的向量的就是我们想要的词向量(word embedding),这个矩阵(所有单词的word embedding)也叫做look up table。
也就是说,任何一个单词的onehot乘以这个矩阵都将得到自己的词向量。有了look up table就可以免去训练过程直接查表得到单词的词向量了。Skip-Gram
接下来我们来看看如何训练我们的神经网络。假如我们有一个句子“The dog barked at the mailman”。
首先我们选句子中间的一个词作为我们的输入词,例如我们选取“dog”作为input word;
有了input word以后,我们再定义一个叫做skip_window的参数,它代表着我们从当前input word的一侧(左边或右边)选取词的数量。如果我们设置skip_window=2,那么我们最终获得窗口中的词(包括input word在内)就是[‘The’, ‘dog’,‘barked’, ‘at’]。skip_window=2代表着选取左input word左侧2个词和右侧2个词进入我们的窗口,所以整个窗口大小span=2x2=4。
另一个参数叫num_skips,它代表着我们从整个窗口中选取多少个不同的词作为我们的output word,当skip_window=2,num_skips=2时,我们将会得到两组 (input word, output word) 形式的训练数据,即 (‘dog’, ‘barked’),(‘dog’, ‘the’)。
神经网络基于这些训练数据将会输出一个概率分布,这个概率代表着我们的词典中的每个词是output word的可能性。这句话有点绕,我们来看个栗子。第二步中我们在设置skip_window和num_skips=2的情况下获得了两组训练数据。假如我们先拿一组数据 (‘dog’, ‘barked’) 来训练神经网络,那么模型通过学习这个训练样本,会告诉我们词汇表中每个单词是“barked”的概率大小。
模型的输出概率代表着到我们词典中每个词有多大可能性跟input word同时出现。举个栗子,如果我们向神经网络模型中输入一个单词“中国“,那么最终模型的输出概率中,像“英国”, ”俄罗斯“这种相关词的概率将远高于像”苹果“,”蝈蝈“非相关词的概率。因为”英国“,”俄罗斯“在文本中更大可能在”中国“的窗口中出现。我们将通过给神经网络输入文本中成对的单词来训练它完成上面所说的概率计算。
面的图中给出了一些我们的训练样本的例子。我们选定句子“The quick brown fox jumps over lazy dog”,设定我们的窗口大小为2(window_size=2),也就是说我们仅选输入词前后各两个词和输入词进行组合。下图中,蓝色代表input word,方框内代表位于窗口内的单词。Training Samples(输入, 输出)负采样
对于训练语言模型来说,softmax层非常难算,毕竟你要预测的是当前位置是哪个词,那么这个类别数就等同于词典规模,因此动辄几万几十万的类别数。但是,如果我们的目标不在于训练一个精准的语言模型,而只是为了训练得到语言模型的副产物-词向量,那么其实只需要用这里隐含的一个计算代价更小的“子任务”。
Ex: 找出10000张写有数字的卡片中的最大值。但是如果把里面的最大值事先抽出来,跟五张随机抽取的卡片混到一起,再选出其中的最大值。
负采样就是这个思想,即不直接让模型从整个词表找最可能的词了,而是直接给定这个词(即正例)和几个随机采样的噪声词(即采样出来的负例),只要模型能从这里面找出正确的词就认为完成目标。所以这个想法对应的目标函数即:这里
是正例,
是随机采样出来的负例(采样k个),
是sigmoid函数。然后即最大化正例的似然,最小化负例的似然。
这种负采样的思想被成功的应用在了BERT模型中,只不过粒度从词变成了句子。 -
感谢lz分享学习笔记,但貌似文中有几张图片无法显示,有空可以重新上传一下哈~期待后续分享