当前位置: 首页 > 后端技术 > Python

词向量技术

时间:2023-03-26 16:40:32 Python

词向量表示基本词的one-hot编码存在以下问题:词的意思不能用向量的形式表达。向量维数很高,而且很稀疏,不衡量两个词之间的语义相似度。由于one-hotencoding独特的缺点,一种新的way-wordvector(也叫分布式表示)表示如下:One-hotencodedwordvector(distributedrepresentation)we[1,0,0,0,0][0.1,0.2,0.4,0.2]爬山[0,1,0,0,0][0.2,0.3,0.1,0.2]当词向量存在分布式表示时,可以计算两个词的相似度当然,效果取决于词向量的质量。词向量的维度由训练词向量的模型手动定义。Bert、Glove、SkipGram、ELMo等学习词向量的模型从上面可以看出:向量在分布式表示上是稠密的,很少有0分布。表达的表达维数比one-hot编码的词向量要小很多。在一定程度上可以表达词的意思,在一定程度上可以表达两个词的相似程度。总结如下:One-hotencodeddistributedrepresentation不能表达词量的意思,可以认为是表示词的意思。矢量非常稀疏。密集向量的长度等于词库的长度。向量的长度是一个超参数。无需培训。SkipGram模型需要训练。参考论文:EfficientEstimationofWordRepresentationsinVectorSpaceSkipGram模型的核心是通过中心词来预测周围的词。也就是说,如果我们的词向量训练得更准确,预测效果就会更强。事实上,这就是我们的目标函数。为了便于理解,为什么可以通过中心词来预测周围的词呢?我们来理解一下背后的逻辑:这里有一个假设,叫做分布式假设,意思是如果两个词相邻,有可能这两个词的意思比较相似,所以我可能会通过一个词来预测它的相似的话。下面记录Skipgram的推导:假设我们有这样一个数据集{\(s_1,s_2,s_3,s_4,s_5\)},当然我们的数据不可能这么小,数据一般是一篇文章或者直接一篇在网页上复制一段话也是我们的数据。通过相邻词的相似思维,我们要用上面的样本训练词向量,我们可以这样做:以下条件概率的最大可能乘积:$$p(s2|s1)p(s1|s2)·p(s3|s2)·p(s2|s3)·p(s3|s4)·p(s5|s4)·p(s4|s5)$$可以发现我们的P(相邻词|centerword)做一个循环,所以可以推导出一个更通用的公式:w-centerword,c-word属于wcontext\inContext}p(c|w;\theta)\tag{1}$$$$\theta=arg\,\max_{\theta}\sum_{w\inText}\sum_{c\inContext}logp(c|w;\theta)\tag{2}$$对于条件概率\(p(c|w;\theta)\),我们希望表示为\(\theta\),所以我们必须知道它的性质才能写出合适的形式,一般它有以下性质:概率值在0~1\(\sum_{i=1}^np(c|w;\theta)=1\)(w,c)相似的时候,我们希望它的值大一些。(w,c)不相似的时候,我们希望它的值小一些。所以我们可以使用softmax的形式:$$softmax=\frac{e^{z_i}}{\sum\limits_{c=1}^ce^c}\tag{3}$$\((p(c|w;\theta)\)可以写成如下式(4):c'表示w的所有相邻词,\(u_c\)表示c的embedding,\(v_w\)表示central的embedding词w。当w和c相似时,\(u_cv_w\)的内积也越大,反之则相反。这里我们用余弦相似度来衡量相似度,两个向量越相似,点积越大。$$(p(c|w;\theta)=\frac{e^{u_cv_w}}{\sum\limits_{c'}e^{u_{c'}v_w}}\tag{4}$$进一步:$$\begin{equation}\begin{split}\theta&=arg\,\max_{\theta}\sum_{w\inText}\sum_{c\inContext}log\frac{e^{u_cv_w}}{\sum\limits_{c'}e^{u_{c'}v_w}}\\&=arg\,\max_{\theta}\sum_{w\inText}\sum_{c\在Context}e^{u_cv_w}-log\sum_{c'}e^{u_{c'}v_w}\tag{5}\end{split}\end{equation}$$上面的公式5可以看到这个目标函数有一些问题:我们在减去最后一项后做了一个内循环,而这一项的时间复杂度是O(|V|),V是我们词库的大小,所以当我们的词库有一个量很大,成本会很高,而且会损失精度,而且这个公式不好优化,所以我们换一种思路,也叫负采样,后面我会解释为什么叫负采样.类似地,我们有一堆数据集D{\(s_1,s_2,s_3,s_4...s_n\)}并且我们假设它的可能性:D=1表示相邻,否则$$p(D=1|w,c;\theta)$$$$p(D=0|w,c';\theta)\tag{6}$$那么我们的目标函数就可以是MLE这个公式(7):$$L(\theta)=\prodp(D=1|w,c;\theta)p(D=0|w,c';\theta)\tag{7}$$$$\begin{方程}\begin{拆分}\theta=&arg\,\max_{\theta}\prodp(D=1|w,c;\theta)p(D=0|w,c';\theta)\\=&arg\,\max_{\theta}\prod_{w,c\inD}p(D=1|w,c;\theta)\prod_{w,c'\in\overlineD}p(D=0|w,c';\theta)\tag{8}\end{split}\end{equation}$$接下来我们考虑这个条件概率p应该满足什么条件:概率值在0和1之间(w,c)是相似的当我们希望它的值更大,当(w,c)不相似时,我们希望它的值更小。所以我们重新考虑Sigmoid函数。下面是我们写的目标函数:$$\ell(\theta)=arg\,\max_\theta\sum_{w,c\inD}log\sigma(u_cv_w)+\sum_{w,c'\in\overlineD}log\sigma(-u_c'v_w)\tag{9}$$在实际样本中,负样本比正样本多很多,所以上面的公式(9)可以转化为公式(10)$$\ell(\theta)=arg\,\max_\theta\sum_{w,c\inD}[log\sigma(u_cv_w)+\sum_{c'\inN(w)}log\sigma(-u_c'v_w)]\tag{10}$$\(c'\inN(w)\)表示属于w的N个负样本,所以也叫负采样。接下来用梯度下降法求解\(\theta\):$$\frac{\partial\ell(\theta)}{\partialu_c}=\sum_{w,c\inD}[1-\sigma(u_cv_w)]v_w\tag{11}$$$$\frac{\partial\ell(\theta)}{\partialv_w}=\sum_{w,c\inD}\{[1-\sigma(u_cv_w)]u_c+\sum_{c'\inN(w)}[\sigma(-u_cv_w)-1]u_{c'}\}\tag{12}$$$$\frac{\partial\ell(\theta)}{\partialu_{c}'}=\sum_{c'\inN(w)}[\sigma(-u_cv_w)-1]v_w\tag{13}$$其他词向量技术矩阵分解思路:构造词库生成\(n*n\)大小的实对称半正定矩阵,n为词库的大小。对于上述矩阵的SVD分解,S矩阵中的列向量就是对应的词向量缺点:当词库很大时,循环词库和训练的过程非常耗时。矩阵分解是一种全局的方法,它依赖于整个词典的信息,这意味着一旦我们词典中的一个词发生变化,整个模型就会发生变化。优点:缺点也是优点,全局方法也意味着学习过程包括全局信息Glove向量Glove向量方法结合了Skip-Gram和矩阵分解的优点,既能看到全局信息又能高效训练。思路:待续……