词向量

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,783评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,360评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,942评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,507评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,324评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,299评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,685评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,358评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,652评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,704评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,465评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,318评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,711评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,991评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,265评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,661评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,864评论 2 335

推荐阅读更多精彩内容