从视频的内容属性中提取特征,是较为常见的方法。但这依赖于视频有很好的属性标注,即给视频维护一套丰富且精准的标签系统。本文介绍用Word2vec算法,不依赖视频标签,仅从用户观看历史中即可提取出很好的视频特征。
Word2vec是“Word to vector”的缩写,顾名思义,是将单词转化为数值向量的一种方法。Word2vec从原理上,又分为CBOW(countinous-bag-of-words)模型和SG(skip-gram)模型。无论哪种模型,都可以给单词提供一种富含语义的刻画。等等,单词的“语义”是什么鬼?什么样的一种刻画又可以称得上是富含语义的?
这先要从单词最基本的的向量化方式,onehot表示法说起。有一个词汇表,{猫,狗,榴莲}。那么,猫可以表示为[1, 0, 0],狗=[0, 1, 0],榴莲=[0, 0, 1]。这里有一个问题,即“猫”和“狗”之间的相似度与“猫”和“榴莲”之间的相似度是一样的。但是,我们想要的表示方式,可以告诉我们“猫”和“狗”都是萌宠,它们之间应该更接近一些。”应该更接近一些”这种东西,就是以上所说的“语义”。
Word2vec得到的向量表示,可以做到:Vec(“猫”) - Vec(“猫粮”) ≈ ≈ Vec(“狗”) - Vec(“狗粮”) 这样的效果。这就是富含语义的表现。
Word2vec模型,包括CBOW模型和SG模型,它们都是只包含一个隐含层的三层神经网络模型。因为CBOW的思想是“根据上下文,来预测单词”,而SG则是“根据单词,来预测上下文”,这两者在结构上刚好相反。
图一、CBOW模型结构
图二、SG模型结构
其中, V V 代表词汇表中单词的个数, N N 为隐含层的维度, C C 则是“词袋”中单词的个数,也即用多少个单词来预测接下来的单词。 WV×N W V × N 为输入层到隐含层之间的权重矩阵, W′V×N W V × N ′ *为隐含层到输出层之间的权重矩阵。输入层到隐含层的激活函数,是简单的线性函数;隐含层到输出层的激活函数,是softmax函数。
下面以CBOW为例,说明其迭代更新过程;对SG模型,结论可以类推。在CBOW模型中,当上下文只有一个单词时,最为简单。其结构相应的变为
图三、One-word context CBOW模型结构
隐含层计算方式如下式(1):
输出层的输入数据计算方式如下式(2):
输出层计算方式如下式(3):
目标函数
假设在一个样本中上下文单词是 wI w I ,对应的输出单词是 wO w O ,真实输出单词在词典中的序号为 j∗ j ∗ 。我们的目标是在已知输入上下文的条件下,让输出对应于真实输出的概率最大,即最大化相应的条件概率。
因此,我们的目标函数为:
为了让目标函数 E E 最小化,我们要让神经网络学习出最佳参数 w′ij w i j ′ 和 wij w i j 。
更新参数 w′ij w i j ′
∂E∂w′ij ∂ E ∂ w i j ′ 的求解比较简单。从式(1)可以看出, hi h i 不是 w′ij w i j ′ 的函数,再结合式(5)即可得到下式(6)。
即得 w′ij w i j ′ 的更新方式如下式(7)。
更新参数 wij w i j
∂E∂wij ∂ E ∂ w i j 的求解稍微复杂一些。式(1)表明, E E 是 hi h i 的函数;同时式(5)表明, hi h i 又是 wij w i j 的函数。因此,
从式(5)得到
从式(1)得到
整合式(8)-(10)得到
即得 wij w i j 的更新方式如下式(12)。
至此,One-word context CBOW算法原理说明完毕。
1)spark mllib提供了Word2vec的分布式实现,因此相比与tensorflow Word2vec理论上运行速度更快。
2)但是spark Word2vec为了保证准确性,有两个条件:1、输入数据分成的numPartitions不能太大(默认值为1),2、迭代次数不能大于numPartitions(默认值为1)。源码见下图
图四、spark setNumPartitions函数源码
图五、spark setNumIterations函数源码
3)作者使用numPartitions=5,只要numIterations > 1,就会导致结果发散。即最后得到的vector的内容全为inf或-inf。而tensorflow不存在这个问题。
4)为降低Word2vec参数更新的计算复杂度,现已有Hierarchical softmax和Negative samping两种优化方式。在tensorflow Word2vec中有两个相关参数,使用非常方便,比如negative=1即表示采用负采样,否则不用。
5)tensorflow使用GPU运行,相对于CPU快非常多。2000多万的sentence,1万多word,用GPU tensorflow几个小时即可完成。因此,综合来讲,使用Word2vec更推荐tensorflow平台。
1)将用户观看历史保存到文件中
2)调用tensorflow Word2vec模型,将用户观看历史作为输入,每个用户的观看历史作为一个sentence,每个节目作为一个Word。运行程序,得到一个Word2vec的model
3)调用Word2vec的方法,从model中提取出视频feature。【Done】
[1] word2vec Parameter Learning Explained, Xin Rong
[2] tensorflow Word2vec官方API
[3] spark Word2vec官方API