美文网首页
词嵌入与word2vec

词嵌入与word2vec

作者: 老喵呜_1 | 来源:发表于2020-03-28 22:54 被阅读0次

    简介

    如何让计算机理解文本?众所周知,机器对数值型数据的处理能力非常强大,但是如果只是丢给他文字,他可能难以理解这些文字的意义。所以,需要有个方法将文字转换成数值,能让计算机了解他们的含义、语义、使用场景等,所以需要一个预训练的词嵌入模型

    什么是预训练词嵌入

    预训练词嵌入是从大量的数据中训练得到词嵌入,将结果存下来应用到解决其他的问题中。

    但是为什么需要进行预训练词嵌入?我们难道不能每次要用的时候自己训练吗?

    为什么需要预训练词嵌入

    预训练的词嵌入基于非常大量的数据训练得到,他们能够捕捉词语中的语义和用法,他们可以提高NLP相关模型的效果,而且可以即插即用。

    那为什么不建议自己训练呢,因为这会面临两个问题:

    1. 稀疏的训练数据: 这个世界中有非常多的不常见词,所以需要一个巨大的训练集才能把他们训练到较好的效果
    2. 大量的训练参数:大量的训练参数会使你的训练速度变慢,从而没有办法聚焦于真正需要解决的问题中

    有哪些预训练词嵌入模型

    一般来说嵌入模型有两大类,一类是词嵌入、一类是字嵌入,像ELMo和Flair都是字嵌入算法的模型,而词嵌入算法比较流行的有

    • Google的Word2Vec
    • Stanford的GloVe

    什么是Word2Vec

    Word2Vec算法是Google开发的预训练词嵌入模型,他通过Google News的数据(大概1千亿词)训练得到,广泛用于推荐系统、文本分析等问题中。但是,Word2Vec的思路却非常简单,是一个只有一层隐层的前馈神经网络。

    根据词嵌入的学习方式,有两种方法可以进行学习:

    • Continuous Bag-of-Words (CBOW)
    • Skip-gram

    CBOW模型是通过相邻词去学习目标词,而Skip-gram是通过目标词去学习相邻词,所以CBOW模型和Skip-gram模型是相反的,例如:

    I have failed at times but I never stopped trying

    假设我们想学习"failed"这个词的词嵌入,也就是说,在这里目标词为"failed"。

    首先,我们先定义一个上下文窗口,上下文窗口指的是目标词以及其左右两边相邻的部分词。假设这个窗口的大小为2,则窗口中的词包含了目标词,以及左边相邻两个词以及右边相邻两个词,即:

    Input Output
    CBOW [ I, have, at, times ] failed
    Skip-gram failed [I, have, at, times ]

    所以我们可以看到,CBOW是将多个词输入到模型中而得到一个词,而Skip-gram是将一个词输入到模型中而得到多个词。

    CBOW

    之前说到CBOW是根据相邻词去学习目标词,而学习的结果是以概率的形式体现,因此准确的说,它是给定相邻的词,预测目标词的概率,即P(\text{target}|\text{context})

    上面提到,模型总共有三层,分别为输入层、隐藏层以及输出层。其中输出层是一个softmax,用于得到每个词的概率。

    对于一条数据,神经网络模型如下图:


    当只有一条数据时的模型

    举个例子,我们有如下的语料:

    “the dog saw a cat”, “the dog chased the cat”, “the cat climbed a tree”

    该语料包含8个词,因此输入层和输出层的长度均为8,假设我们想把词转化成长度为3的向量,那么隐藏层的长度为3,这意味着上图中WW'两个矩阵的大小分别是(8\times3)以及(3\times8),这两个矩阵是我们模型要学习的参数。

    假设我们想学习"cat"和"climb"之间的关系,我们将"cat"设置为上下文,"climb"设置为目标词,将他们分别进行one-hot编码。假设编码的顺序与字典序相同,则"cat"编码后为x=[0,1,0,0,0,0,0,0]^T,"climb"编码后为y=[0,0,0,1,0,0,0,0]^T,那么隐藏层的计算方式为h=W^Tx

    在这里,因为x中的元素有且仅有一位为1,因此上述的计算也相当于在W中取出x中值为1的对应那行。

    类似的,输出层的计算方法为\hat{y'}=W'^Th

    由于我们想在输出层得到模型基于给定的上下文对每一个潜在目标词汇的预测概率,所以我们希望输出层的所有数加起来为1,在这里很自然会用到softmax,将输出层的值转化为概率,即对于第k个词,它的概率计算方法为\hat{y_k}=P(k|\text{context})=\frac{exp(\hat{y'_k})}{\sum{exp(\hat{y'})}}

    由于我们希望模型预测目标词为"climb",即y=[0,0,0,1,0,0,0,0]^T,那么很自然的可以用交叉熵定义损失函数,并且最小化损失函数来进行训练了。

    一般情况下,尤其当上下文窗口设置较大时,通常会有多个上下文词对应一个目标词的情况,例如在之前的例子中,同时用上下文词"cat","tree",和目标词"climb"进行训练,所以需要稍微修改一下模型,修改方法如下:


    多个上下文词对应一个目标词的模型

    模型的右半边不动,左半边复制出多份,每个上下文词对应一份,但是注意这里的矩阵W是同一个。而对于隐藏层的计算来说,则是将所有的输入层与W相乘后得到的结果求和平均即可。

    Skip-gram

    之前提到,与CBOW相比,Skip-gram将上下文和目标反过来,即将目标词作为输入,上下文词作为输出,隐藏层保持不动。所以此时,是右半边复制出多份,每个上下文词对应一份。同样以之前的例子来说,输入词"climb"对应的one-hot编码为[0,0,0,1,0,0,0,0]^T,两个输出"cat"和"tree"对应[0,1,0,0,0,0,0,0]^T以及[0,0,0,0,0,0,0,1]^T,由于此时有多个输出的向量,因此对于每个向量来说,它的损失函数不变,而模型的损失函数则是每个向量的损失函数之和,根据它进行反向传播即可。

    参考
    [1] An Essential Guide to Pretrained Word Embeddings for NLP Practitioners
    [2] An Intuitive Understanding of Word Embeddings: From Count Vectors to Word2Vec
    [3] Words as Vectors

    相关文章

      网友评论

          本文标题:词嵌入与word2vec

          本文链接:https://www.haomeiwen.com/subject/ezbluhtx.html