自然语言处理 —— 2.6 word2vec

假定训练集中给定了一个这样的句子: I   w a n t   a   g l a s s   o f   o r a n g e   j u i c e   t o   g o   a l o n g   w i t h   m y   c e r e a l . I\space want\space a\space glass\space of\space orange\space juice\space to\space go\space along\space with\space my\space cereal. I want a glass of orange juice to go along with my cereal.在skip-gram模型中,我们要做的是抽取上下文和目标词配对来构造一个监督学习问题,上下文不一定总是在目标单词之前离得最近的四个单词或者最近的n个单词。

我们要做的是随机选一个词作为上下文词,比如选orange这个词,然后我们要做的是随机在一定词距内选另一个词,比如在上下文词前后的5个词内或者前后10个词内,我们就在这个范围内选择目标词。可能你正好选到了juice作为目标词正好是下一个词,也有可能你选到了前面第二个词。所以另一种配对目标词可以是glass,还可能选取到了单词my作为目标词,于是我们将构造一个监督学习问题,它给定上下文词,要求你预测在这个词正负10个词距或者正负5个词距内随机选择的某个目标词。显然这不是个非常简单的学习问题,因为在单词orange的正负10个词距之间可能会有很多不同的单词,但是构造这个监督学习的目标并不是想要解决这个监督学习问题本身,而是想要使用这个学习问题来学到一个好的词嵌入模型。

接下来说说模型的细节,我们继续假设使用一个10000词的词汇表,有时训练使用的词汇表会超过一百万词,但我们要解决的基本的有监督学习问题是从上下文C中学习一种映射关系,比如单词orange到某个目标词,记为t,可能是单词juice或者单词glass或者单词my。

在词汇表中,orange是第6257个单词,juice是10000个单词中的第4834个,这就是你想要的映射到输出y的输入x。

为了表示输入,比如单词orange,你可以从one-hot向量开始,我们将其写作 O c O_c Oc,这就是上下文词的one-hot向量,然后可以拿嵌入矩阵E乘于向量 O c O_c Oc得到输入的上下文词的嵌入向量 e c e_c ec。在这个神经网络中,我们将把向量 o c o_c oc喂入到一个softmax单元,softmax单元要做的就是输出 y ^ \hat{y} y^

然后我们写出模型的细节,softmax在给定输入的上下文词预测不同目标词的概率。 s o f t m a x :   p ( t ∣ c ) = e θ t T e c ∑ j = 1 10000 e θ j T e c softmax:\space p(t|c)=\frac{e^{\theta_t^Te_c}}{\sum_{j=1}^{10000}e^{\theta_j^Te_c}} softmax: p(tc)=j=110000eθjTeceθtTec公式中的 θ t \theta_t θt是一个与输出t有关的参数,即某个词语标签相符的概率是多少,这里省略了softmax中的偏差项,想要加上的话也可以加上。

最终softmax的损失函数就会像之前一样,我们用y表示目标词,这里用y和 y ^ \hat{y} y^都是用one-hot表示,于是损失函数就会是 L ( y ^ , y ) = − ∑ i = 1 10000 y l o g y i ^ L(\hat{y},y)=-\sum_{i=1}^{10000}ylog\hat{y_i} L(y^,y)=i=110000ylogyi^这是一个在目标词y表示为one-hot向量时常见的softmax损失函数,y就是只有一个1,其它都是0的one-hot向量,如果目标词是juice,那么第4834个元素就是1,其余是0。类似的, y ^ \hat{y} y^是一个从softmax单元输出的10000维向量,这个向量是所有可能目标词的概率。

总结一下,这大体上就是一个可以找到词嵌入的简化模型和神经网络,其实就是一个softmax模型,嵌入矩阵E将会有很多参数,所以矩阵E有对应所有嵌入向量 e c e_c ec的参数,softmac单元也有 θ t \theta_t θt的参数。如果优化关于所有这些参数的损失函数,你就会得到一个较好的嵌入向量集,这个就叫做skip-gram模型。它把一个像orange这样的词作为输入,并预测这个输入词从左数或从右数的某个词,预测上下文的前面一些或者后面一些是什么词。

实际上使用这个算法会遇到一些问题,首要的问题就是计算速度。尤其是在softmax模型中,每次你想要计算下面这个概率时 p ( t ∣ c ) = e θ t T e c ∑ j = 1 10000 e θ j T e c p(t|c)=\frac{e^{\theta_t^Te_c}}{\sum_{j=1}^{10000}e^{\theta_j^Te_c}} p(tc)=j=110000eθjTeceθtTec需要对词汇表中的所有10000个词做求和计算,可能10000个词的情况还不算太差,如果你用100000或1000000的词汇表,那么这个分母的求和操作时相当慢的。实际上10000已经是相当慢的了,所以扩大词汇表就更加困难了。

这里有一些解决方案,在文献中你会看到的方法是使用一个分层softmax分类器,意思就是说不是一下子就确定到底是属于10000类中的哪一类,想象如果你有一个分类器,它告诉你目标词是在词汇表的前5000个中还是在词汇表的后5000个词中。假如这个分类器告诉你这个词在前5000个词中,然后第二个分类器会告诉你这个词在词汇表的前2500个词中或者在词汇表的第二组2500个词中,直到最终你找到一个词准确所在的分类器,那么就是这棵树的一个叶子节点。像这样有一个树形的分类器,意味着树上内部的每一个节点都可以是一个二分类器,比如说logistic分类器,所以你不需要再为单次分类,对词汇表中所有的10000个词求和了。实际上,用这样的分类树,计算成本与词汇表大小的对数成正比,而不是词汇表大小的线性函数,这个就叫做分层softmax分类器。

需要提一下,在实践中,分层softmax分类器不会使用一棵完美平衡的分类树或者说一棵左边和右边分支的词数相同的对称树。实际上,分层softmax分类器会被构造成常用词在顶部,不常用的词像durian会在树的更深处。因为你想更常见的词会更频繁,所以你可能只需要少量检索就可以获得常用单词像the和of,然而你更少见到的词比如durian就更适合在树的较深处,因为你一般不需要到那样的深处,有不同的经验法则可以帮助构造分类树形成分层softmax分类器。所以这是你能在文献中见到的一个加速softmax分类的方法,以后还会讲到一个加快训练速度的方法叫负采样。

这里还说一点,那就是怎么对上下文c进行采样,一旦你对上下文c进行采样,那么目标词t就会在上下文c的(比如)正负10个词距内进行采样,但是你要如何选择上下文c呢?

一种选择就是你可以就对语料库均匀且随机地采样。如果你那么做,你会发现有一些词像the,of,a,and,to等出现得相当频繁。于是你那么做的话,你会发现你的上下文到目标词的映射会相当频繁地得到这类的词。其它词像orange、apple或durian就不会那么频繁地出现了,你可能不会想要你的训练集都是这些出现得很频繁的词,因为这会导致你花大部分的力气来更新这些频繁出现的单词 e c e_c ec。但你想要的是花时间来更新像durian这样更少出现的词的嵌入。实际上词 p ( c ) p(c) p(c)的分布并不是单纯的在训练集语料库上均匀且随机的采样得到的,而是采用了不同的启发来平衡常见的词和不那么常见的词。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值