词向量

作者: 三方斜阳 | 来源:发表于2021-01-31 17:54 被阅读0次

自然语言处理问题中,一般以词作为基本单元,例如我们想要分析 "我来自北语" 这句话的情感,一般的做法是先将这句话进行分词,变成我,来自,北语,由于计算机无法处理词,神经网络也无法对词进行处理,所以我们需要将这些词通过某些办法映射成词向量。词向量是用来表示词的向量,也可被认为是词的特征向量。把词映射为实数域向量的技术也叫词嵌入(word embedding)

one-hot

最开始的词嵌入技术是采用one-hot编码,One-Hot编码,又称为一位有效编码,主要是采用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候只有一位有效。

直观理解one-hot编码,比如你现在要处理一篇文本输入给计算机,one-hot的做法是:

1. 首先统计整个文本的词汇的个数N,将所有的词汇排列成表vocab,vocab:我,早上,你好,开学。。。

2.根据词汇表分配编码,每个词对应一个词向量,实际就是一个一维数组,“我”在词汇表vocab的第一个,那么对应的词向量(一维数组)的第一个位置就是1,其余位置置零:[1,0,0 ... 0,0 ];“早上”在词汇表vocab的第二个,那么对应的词向量的第二个位置就是1,其余位置置零: [ 0,1,0 ... 0,0 ];第三个词就是第三个位置为1,其他位置置零;所有的词都按照这样的规则转换成对应的一维数组,也就是词向量了;

那么整个文本就表示成了词向量,比如这个文本就是一句话:今日计划,啥也不干

分词之后得到的词汇表vocab:["今日","计划","啥","也","不干","," ];这个文本的词汇个数就是N=6,

根据one-hot编码依次转换为词向量:

今日:[1,0,0,0,0,0]

计划:[0,1,0,0,0,0]

啥:[0,0,1,0,0,0]

也:[0,0,0,1,0,0]

不干:[0,0,0,0,1,0]

,:[0,0,0,0,0,1]

为什么不用one-hot编码:

很明显的一个缺点就是,维度爆炸,比如现在有一个文本有100万个词,那么每个词按照ont-hot编码就对应一个100万维度的一维数组,这个内存占用是非常高的,

另外一个缺点就是,one-hot编码无法体现出词与词之间的语义联系,任何两个词的余弦相似度都是0:

向量余弦相似度体现词之间的相似程度

word2vec

关于word2vec的原理和使用python的实战推荐一篇博文,博主有个公众号:数据挖掘机养成记

[NLP] 秒懂词向量Word2vec的本质 - 知乎

one-hot编码要求每个类别之间相互独立,如果之间存在某种连续型的关系,文本的词汇之间就是存在关联的存在,所以 distributed respresentation(分布式表示)更加合适,实际就是将高维稀疏的向量降维成稠密的低维向量,一种高维到低维的映射方式。

Wordvec的维基百科解释:

wordvec为一群用来产生词向量的相关模型。这些模型为浅层双层的神经网络,用来训练以重新建构语言学之词文本。网络以词表现,并且需猜测相邻位置的输入词,在word2vec中词袋模型假设下,词的顺序是不重要的。训练完成之后,word2vec模型可用来映射每个词到一个向量,可用来表示词对词之间的关系。该向量为神经网络之隐藏层;

2013 年,Google 团队发表了 word2vec 工具。word2vec 工具主要包含两个模型:跳字模型(skip-gram)连续词袋模型(continuous bag of words,简称 CBOW),以及两种高效训练的方法:负采样(negative sampling)层序 softmax(hierarchical softmax)。值得一提的是,word2vec 词向量可以较好地表达不同词之间的相似度和类比关系。

 Mikolov的原论文:

《Distributed Representations of Sentences and Documents》

《Efficient estimation of word representations in vector space》

关于CBOW和skip-gram模型:

1.用一个词语作为输入,来预测它周围的上下文,那这个模型叫做 Skip-gram 模型

2. 而如果是拿一个词语的上下文作为输入,来预测这个词语本身,则是 CBOW 模型

用两张图来表示CBOW和skip-gram的原理:

CBOW&skip-gram

为什么说word2vec训练的词向量可以表示出词语之间的相似度呢?

这个是基于word2vec算法的假设:在文本中,具有相似上下文的词具有相似的语义

example:

这个其实很好理解的,举个例子,现在有两句文本,分别是:

他们 说 那个 女孩 非常 可爱

这句话如果输入是“女孩”,那么上下文就是“他们” “说” “那个” ”非常“ “可爱” 等这些词

另一句文本是:

他们 说 那个 姑娘 非常 可爱

这个地方很明显,输入是“姑娘”的话,这个输入的上下文词跟刚刚的“女孩”这个词是一样的,所以算法的结果就是“女孩”=“姑娘”一样可爱

word2vec的计算过程就是遍历所有的训练数据,最后就可以得到具有相似的上下文的词具有相似的语义,这些词对应的词向量计算余弦相似度也可以得到较高的值。

关于word2vec中的计算原理,有一篇word2vec的数学原理已经讲解的非常详细了,感兴趣的童鞋可以去看看:

word2vec 中的数学原理详解 - peghoty - 博客园

word2vec的本质:

词向量的本质可以看出是一个只有一层的神经网络,因此必须有输入、输出,训练的目的不是为了得到预测的结果,而是对单词进行分类。最关键的就是获得hidden layer的中的权重。也就是借助sequnece2sequence模型训练过程,得到hidden layer的权重。

训练中的数学原理:

以 基于负采样(negative sampling)的CBOW为例,模型会遍历依次遍历全部的文本,这里有一个概念就是窗口,window size,窗口大小自己定义,一般取5-8左右,代表训练时指定的中心词周围的上下文词的个数,模型的第一层输入是,将所有上下文词都随机初始化成词向量,将这些词向量相加的均值作为CBOW的输入,用这些上下文去预测中心词w

在CBOW模型中,已知词  的上下文 Context(w) ,需要预测 ,因此,对于给定的 Context(w),词w 就是一个正样本,其他词就是负样本了,负样本那么多,全部加入训练那计算量会非常大,于是进行采样处理,选取一部分负样本进行训练;

假定现在已经选好了一个关于w 的负样本子集NEG(w)\neq \phi ,且对于\forall \tilde{w} \in D,定义:

1.1

表示词 \tilde{\omega }  的标签,即正样本的标签为1,负样本的标签为0.

对于给定的一个正样本 ,我们希望最大化:

1.2

其中:

1.3

或者写成整体表达式:

1.4

这里X_{w} 仍然表示Context(w) 中各词的词向量之和,而\theta ^u\in R^m表示词 u 对应的一个(辅助)向量,为待训练的参数。

为什么要最大化 g(w)呢?将 1.4 带入 1.2 之后,得到新的g(w)  的表达式是:

1.5

其中\delta (X_{w}^T \theta ^w)表示当上下文为Context(w) 时,预测中心词为 w的概率,而\delta (X_{w}^T\theta ^u ),u\in NEG(w)则表示当上下文是 Context(w) 时,预测中心词为 u 的概率,于是可以转换为一个二分类问题,从形式上看,最大化g(w),相当于最大化\delta (X_{w}^T \theta ^w ),同时最小化\delta (X_{w}^T\theta ^u ) u\in NEG(w),于是达到了目的:增大正样本的概率,同时降低负样本的概率;于是对于给定的语料库 C,函数:

1.6

就作为整体的优化目标,即目标函数;然后按照梯度上升法进行求导数梯度误差值优化等等。

下面给出以样本(Context(w),w)为例,给出基于Negative Sampling 的 CBOW模型中采用梯度上升法更新各参数的伪代码:

伪代码

word2vec得到的词向量就是其中全部的误差 项的累积和e,其中的训练参数\theta ^u 是辅助向量,经过梯度上升法更新了误差项之后,遍历所有的上下文向量,将得到的误差累积和e加到每个向量中,于是完成一次向量的更新,窗口依次往后移,训练新的目标词和上下文词向量;

全部遍历完语料之后,所有词的向量都是参与了训练且更新 之后的,这些词向量就具备了最开始假设的语义信息,用于下游的一些任务,比如词相似度,词语消歧等任务。

skip-gram的训练过程跟CBOW是大同小异的,只是反过来使用中心词去预测每一个上下文词,具体的训练过程可以参考上文提到的word2vec中的数学原理一文,推导得非常详细。

使用word2vec:

python 中的 gensim 库封装了调用word2vec的接口,只需要几行代码就可以使用word2vec训练好词向量,并且计算词相似度等任务,下面是一些使用的主要代码供参考:

缺点不足:

尽管word2vec训练出的词向量可以表征一定的语义信息,但是训练得到的词向量是静态的,也就是说,一个词只对应一个词向量,那么对于多义词就无法根据上下文去进行处理,举一个大家都用的例子:

He has a large deposit in the bank.

The town stands on the left bank of the river.

这里的“bank" 是完全不同的两个意思,但是使用word2vec训练得到的词表只有一个词向量,那么这个词向量在用于下游任务的时候,更代表哪一种语义呢?这个问题使用静态词向量无法得到解决。

并且在计算词语相似度的时候会发现实验结果存在非常大的噪声,因为基于的假设是上下文相似的词具有相似的语义,所以位置相隔很近的也会具有相似的语义信息,那么在中文里面,一句话的主谓宾,相隔的很近的主语和宾语,是完全不一样的词性,有时候也会得到很高的余弦相似度,比如代词和名词,名词和动词,例如:动词 “打击” 的相似词会出现例如 “悍匪”,“犯罪” 等名词,这显然是不对的,但是因为很多时候:“打击 悍匪”,“打击 犯罪” 经常相隔很近的一起出现在语料里面,所以这一点也是word2vec词向量本身效果不好的一个原因,因为其基本假设存在一些瑕疵。


glove:

官网:GloVe: Global Vectors for Word Representation

官方的代码的GitHub在此 : https://github.com/stanfordnlp/GloVe

上面有训练好的模型可以下载

Glove (Global vectors for word representation),2014年由Stanford NLP Group组织提出,它是一个基于全局词频统计(count-based & overall statistics)的词表征(word representation)工具。

跟word2vec的几点不同:

1. 在表现上 glove 和 word2vec 其实相差不大,Word2vec是局部语料库训练的,其特征提取是基于滑动窗口的;而glove的滑动窗口窗是为了构建co-occurance matrix 共现矩阵,统计了全部语料库里在固定窗口内的词共线的频次,是基于全局语料的,可见glove需要事先统计共现概率;因此,word2vec可以进行在线学习,glove则需要统计固定语料信息。

2. Glove利用了全局信息,使其在训练时收敛更快,训练周期较word2vec较短且效果更好。

golve 原理:

golve 本质上是对共现矩阵进行降维度,下面对glove的基本原理进行一个记录:

1. 首先构建一个词汇的共现矩阵X,同样也是构建一个滑动窗口,依次遍历整个语料库,统计在每个窗口下,词汇与词汇之间共同出现的频率,由此构建出词汇共现矩阵X,其元素是X_{ij} ,代表:在整个语料库中,单词i和单词j共同出现在语料库中的次数

搬个例子:

i love you but you love him i am sad

这个小小的语料库只有1个句子,涉及到7个单词:i、love、you、but、him、am、sad。

如果我们采用一个窗口宽度为5(左右长度都为2)的统计窗口,那么就有以下窗口内容:

中心词为love,语境词为but、you、him、i;则执行:

X_{love,but}+=1 X_{love,you}+=1X_{love,him}+=1X_{love,i}+=1

使用这样的窗口统计所有的语料,就得到了共现矩阵X

2. 模型思想来源:首先定义:X_{i}=\sum_{j=1}^N X_{i,j}  ,表示矩阵单词i那一行的和

条件概率:P_{i,k} =\frac{X_{i,k} }{X_{i} }  表示单词k出现在单词i语境中的概率

这里的 语境有多种定义。举个例子,在一段文本序列中,如果词j 出现在词i 左边或者右边不超过 10 个词的距离,我们可以认为词 j 出现在词 i的环境一次。

然后得到两个条件概率的比率:ratio_{i,j,k}=\frac{P_{i,k} }{P_{j,k} }

3. 然后作者发现,这个ratio_{i,j,k} 存在下表所示的规律:

作者的思想:假设我们已经得到了词向量,如果我们用词向量V_{i} ,V_{j}, V_{k} 通过某种函数计算ratio_{i,j,k} ,能够同样得到这样的规律的话,就意味着我们词向量与共现矩阵具有很好的一致性,也就说明我们的词向量中蕴含了共现矩阵中所蕴含的信息。

依据这个思想作者去构建损失函数进行训练

假设用词向量v_{i},v_{j},v_{k}  计算 ratio_{i,j,k} 的函数为:g(v_{i},v_{j},v_{k} ),那么有:

                        \frac{P_{i,k} }{P_{j,k} }  =ratio_{i,j,k}=g(v_{i},v_{j},v_{k} )

模型的构建细节这篇博客讲的很清楚,感兴趣的童鞋可以去看看:

理解GloVe模型(Global vectors for word representation)_饺子醋的博客-CSDN博客_glove

进步与不足:

1. glove相对于word2vec的局部滑动窗口上下文,采取的是统计整个语料的词汇的共现频率,但是实际上这个全局信息也是根据一个个局部窗口统计得到的,相当于是多个窗口进行训练更新词向量,论文中的结果比word2vec的词向量效果好一些,但是没有根本解决静态词向量这个致命伤,依旧不能称得上非常大的突破。


fasttext:

fastText是一个快速文本分类算法,与基于神经网络的分类算法相比有三大优点:

1、fastText在保持高精度的情况下加快了训练速度和测试速度

2、fastText不需要预训练好的词向量,fastText会自己训练词向量

3、fastText两个重要的优化:Hierarchical Softmax、N-gram

fastText原理:

word2vec把语料库中的每个单词当成原子,它会为每个单词生成一个向量,这忽略了单词内部的形态特征,如“apple”与“apples”,两个单词都有较多的公共字符,即它们的内部形态类似,但是在传统的word2vec中,这种单词内部形态信息因为它们被转换成不同的id丢失了。

为了克服这个问题,fastText使用了字符级别的n-grams来表示一个单词,对于“apple”,假设n的取值为3,则它的trigram有:

"<ap","app","ppl","ple","le>"

其中<表示前缀,>表示后缀,我们可以使用这5个trigram的向量叠加来表示“apple”的词向量。

fastText在使用负采样的 skip-gram 模型的基础上,将每个中心词视为子词(subword )的集合,并学习子词的词向量。

给定一个词w,通常可以把字符长度在3到6之间的所有子词和特殊子词的并集g_{w} 取出来。假设任意子词g的子词向量为z_{g} ,我们可以使用负采样的skip-gram 模型的损失函数:

直接替换成:

可以看到,于是原中心词向量被替换成中心词的子词向量之和,这对于低频词效果会比较好,因为低频词的 n-gram 可以跟其他词共享;跟 word2vec 和 glove 不同的是,词典外的新词,即未登录词可以使用 fastText 中相应的字词向量之和表示。

fastText 对于一些语言比较重要,例如阿拉伯语和德语。例如 德语中有许多复合词,例如乒乓球(英文 table tennis)在德语中叫 "tischtennis"。fasttext可以通过字词表达两个词的相关性,例如 "tischtennis" 和 "tennis"。

模型结构:

fastText模型架构和word2vec中的CBOW很相似, 不同之处是fastText预测标签而CBOW预测的是中间词,即模型架构类似但是模型的任务不同。

fasttext模型架构

其中x_{1} ,x_{2} ,x_{n-1}, x_{n} 表示一个文本中的n-gram向量,每个特征是词向量的平均值。cbow用上下文去预测中心词,而此处用全部的n-gram去预测指定类别。输入是embedding 过的词向量,输出是类别lable,fastText是根据文本分类任务来进行训练并且得到词向量这个产物,隐藏层是对多个词向量的叠加平均。

1)CBOW的输入是目标单词的上下文,fastText的输入是多个单词及其n-gram特征,这些单词用来表示单个文档

2)CBOW的输入单词被one-hot编码过,fastText的输入特征时被embedding过

3)CBOW的输出是目标词汇,fastText的输出是文档对应的类标

将整篇文档的词及n-gram向量叠加平均得到文档向量,然后使用文档向量做softmax多分类

结论:

glove使用词向量表达共现词频的对数。

fastText用子词向量之和表达整词。

实战代码参考:

代码参考

fastText 在https://github.com/facebookresearch/fastText/tree/master/python上提供了绑定了fastText库的Python接口及使用示例代码。

参考:

FastText的简单介绍_摆渡者-CSDN博客_fasttext

相关文章

  • 利用gensim使用腾讯开源的预训练好的词向量

    腾讯开源词向量下载地址 导入词向量 未知词短语向量补齐: 样例: 输出为: 分词,词向量编码,去除标点符号(中英文...

  • 在 Keras 模型中使用预训练的词向量

    1. 什么是词向量?   简而言之,词向量技术是将词转化成为稠密向量,并且对于相似的词,其对应的词向量也相近。词向...

  • TensorFlow实现Word2Vec并进行代码详解

    1.代码部分 2. 词向量图词向量空间表示

  • 预训练好的词向量资源

    词向量是用来表示词的向量,通常也被认为是词的特征向量。现在已经成为自然语言处理的基础技术。词向量的好坏,会直接影响...

  • 词向量

    词向量大法 从文本语料得到词向量的话,大概来讲有如下几个步骤:分词,统计词频,构建huffman树,输入文本训练词...

  • 词向量

    1.更别致的词向量模型:Simpler GloVe - Part 2 2.

  • 词向量

    目前词向量主要用的技术 word2vec fasttext glove 1 one-host编码 one-hot编...

  • 词向量

    自然语言处理问题中,一般以词作为基本单元,例如我们想要分析 "我来自北语" 这句话的情感,一般的做法是先将这句话进...

  • 技术-聊天机器人-word2vec学习笔记

    词向量(http://www.shareditor.com/blogshow/?blogId=99) 词向量:是这...

  • 词向量Word2vec

    下面是记录一下,学习词向量的笔记(根据自己的风格) 一、词向量 假设现在词向量长度length=3,一个词对应on...

网友评论

    本文标题:词向量

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