word2vec相关技术总结

对中文进行NLP,首先要对要处理的文本进行分词,再对每一个词建立向量空间,即word2Vec。

简单的词向量-one-hot vector

最简单的词向量可采用one-hot vector,对每个词用单位向量来进行表示。比如对所有的词 w 1 w_1 w1, w 2 w_2 w2, … w ∣ V ∣ ∈ V w_{|V|} \in V wVV,对其中的词 w i w_i wi,表示的词向量为 ( 0 , 0 , . . . , 1 , 0 , . . . 0 ) T ∈ { 0 , 1 } ∣ V ∣ (0,0,...,1,0,...0)^T \in \{0,1\}^{|V|} (0,0,...,1,0,...0)T{0,1}V,其中向量在第 i i i个位置为1,其它为0。
这种词向量会导致建立的维度太大,矩阵过于稀疏,现在用的不多了。

基于频度的共生矩阵的方法

我们可以先建立一个 R ∣ V ∣ × ∣ V ∣ R^{|V| \times |V|} RV×V的矩阵。比如以下三句话:

  • 我 热爱 祖国
  • 我 热爱 人民
    以每句话中的每一个词,作为中心词,然后看与中心词相邻的词一起出现了几次。假设我们的训练集只有这三句话,也就是 { 我 , 热 爱 , 祖 国 , 人 民 } = V \{我,热爱,祖国,人民\} = V {,,,}=V;同时假定我们只看相邻距离为1的词。比如我+热爱,出现了2次;我+祖国出现了1次;我+人民出现了1次等等。这样建立的矩阵就为
    我 热 爱 祖 国 人 民 X = ( 0 2 0 0 2 0 1 1 0 1 0 0 0 1 0 0 ) 我 热 爱 祖 国 人 民 \begin{aligned} &\begin{matrix} 我&热爱&祖国&人民 \end{matrix} \\ X=&\begin{pmatrix} 0 & 2 & 0 & 0 \\ 2 & 0 & 1 & 1 \\ 0 & 1 & 0 & 0 \\ 0 & 1 & 0 & 0 \end{pmatrix} \begin{matrix} 我\\热爱\\祖国\\人民 \end{matrix} \end{aligned} X=0200201101000100
    再对该矩阵进行奇异值分解(SVD),即 X = U Σ V T X=U\Sigma V^T X=UΣVT,其中矩阵 U , Σ , V ∈ R ∣ V ∣ × ∣ V ∣ U , \Sigma, V\in R^{|V| \times |V|} U,Σ,VRV×V U = ( u 1 , u 2 , . . . , u ∣ V ∣ ) U=(u_1,u_2, ..., u_{|V|}) U=(u1,u2,...,uV) Σ = d i a g ( σ 1 , σ 2 , . . . , σ ∣ V ∣ ) \Sigma=diag(\sigma_1,\sigma_2,...,\sigma_{|V|}) Σ=diag(σ1,σ2,...,σV) V = ( v 1 , . . . , v ∣ V ∣ ) V=(v_1,...,v_{|V|}) V=(v1,...,vV),其中 u i u_i ui, v i v_i vi均为 ∣ V ∣ |V| V维的向量。
    然后再进行降维至 K K K维,即 U K = ( u 1 , u 2 , . . , u K ) U_K=(u_1,u_2,..,u_K) UK=(u1,u2,..,uK), V K = ( v 1 , v 2 , . . , v K ) V_K=(v_1, v_2, .., v_K) VK=(v1,v2,..,vK), Σ K = ( σ 1 , . . . , σ k ) \Sigma_K=(\sigma_1,...,\sigma_k) ΣK=(σ1,...,σk),这样 X K = U K Σ V K T X_K=U_K\Sigma V_K^T XK=UKΣVKT,即为 ∣ V ∣ × K |V| \times K V×K的矩阵,矩阵 X K X_K XK的第 i i i行可认为是单词 i i i对应的词向量 x i T x_i^T xiT
    注意到对 X X X进行SVD,计算复杂度可高达 O ( ∣ V ∣ 3 ) O(|V|^3) O(V3),因此现在用的也少。

基于Word2Vec的方法

CBOW法

将每一句话的每一个单词看作是一个中心词,和中心词相邻的距离为 m m m的词对应词为上下文词。CBOW法是已知上下文词,推测中心词为哪个词。比如假定 m = 1 m=1 m=1,看以下这句话

  • 我 明天 就 回家 了

比如对中心词“就”,和它相邻距离为1的词为"明天"和“回家”。CBOW的中心思想是,已知"明天"和“回家”,求所有的词向量,使得"就“出现的概率最大
假定我们就考虑 { 我 , 明 天 , 就 , 回 家 , 了 } = V \{我,明天,就,回家,了\}=V {,,,,}=V,可以建立一个只有一层隐藏层(两层全连接层)的神经网络。神经网络的输入、输出均采用one-hot vector编码,即对”我“编码为 ( 1 , 0 , 0 , 0 , 0 ) T (1,0,0,0,0)^T (1,0,0,0,0)T,明天编码为 ( 0 , 1 , 0 , 0 , 0 ) T (0,1,0,0,0)^T (0,1,0,0,0)T,依次类推。那么神经网络的结构可以表示为

|V|*K
K*|V|
2m*|V|的矩阵
隐藏层
各行求平均
输出层

其中 K K K为我们需要计算的词向量的长度。隐藏层之前的 W ∣ V ∣ × K W_{|V| \times K} WV×K的weight matrix定义为我们想要的输入词矩阵,其中矩阵的每一行对应一个单词的输入词向量 w i T w_i^T wiT,隐藏层之后的 U K × ∣ V ∣ U_{K \times |V|} UK×V定义为我们想要的输出词矩阵,其中矩阵的每一列对应一个单词的输出词向量 u i u_i ui
很明显,这个并不是一个标准的神经网络,因为隐藏层的输出并没有激活,而是对输出的结果各行求了平均。输入到隐藏层的矩阵为 W ~ 2 m ∗ K \tilde{W}_{2m*K} W~2mK,其中 W ~ \tilde{W} W~的每一行正好对应的是输入的上下文词的输入词向量,即 ( w j c − m , . . . , w j c − 1 , w j c + 1 , . . . , w j c + m ) T (w_{j_{c-m}},...,w_{j_{c-1}},w_{j_{c+1}},...,w_{j_{c+m}})^T (wjcm,...,wjc1,wjc+1,...,wjc+m)T,求完平均后矩阵为
w c T ˉ = 1 2 m ∑ i = c − m i = c + m w j i T \bar{w_c^T }= \frac{1}{2m}\sum_{i=c-m}^{i=c+m}w_{j_i}^T wcTˉ=2m1i=cmi=c+mwjiT
其中, w c T ˉ \bar{w_c^T} wcTˉ K K K维向量。对数据求 s o f t m a x softmax softmax,即
o u t p u t = s o f t m a x ( w c T ˉ u 1 , . . . , w c T ˉ u ∣ V ∣ ) = ( y ^ 1 , . . . , y ^ ∣ V ∣ ) \begin{aligned} output &= softmax(\bar{w_c^T}u_1, ..., \bar{w_c^T}u_{|V|}) \\ &= (\hat{y}_1,...,\hat{y}_{|V|}) \end{aligned} output=softmax(wcTˉu1,...,wcTˉuV)=(y^1,...,y^V)
训练集里,输出应为 ( y 1 , . . . , y ∣ V ∣ ) (y_1, ..., y_{|V|}) (y1,...,yV),定义输出的损失函数为
L = − ∑ i y i log ⁡ y ^ i L=-\sum_i y_i \log{\hat{y}_i} L=iyilogy^i
注意到 ( y 1 , . . . , y ∣ V ∣ ) (y_1, ..., y_{|V|}) (y1,...,yV)采用的是one-hot vector编码,所以对于输入的中心词 c c c,其对应的 y c = 1 y_c=1 yc=1,同时 y i = 0 , ∀ i ≠ c y_i=0, \forall i \neq c yi=0,i=c。这样损失函数可以简化为
L = − log ⁡ y ^ c = − w c T ˉ u c + log ⁡ ∑ i = 1 ∣ V ∣ exp ⁡ w c T ˉ u i \begin{aligned} L&=-\log{\hat{y}_c} \\ &=-\bar{w_c^T}u_c+\log{\sum_{i=1}^{|V|}{ \exp{\bar{w_c^T}u_i } }} \end{aligned} L=logy^c=wcTˉuc+logi=1VexpwcTˉui

Skip-Gram法

Skip-Gram与CBOW正好相反,是输入中心词的one-hot vector,输出上下文词的one-hot vector,对应的神经网络的结构为

|V|*K
K*|V|
K*|V|
K*|V|
K*|V|
1*|V|的矩阵
隐藏层
复制出2m路
取分量j(c-m)
取分量j(c-1)
取分量j(c+1)
取分量j(c+m)

隐藏层的输出为 w c T w_c^T wcT K K K维向量,这样到输出层的向量为
w c T ( u 1 , . . . , u ∣ V ∣ ) = ( w c T u 1 , . . . , w c T u ∣ V ∣ ) \begin{aligned} &w_c^T(u_1,...,u_{|V|}) \\ &=(w_c^Tu_1,...,w_c^Tu_{|V|}) \end{aligned} wcT(u1,...,uV)=(wcTu1,...,wcTuV)
其中输出的第 i i i个分量,对应的损失函数为
L i = − log ⁡ y ^ c − m + i = − w c T u j c − m + i + log ⁡ ∑ i = 1 ∣ V ∣ exp ⁡ w c T u i \begin{aligned} L_i &= -\log{\hat{y}_{c-m+i}} \\ &= -w_c^Tu_{j_{c-m+i}} + \log{\sum_{i=1}^{|V|}\exp{w_c^Tu_i} } \end{aligned} Li=logy^cm+i=wcTujcm+i+logi=1VexpwcTui
总损失函数为
L = ∑ i = 0 , i ≠ m 2 m L i = − ∑ i = 0 , i ≠ m 2 m w c T u j c − m + i + 2 m log ⁡ ∑ i = 1 ∣ V ∣ exp ⁡ w c T u i \begin{aligned} L&=\sum_{i=0,i \neq m}^{2m}L_i \\ &=-\sum_{i=0,i \neq m}^{2m}w_c^Tu_{j_{c-m+i}} + 2m\log{\sum_{i=1}^{|V|}\exp{w_c^Tu_i} } \end{aligned} L=i=0,i=m2mLi=i=0,i=m2mwcTujcm+i+2mlogi=1VexpwcTui
有了损失函数,就可以将 L L L分别对 u i u_i ui w i w_i wi取偏导,通过随机梯度法的迭代,去解出词向量矩阵的最优值。

改进1——Negative Sampling

上述方法中的 L L L,都涉及到要对 ∣ V ∣ |V| V个数求和。这样每次采用梯度法迭代时,对每一个分量求梯度都会有 ∣ V ∣ |V| V个求和运算。由于汉语的词汇量很大,达几十万个。这种方法会导致每次迭代的运算量过大,收敛慢。因此,需要考虑定义一个更加有效的损失函数 L L L
D \mathcal{D} D为语料库中的中心词和上下文词构成的集合。现在我们考虑另一个集合 D ^ \mathcal{\hat{D}} D^,表示所有中心词不对应的上下文词构成的集合。我们取求 U U U W W W,使得以下值最大
L = − log ⁡ ∏ ( c , a ) ∈ D P ( D = 1 ∣ c , a , U , W ) ∏ ( c , a ) ∈ D ^ P ( D = 0 ∣ c , a , U , W ) L=-\log{ \prod_{(c,a) \in \mathcal{D}}P(D=1|c,a,U,W)\prod_{(c,a) \in \mathcal{\hat{D}}}P(D=0|c,a,U,W) } L=log(c,a)DP(D=1c,a,U,W)(c,a)D^P(D=0c,a,U,W)
其中 P ( D = 1 ∣ c , a , U , W ) P(D=1|c,a,U,W) P(D=1c,a,U,W) ( c , a ) (c,a) (c,a)作为中心词和上下文词出现在语料库的概率,利用 s o f t m a x softmax softmax可将其定义为
P ( D = 1 ∣ c , a , U , W ) ≡ 1 1 + exp ⁡ ( − w c T u a ) ≡ σ ( w c T u a ) P(D=1|c,a,U,W) \equiv \frac{1}{1+\exp{(-w_c^Tu_a)}} \equiv \sigma(w_c^Tu_a) P(D=1c,a,U,W)1+exp(wcTua)1σ(wcTua)
这样, L L L可以化简为
L = − ∑ ( c , a ) ∈ D log ⁡ σ ( w c T u a ) − ∑ ( c , a ) ∈ D ^ log ⁡ σ ( − w c T u a ) L=-\sum_{(c,a) \in \mathcal{D}}\log\sigma(w_c^Tu_a)-\sum_{(c,a) \in \mathcal{\hat{D}}} \log \sigma(-w_c^Tu_a) L=(c,a)Dlogσ(wcTua)(c,a)D^logσ(wcTua)
在实际中 D ^ \mathcal{\hat{D}} D^可以通过随机取样获得。注意到skip-gram的损失函数 L i L_i Li
L i = − log ⁡ exp ⁡ w c T u j c − m + i + log ⁡ ∑ i = 1 ∣ V ∣ exp ⁡ w c T u i L_i= -\log \exp w_c^Tu_{j_{c-m+i}} + \log{\sum_{i=1}^{|V|}\exp{w_c^Tu_i} } Li=logexpwcTujcm+i+logi=1VexpwcTui
可以改写为
L i = − log ⁡ σ ( w c T u j c − m + i ) − log ⁡ ∑ ( c , a ) ∈ D ^ σ ( − w c T u a ) L_i=-\log \sigma{(w_c^Tu_{j_{c-m+i}})} - \log{\sum_{(c,a) \in \mathcal{\hat{D}}}}\sigma{(-w_c^Tu_a)} Li=logσ(wcTujcm+i)log(c,a)D^σ(wcTua)
而CBOW的损失函数 L L L则可以改写为
L = − log ⁡ σ ( w c T ˉ u c ) − log ⁡ ∑ ( c , a ) ∈ D ^ σ ( − w c T ˉ u a ) L=-\log\sigma(\bar{w_c^T}u_c)-\log{\sum_{(c,a) \in \mathcal{\hat{D}}}{ \sigma (-{\bar{w_c^T}u_a }) }} L=logσ(wcTˉuc)log(c,a)D^σ(wcTˉua)
这样,对应每个中心词c,我们只需要随机找出一部分不是它上下文的词a就可以。同时要注意到随机取a时也要考虑到a本身在语料库中出现的频率,令 f r e q ( a ) = c o u n t ( a ) / ∣ T e x t ∣ freq(a)=count(a)/|Text| freq(a)=count(a)/Text,那取a的概率建议为 f r e q ( a ) 3 / 4 freq(a)^{3/4} freq(a)3/4。所以negative sampling算法在为常见词建立词向量空间,是适合的。

改进2-Hierarchical Softmax

针对于非常见词,更合适的改进算法是Hierarchical softmax方法。
在这里插入图片描述
图中给出了Hierarchical softmax的算法。首先,将语料库的所有词建成一个二叉树的结构,其中每一个词都是这个树的叶子节点。(算法作者建议构建成Huffman树,频率高的词位于层数低的叶子节点,频率低的词位于层数高的叶子节点)。
图里以skip-gram为例,给定要训练的中心词 c c c和上下文词 a a a,找从根节点到 a a a的路径。定义给定中心词 c c c,出现上下文词 a a a的概率为
P ( a ∣ c ) = P ( a 在 节 点 6 的 右 边 ∣ c ) ∗ P ( a 在 节 点 4 左 边 ∣ c ) ∗ P ( a 在 节 点 3 右 边 ∣ c ) = σ ( v 6 T v c ) ∗ σ ( v 4 T v c ) ∗ σ ( − v 3 T v c ) \begin{aligned} P(a|c)&=P(a在节点6的右边|c)*P(a在节点4左边|c)*P(a在节点3右边|c) \\ &=\sigma(v_6^Tv_c)*\sigma(v_4^Tv_c)*\sigma(-v_3^Tv_c) \end{aligned} P(ac)=P(a6c)P(a4c)P(a3c)=σ(v6Tvc)σ(v4Tvc)σ(v3Tvc)
这里利用了 σ ( x ) + σ ( − x ) = 1 \sigma(x)+\sigma(-x)=1 σ(x)+σ(x)=1的性质。
于是损失函数即为
L i = − log ⁡ P ( a ∣ c ) = − ∑ n 为 到 a 的 节 点 log ⁡ σ ( v n T v c ∗ s n ) s n = { 1 a 在 节 点 n 的 右 边 − 1 a 在 节 点 n 的 左 边 \begin{aligned} L_i &= -\log P(a|c)=-\sum_{n为到a的节点}\log\sigma(v_n^Tv_c*s_n) \\ s_n&=\begin{cases} 1 & a在节点n的右边\\ -1 & a在节点n的左边 \end{cases} \end{aligned} Lisn=logP(ac)=nalogσ(vnTvcsn)={11anan
和skip-gram原算法的 L i L_i Li进行比较可以发现,这里的计算 L i L_i Li复杂度取决于树的高度,即 O ( log ⁡ 2 ∣ V ∣ ) O(\log_2|V|) O(log2V),而不再是整个词汇的数目 O ( ∣ V ∣ ) O(|V|) O(V),大大减少了计算的复杂度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值