赞
踩
在Word2vec出现之前,在nlp中最常用的是one-hot(独热)编码,先来解释一下什么是独热的编码:假设我们数据集为,“今天天气特别晴朗”,“六月的天气是多变的”,对应词库{“今天”,“天气”,“特别”,“晴朗’,“六月”,“是”,“多变”}。
那么每个词对应的one-hot词向量就是:
今天:{1,0,0,0,0,0,0}
天气:{0,2,0,0,0,0,0}
特别:{0,0,1,0,0,0,0}
晴朗:{0,0,0,1,0,0,0} 等等
这样我们可以看出one-hot编码的一些特点:
1、词向量的维度是和词库的大小一致
2、每一维的位置代表词的位置(不是词在文中的位置,是词在词库中的位置)只有对应位置有值,、值的大小代表该词在文本出现的次数,其他位置为0;
这样我们可以看出one-hot编码的一些缺点:
1、稀疏的表示
我们的数据集往往有成千上万的词,根据one-hot编码的特点每个词的词向量都有上万维,而且只有其中一维有值,其他位置为0。
2、这种对编码对词表达的能力很弱,基本上没有包含词义在里面。
我们先不谈word2vec的原理,先看一下由word2vec计算出来的词向量有什么特点:
今天:{0.235,0.145,0.287,0.264}
天气:{0.113,0.212,0.185,0.235}
特别:{0.825,0.213,0.212,0.336}
晴朗:{0.32,0.655,0.412,0.251}
第一、每一个维度都有值,是稠密的表示
假设现在有一个八维的词向量那么使用one-hot编码只能表示8个词,而使用word2vec的这种表示方式可以表示无数个词
第二 word2vec计算出的词向量包含词义信息,也就是词义相近,那么词向量之间的距离相近
相对于one-hot,我们一般称word2vec的这种编码方式为分布式的编码
想要了解word2vec首先要明白它的一个基本原理:在一句话中对于每个词与其他词之间有这么一种现象:两词离得越近,词义相似度越高。例如:
”我们在训练一个非常有意思的nlp模型。”这一句话中,“我们”和“nlp”这两个词的相似度要小于“nlp”与“模型”之间的相似度,这也就说明一个词的含义是与周围几个词有很大的关系。所以根据这种关系我们设计里两个模型:
Skip-gram:利用当前单词预测周围单词。
CBOW:利用周围单词预测当前单词。
当前比较流行的是使用Skip-gram模型,所以下面重点介绍这种模型的原理
Skip-gram的主要思想是:根据当前词预测周围词,还是举个例子说明吧:
现在有这样的一句话:”我们在训练一个非常有意思的nlp模型”,假设对“训练”这个词进行计算,那么计算过程就是,如图(1),计算周围词出现的概率: p ( 我 们 ∣ 训 练 ) p(我们|训练) p(我们∣训练), p ( 在 ∣ 训 练 ) p(在|训练) p(在∣训练), p ( 一 个 ∣ 训 练 ) p(一个|训练) p(一个∣训练), p ( 非 常 ∣ 训 练 ) p(非常|训练) p(非常∣训练), p ( 有 意 思 ∣ 训 练 ) . . . p(有意思|训练)... p(有意思∣训练)...并且要把这个概率最大化,也就是MLE的思想(不了解的同学先去了解一下MLE)。
对于每个词我们都进行这样的计算,假设我们考虑周围2个单词那么这句话的计算流程就是:
p ( 在 ∣ 我 们 ) p(在|我们) p(在∣我们), p ( 训 练 ∣ 我 们 ) p(训练|我们) p(训练∣我们), p ( 我 们 ∣ 在 ) p(我们|在) p(我们∣在), p ( 训 练 ∣ 在 ) p(训练|在) p(训练∣在) , p ( 一 个 ∣ 在 ) p(一个|在) p(一个∣在), p ( 我 们 ∣ 训 练 ) p(我们|训练) p(我们∣训练), p ( 在 ∣ 训 练 ) p(在|训练) p(在∣训练), p ( 一 个 ∣ 训 练 ) p(一个|训练) p(一个∣训练), p ( 非 常 ∣ 训 练 ) . . . p(非常|训练)... p(非常∣训练)...
我们一般把当前词叫做中心词,周围的词叫做上下文词(context),那么我们把计算流程写成数学公式就是:
a r g m a x ∏ w ∈ T e x t ∏ c ∈ c o n t e x t ( w ) p ( c ∣ w ; θ ) argmax\prod _{w\in Text}\prod _{c\in context(w)}p\left( c|w;\theta\right) argmax∏w∈Text∏c∈context(w)p(c∣w;θ)
进行简单的转化为:
a r g m a x ∑ w ∈ T e x t ∑ c ∈ c o n t e x t ( w ) log p ( c ∣ w ; θ ) argmax\sum _{w\in Text}\sum _{c\in context(w)}\log p\left( c|w;\theta\right) argmax∑w∈Text∑c∈context(w)logp(c∣w;θ)
也就是说我们输入大量的数据集到模型进行训练,不断的最大化目标函数,优化参数。在这里我们的参数是: θ \theta θ
简单介绍一下 θ \theta θ :
θ \theta θ是有两个矩阵组成 U U U和 V V V,也就是 θ = [ U , V ] \theta=[U,V] θ=[U,V]
U U U表示的是每个词作为中心词时的词向量如图(2):
由图(2)可知每一行都代表这每个词的词向量,也就是我们在训练时不断优化每个词对应的词向量。K表示的是词向量的维度,V表示词库的大小。
V和U是一模一样的,也是个矩阵,每一行代表着单词作为上下文时的向量
具体最后 θ \theta θ是用 U U U还是 V V V我们一会再说
根据上面的解释我们了解了skip-gram的目标函数是:
a r g m a x ∑ w ∈ T e x t ∑ c ∈ c o n t e x t ( w ) log p ( c ∣ w ; θ ) argmax\sum _{w\in Text}\sum _{c\in context(w)}\log p\left( c|w;\theta\right) argmax∑w∈Text∑c∈context(w)logp(c∣w;θ)
也就是最大化训练数据的当前词与上下文词之间的概率
以计算 p ( 在 ∣ 我 们 ) p(在|我们) p(在∣我们)为例:
就是最大化“我们”作为中心词,“在”作为上下文词的概率,“我们”作为中心词时的词向量为: V ( 我 们 ) V_{(我们)} V(我们),“在”作为上下文词的词向量为 U ( 在 ) U_{(在)} U(在),我们知道两个向量的内积表示向量之间的关系:而模型的目的是最大化此时的“我们”和“在”之间的关系。因此也就是最大化 V ( 我 们 ) V_{(我们)} V(我们)和 U ( 在 ) U_{(在)} U(在)的内积: p ( 在 ∣ 我 们 ) p(在|我们) p(在∣我们)是一个概率的形式,所以我们还要除以“我们”作为中心词时所有可能发生的情况。:
p ( 在 ∣ 我 们 ) = V ( 我 们 ) ⋅ U ( 在 ) ∑ d V ( 我 们 ) ⋅ U ( d ) p(在|我们)=\dfrac {V_{(我们)}\cdot U_{(在)}}{\sum_d V_{(我们)}\cdot U_{(d)}} p(在∣我们)=∑dV(我们)⋅U(d)V(我们)⋅U(在)
d d d表示在词库中除了“在”其他所有词
由于这样计算出的数字比较大,再改变一下形式:
p ( 在 ∣ 我 们 ) = e ( V ( 我 们 ) ⋅ U ( 在 ) ) ∑ d e ( V ( 我 们 ) ⋅ U ( d ) ) p(在|我们)=\dfrac {e^{(V_{(我们)}\cdot U_{(在)})}}{\sum_d e^{(V_{(我们)}\cdot U_{(d)})}} p(在∣我们)=∑de(V
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。