word2vec
word2vec是用一个一层的神经网络(CBOW的本质)把one-hot形式的词向量映射为分布式形式的词向量,为了加快训练速度,用了Hierarchical softmax,negative sampling 等trick。
词向量(word vector)
首先是词向量(word vector),图像和音频等信号都可以用一个矩阵或者向量表示,所以我们也希望用一个数学方法来表达单词,这样可以方便的用于各种后续计算,这就是词向量。
词向量最简单的方式是1-of-N的one-hot方式,也就是从很大的词库corpus里选V个频率最高的词(忽略其他的) ,V一般比较大,比如V=10W,固定这些词的顺序,然后每个词就可以用一个V维的稀疏向量表示了,这个向量只有一个位置的元素是1,其他位置的元素都是0。One hot方式其实就是简单的直接映射,所以缺点也很明显,维数很大,也没啥计算上的意义。
于是第二种方法就出现了分布式词向量(distributed word representation), 分布式词向量是一个固定大小的实数向量,事前确定它的大小(根据样本规模和网络结构自己设定)比如N=300维或者N=1000维,每个元素都是一个实数,实数的具体值是词库里面每个词通过不同的贡献得来的,所以叫分布式的。而word2vec就是一种学习这个分布式词向量的算法。
词向量训练算法
分布式词向量并不是word2vec的作者发明的,他只是提出了一种更快更好的方式来训练也就是:连续词袋模型(CBOW)和Skip-Gram Model。这两种都是训练词向量的方法,可以选择其一,不过据论文说CBOW要更快一些(1天vs.3天的区别)。
统计语言模型(statistical language model)就是给你几个词,在这几个词出现的前提下来计算某个词出现的(事后)概率。CBOW也是统计语言模型的一种,顾名思义就是根据某个词前面的C个词或者前后C个连续的词,来计算某个词出现的概率。Skip-Gram Model相反,是根据某个词,然后分别计算它前后出现某几个词的各个概率。
基础的训练算法:
在输入层,一个词被转化为One-Hot向量。
然后在第一个隐层,输入的是一个W*x+b(x就是输入的词向量,W、b是参数),做一个线性模型,注意已这里只是简单的映射,并没有非线性激活函数,当然一个神经元可以是线性的,这时就相当于一个线性回归函数。
第三层可以简单看成一个分类器,用的是Softmax回归,最后输出的是每个词对应的概率
举个例子:
如果我们的语料仅仅有这3句话: “the dog saw a cat”, “the dog chased the cat”, “the cat climbed a tree”. 那么单词字典只有8个单词: “the”, “dog”, “saw”, “a”, “cat”, “chased”, “climbed”, “tree”.那么V=8, 输入层的初始就可以是:
[1, 1, 1, 1, 1, 1, 1, 1] 代表: [“the”, “dog”, “saw”, “a”, “cat”, “chased”, “climbed”, “tree”]
输入[“”, “dog“, “”, “”, “”, “”, “”, “”] 可以表示为: [0, 1, 0, 0, 0, 0, 0, 0]
输入[“”, “”, “saw“, “” , “”, “”, “”, “”] 可以表示为: [0, 0, 1, 0, 0, 0, 0,0]
如果是在字典中有的, 就用1表示W 的大小是NxV的, 通过训练完毕后得到权重 W_1和W_0 ,当只要输入单词, 就能预测出最符合这个上下文的下一个单词时,这时候的 W_1和W_0参数的精度最高。
CBOW算法
输入层: 2m×|V|个节点2m个词的one-hot 编码表示
输入层到投影层到连接边:输入词矩阵 V:n×|V|维;
投影层: n 个节点,上下文共 2m 个词的one-hot 表示和输入词矩阵相乘后得到的词向量求和再平均的值,也就是 V*x 的求和再平均 ;
投影层到输出层的连接边:输出词矩阵 U:|V|×n 维;
输出层: |V|个节点,先经过softmaiii个节点代表w_iii的概率,后得到最大概率词的one-hot表示。
然后词向量就是神经网络里的参数,生成词向量的过程就是一个参数更新的过程。首先将one-hot向量转换成低维词向量的这一层中,某个词的one-hot表示可看成是 1|V| (|V|是词总数)的矩阵,与这个系数矩阵 V:n×|V|(维),相乘之后1n的向量,这个向量就是这个词对应的词向量了。那V:n×|V|维 的矩阵,每一列就对应了每个单词的词向量。在神经网络中,训练不断更新这个矩阵。
另外,对于投影层到输出层的输出词矩阵 U:|V|×n 的每一行,也是对于每个单词的词向量。然后词向量具体怎么得到呢?这类似一个查表,比如输入节点有个词x的one-hot是 [1,0,0,…,0],他与输入词矩阵相乘 Ux^T 就得到该词的词向量(因为one-hot 里值是 1 的那个位置,对应的 n个权重被激活,其实就是从一个 n|V| 的随机词向量矩阵里,抽取某一列)。或者在输出节点若得到词x的one-hot是 [1,0,0,…,0],它和输出词矩阵 x*V 也得到该词的词向量。这也就是该词对应的输入向量和输出向量,一般我们只用输入向量。
Skip-Gram模型
Skip-gram模型其实和CBOW模型很相似,都是相关词预测其他词,只是变成了由中心词来预测上下文的词。在结构上也是这样,两种角度,其中对于CBOW第二种结构或角度的情况如下图:
以上是输入层是one-hot,输出层也是one-hot的结构,具体里面的参数含义和CBOW相对应。
Word2vec 本质上是一个语言模型,它的输出节点数是 V 个,对应了 V 个词语,也是一个多分类问题,但实际当中,词语的个数非常非常多,直接softmax来计算会给计算造成很大困难,所以需要用技巧来加速训练。word2vec对应的两个加速技巧hierarchical softmax(利用霍夫曼树)和negative sampling(负采样)。注意:这两个技巧只是加速训练的技巧,在此就不在详细描述了,可以参考下面两篇博文。
http://www.cnblogs.com/pinard...
http://www.cnblogs.com/pinard...
参考资料:
https://zhuanlan.zhihu.com/p/...
https://zhuanlan.zhihu.com/p/...
http://www.cnblogs.com/pinard...