NLP基础之词向量(Word2Vector)
文章目录
0. 前言
与图像或相比,语言是一种经过人类智力处理后的、更为抽象的数据对象,因此nlp相比cv相比有许多独特之处,研究起来也比较复杂,其中词的表征方式就是一个重要方面。
1. one-hot向量
词(Word)最简单粗暴的一种表征方式(representation)就是one-hot vector。记为词库,为词库大小,则每个词可以表征为一个的向量,其中第维为1,其他维为0 ,是该词在词库中的位置。这种方式的缺点在于:
- 维数可能会很大,词向量会很稀疏
- 无法衡量词与词之间的相似性(任何两个词之间的内积或者余弦相似度都为0)
因此,我们自然而然地想能否将词向量的空间降维成一个子空间,并且这个子空间可以表征出词与词之间的关系。
2. SVD分解
先遍历一个大的文档集,统计每两个词是否配对出现。例如,设文档集里面的句子为如下:
- I enjoy flying.
- I like NLP.
- I like deep learning.
则可以都得到这样的共现矩阵(Co-occurrence Matrix):
对进行SVD分解:
假设选取前个奇异值对应主要成分,则应该选择作为降维后的词嵌入矩阵,这样就得到了词库中每个词的维表征。
3. Word2Vec
前面提到的方法需要存储和计算整个语料库的所有信息,而Word2Vec通过上下文来预测词的概率,用迭代学习参数的方法,可以降低复杂度。它包含两种算法:continuous baf-of-words(CBOW)和skip-gram,两种训练方法:负采样和层级softmax。
3.1. 语言模型——n-gram
用表示一个具有n个词的序列(句子)的概率。Unigram模型假设每个词之间都是相互独立的,也即
Bigram模型假设每个词只与它前面的词有关:
类似地可以得到n-gram的表达式。一般用CBOW或者Skip-gram方法来学习出一个句子的概率。
简而言之,CBOW的目的是通过上下文来预测中心词,而Skip-gram是通过中心词来预测上下文的分布。它们的作用都是将one-hot表示的词“嵌入”到一个低维空间中,这个方法也叫“词嵌入”(Word Embedding)
这种方法的缺点是:
- 随着新词的引入,共现矩阵的大小会经常变化
- 共现矩阵很高维,而且很稀疏
- SVD分解需要很大的时间开销(约)
3.2. Continuous Bag of Words Model(CBOW)
先考虑bigram的情形,也即利用一个词预测下一个词。此时,输入词是语境词(context word),输出词是目标词。
记输入词的one-hot向量为,输出词的one-hot向量为。它们的维度都是,非常大。我们希望将每个词的one-hot向量映射到一个较低的维度上(同时还能较好地表达词的含义以及词与词之间的关系)。为此,我们在输入词和输出词之间增加一个个节点的隐藏层,输入层到隐藏层的权重矩阵记为,称之为输入层矩阵,隐藏层到输出层的权重矩阵记为,称之为输出词矩阵。我们就是希望通过一系列训练数据和上述模型结构学习到输入词矩阵和输出词矩阵。bigram的CBOW模型可以表示为如下的一个两层神经网络结构:
输入层到隐藏层的矩阵运算为:
的每一行代表了某个词的输入词向量(第i行代表第i个词的输入词向量),输入层h其实就是把的第层复制过来了,它代表了输入词的。这个地方隐含了输入词的**函数是线性的且不对该层的输入做任何改变。
隐藏层到输出层可以表示为:
其中的每一行,代表了输出词矩阵的第列。再对进行一个softmax变换,就可以将其每一维都映射到之间,用来代表输出层某一维不为零的概率,这样就可以与输出词的真实one-hot向量进行比较(计算loss function)。
当利用n-gram模型或者利用目标词的前后(对称)的个词来预测目标词时,模型结构与上述类似,只是输入层变为多个词的one-hot向量,输入层到隐藏层的映射关系变为与各个输入词的one-hot向量的和的内积。
CBOW的原理可以概括为:通过中心词前后的词语(上下文)来预测中心词,一般性的流程如下:
- 用表示中心词的one-hot向量,假设用前后各m个词语的上下文来预测中心词,上下文表示为,其中是上下文中某个词的one-hot向量,代表词典。
- 定义输入词矩阵(也叫词嵌入矩阵),它的作用是将每个词都“嵌入”到一个低维空间中(由原来的维变为维)。我们的目的就是用某些算法来高效地学习到这样的词嵌入矩阵。
- 由上面的定义和假设,嵌入后的词(Embedded Word Vectors)可以表示为:,对它们求平均.
- 定义输出词矩阵,用于将上一步的Embedded Word Vectors映射到目标分数向量:
- 将上一步的向量转换为概率:
- 我们希望真实的概率和预测的概率尽可能接近,常用交叉熵来作为损失函数