02-NLP-07-词向量及相关应用

表示人类造出的词:

(1)从语料中提取出含义表达。

(2)从文字到数值向量

词编码的方式:N-gram,TF-IDF——Word2vec(对于多义词会转化到同一个数值向量,从而导致不准确)——sense2vec(区分在不同语境下某些单词的具体含义)

·

给每个词一个索引,每个词都编码一个下标,但是由于词与词之间有一些隐含的关系,这样做会破坏这个关系。近义词,同一类。

绘制到一个二维空间中,希望保证向量空间的相似度,即含义上相近的词绘制到二维空间中之后仍然是相近的。

词典:给每个不同的词一个下标

one-hot方法非常耗费内存,很稀疏的表示。数组会很长。

优化方法是只从这么多词当中取出最常用的几千个词,其余超出这些词的全部用一个下标来表示。

由于每个词在本文档中的重要性不一样。如果某个词在所有文档集合中出现频次都很高,那这个词可能就是一个烂大街的词。

但如果这个词仅仅是在本文档中出现高的话,那它就是很重要的一个词,需要适当利用TF-IDF来提高它的重要性。

语言模型:Bi-gram和N-gram

没有办法捕捉到背景知识,例如:词语之间的相近度。

由于句子结构都是这三个类型组成的,因此将乘法变加,大大减少了复杂度

计算机可以看很多文本,可能发现banking这个词老是和某些词一起出现,所有这个词可以用与它相近的词进行表示。

local window局域窗口

表中未计数。矩阵为对称矩阵。当列出共现矩阵的时候,可以通过某一行某一列进行表示。

欠稳定的原因:维度太高,太稀疏

SVD会分解为三个矩阵,取前两个矩阵构成二维空间表示到2D图中:

同样,随着语料库的增加,学习的文本数目越多,共现矩阵的维度也就越大。

此时依旧需要对词进行TF-IDF的词频统计,在周边的共现窗中只考虑高频词汇、有直接实际含义的、重要的词。

由于汉语本来丰富度就很高,如果说要挑选出几千个词就能表示所有常见词显然是一件很难很不实际的事情。

线性模型如果稀疏的话,如L2这一类的,由于这类模型的每个维度的输入会对最后的结果有一个共现。如果当前维度上的input会非常大,那最后结果影响肯定也会很大。

稀疏的坏处就是最后只会有几个有数值的位置会决定最后的结构

如果新加入了词的话,可能需要对共现矩阵重新全部做一遍统计。

DL是对原始特征进行变换然后做特征的抽取。SVD利用数学的方式进行降维不一定是DL想要的方式。

2003年提出了NNLM:

遍历整个语料库,将所有对的词都取出来,将所有正确的概率都加到一起,希望结果尽量大。

神经网络依旧需要大量的数据才能取得好的效果。只有一个隐藏层,一个投射层。

实际应用中,效果好的是有监督的学习,能看到标准答案,并在标准答案的指引下进行学习,这样可以有方向地学习。

但是很难直接获取到大量的有标准答案的数据。因此设法将大量语料库转化为有监督的语料。

之前的语言模型是基于前n-1个词来推导后一个词。而下面引出的CBOW是由周边的词来推导中间的一个词。

(1)NN计算量之所以会变大是因为含有隐藏层,所以首先去掉了隐藏层。

(2)由于NN中采用的是拼接,使得维度太高也会加大计算量。因为高维度向量如果拼接起来再经过全链接层,将会是一个相当庞大的计算量。

  因此直接去掉了投射层,并直接进行求和(不拼接,维持原来的维度)

(3)利用上下文来预测w的目标函数,在语料库中遍历所有的词,进行学习使得目标函数J有最大值。

最后一层采用的是softmax,需要采用一个全链接的计算。例如sum结果为500维,输出w(t)为40w维,则需要500*40w次计算。

softmax层消耗太大了,因此有两种解决方式:(1)层次softmax  (2)负例采样

google设计算法的思路是计算要竟可能简单,计算量小,最后都不用GPU来计算,用CPU就可以解决而且用CPU就能很快地处理。

上述的w(t)为40w全部平铺开来的数据,因此SUM的结果每一位都需要跟这40w维度的每一位都有连接,因此需要对40W平铺开来的数据进行压缩空间:层叠起来。

利用哈夫曼树对原本语料库中的每一个词进行编码,根据词出现的频次高低建立出一棵树,频次越低离叶子节点越近,频次越高离根节点越近。

问题转化为从根节点沿着路径来寻找相应的叶子节点。哈弗曼树是一颗二叉树,每次沿路径寻找的时候其实就是在做一个二分类的问题。因此,

现在转为关心路径上的所有二分类的分类器,要求的预测概率就转换为这几个二分类分类概率的乘积。每个结点处有一个权重。

将每次二分类的抉择做一次LR(逻辑回归)根据sigmoid函数的结果跟阈值比较划分路径。

这样分层之后的好处在于:有很多重复的路径都可以共享权重。不像原来的全链接层需要500*40w个权重。

每个结点的二分类模型都是一样的,这里假设都采用的是LR模型。

找出路径,然后根据节点处往左还是往右判断出是(sigmoid)还是(1-sigmoid),从而求出哈弗曼树上所有的权重值。

然后得到含有θ参数的目标函数,尝试最大化目标函数(利用优化算法来做优化:求偏导数,然后沿着梯度方向优化)。

总结:层次softmax就是将原来平铺开来的softmax结果变成了一个深度层级结构,然后只需要顺着层级进行查找。每次只需判断往左还是往右。

由于在40w样本中,只会有一个正确答案,对于巨大的40w-1的负样本可以进行采样。

不是随便采样的,保证采样后的样本和原样本有一定的相近度。方法如下:

利用出现的词频的3/4次方来分段。然后每次相当于掷骰子一样,从总的10^8段中取出一个数,找出该段对应的词。并将这个词取出(采样得到一个负样本的方法)。

在实际中,负例采样比层次softmax更常用。

Skip-Gram模型是利用中间的词来推断周边的词。

目标函数有两个求和:内层求和是遍历某个词周围的词,外层是遍历整个词表。

经验:如果语料库很大的时候,采用Skip-Gram会比CBOW的效果好很多。如果语料库不是很大的时候会采用CBOW。

对于第一个问题改进:Glove可以利用全局的信息

对于多义词进行了平滑,所有没办法区分开多义词。

但是在DL中还是多采用word2vec,而不是glove。

因为在DL当中会采用embedding layer(嵌入层)来做word embedding,将稀疏的表示变为稠密的。由于这是NN当中的一层,所有它的权重调整是和目标直接相关的。不是独立于网络的。

从而可以直接做一个end-to-end的模型,然后进行训练。现在制作的词表是和目标直接关联的。

可以带上词性、类别领域等标签去训练。从而区分开不同语境下的多义词。

word2vec和sense2vec只是对词的一种编码形式,后续可以用SVM、LTSM等方法进行处理。

原文地址:https://www.cnblogs.com/Josie-chen/p/9150020.html