文章目录
Embedding
- Embedding能够用低维向量对物体进行编码还能保留其含义的特点非常适合深度学习。在传统机器学习模型构建过程中,我们经常使用one hot encoding对离散特征,特别是id类特征进行编码,但由于one hot encoding的维度等于物体的总数
- 比如阿里的商品one hot encoding的维度就至少是千万量级的。
- 这样的编码方式对于商品来说是极端稀疏的,甚至用multi hot encoding对用户浏览历史的编码也会是一个非常稀疏的向量。而深度学习的特点以及工程方面的原因使其不利于稀疏特征向量的处理。因此如果能把物体编码为一个低维稠密向量再喂给模型,自然是一个高效的基本操作。
Word Embedding
- 顾名思义,词向量是⽤来表⽰词的向量,也可被认为是词的特征向量或表征。把词映射为实数域向量的技术也叫词嵌⼊(word embedding)。近年来,词嵌⼊已逐渐成为⾃然语⾔处理的基础知识。
- 在NLP(自然语言处理)领域,文本表示是第一步,也是很重要的一步,通俗来说就是把人类的语言符号转化为机器能够进行计算的数字,因为普通的文本语言机器是看不懂的,必须通过转化来表征对应文本。早期是基于规则的方法进行转化,而现代的方法是基于统计机器学习的方法。
- 数据决定了机器学习的上限,而算法只是尽可能逼近这个上限,在本文中数据指的就是文本表示,所以,弄懂文本表示的发展历程,对于NLP学习者来说是必不可少的。
- 词向量转换也就是将文本数据转换为数值型数据的一种方式,在 人工智能中,这种方式统称为Word Embedding;Word Embedding 实际上就是一种映射,将文本空间中的某个word,通过一定的方 法,映射或者嵌入(Embedding)到另外一个数值向量空间。之所以 称为embedding,是因为这种映射往往伴随着降维的思想。
词向量
- 两个词向量之间的距离(例如,任意两个向量之间的L2范式距离 或更常用的余弦距离)一定程度上表征了的词之间的语义关系;
- 例如,“椰子”和“北极熊”是语义上完全不同的词,所以它们 的词向量在一个合理的嵌入空间的距离将会非常遥远。但“厨房” 和“晚餐”是相关的话,所以它们的词向量之间的距离会相对小。
- 但是哑编码、词袋法以及TF-IDF这些方式都不能达到这个效果, 故提出了基于矩阵分解的主题模型算法以及基于神经网络的 Word2Vec的词向量转换方式。
词向量—One-Hot
One-hot简称读热向量编码,也是特征工程中最常用的方法。
One-Hot骤如下:
-
构造文本分词后的字典,每个分词是一个比特值,比特值为0或者1。
-
每个分词的文本表示为该分词的比特位为1,其余位为0的矩阵表示。
-
使用一个非常稀疏的向量来表示单词的特征向量信息,假设现在 有n个单词,那么转换的特征向量就是n维,仅在对应位置为1, 其它位置全部为0。如下图:
One-hot表示文本信息的缺点:
- 随着语料库的增加,数据特征的维度会越来越大,产生一个维度很高,又很稀疏的矩阵。
- 这种表示方法的分词顺序和在句子中的顺序是无关的,不能保留词与词之间的关系信息。
词向量—词袋法
- 词袋法(Bag of words, BOW)是最早应用于NLP和IR领域的一种文本 处理模型,该模型忽略文本的语法和语序,用一组无序的单词 (words)来表达一段文字或者一个文档,词袋法中使用单词在文档中出现的频数/频率来表示文档,使用所有文档中出现的单词作 为特征属性。
- 词袋法像是句子或是文件这样的文字可以用一个袋子装着这些词的方式表现,这种表现方式不考虑文法以及词的顺序。
词袋模型同样有一下缺点:
- 词向量化后,词与词之间是有大小关系的,不一定词出现的越多,权重越大。
- 词与词之间是没有顺序关系的。
词向量—TF-IDF
- 在词袋法的基础上加入单词重要性的影响系数:
- 单词的重要性随着它在文本中出现的次数成正比增加,也就是单词的出现次数越多,该单词对于文本的重要性就越高。
- 同时单词的重要性会随着在语料库/训练数据中出现的频率成反比下降, 也就是单词在语料库中出现的频率越高,表示该单词越常见,也就是该单词对于文本的重要性越低。
- TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的常用加权技术。TF意思是词频(Term Frequency),IDF意思是逆文本频率指数(Inverse Document Frequency)。
- 公式如下:
T
F
w
=
在
某
一
类
中
词
条
w
出
现
的
次
数
该
类
中
所
有
词
条
的
数
目
TFw=\frac{在某一类中词条w出现的次数}{该类中所有词条的数目}
TFw=该类中所有词条的数目在某一类中词条w出现的次数
I D F = log 语 料 库 的 文 档 总 数 包 含 词 条 w 的 文 档 总 数 + 1 IDF=\log\frac{语料库的文档总数}{包含词条w的文档总数+1} IDF=log包含词条w的文档总数+1语料库的文档总数
T F − I D F = T F w ∗ I D F TF-IDF=TF_w*IDF TF−IDF=TFw∗IDF
分母之所以加1,是为了避免分母为0。
- 公式如下:
T
F
w
=
在
某
一
类
中
词
条
w
出
现
的
次
数
该
类
中
所
有
词
条
的
数
目
TFw=\frac{在某一类中词条w出现的次数}{该类中所有词条的数目}
TFw=该类中所有词条的数目在某一类中词条w出现的次数
计算this的TF-IDF如下:
t
f
(
′
′
t
h
i
s
′
′
,
d
1
)
=
1
5
tf(''this'',d_1)=\frac{1}{5}
tf(′′this′′,d1)=51
t
f
(
′
′
t
h
i
s
′
′
,
d
2
)
=
2
8
tf(''this'',d_2)=\frac{2}{8}
tf(′′this′′,d2)=82
i
d
f
(
′
′
t
h
i
s
′
′
,
D
)
=
log
(
2
+
1
2
+
1
)
=
0
idf(''this'',D)=\log\left(\frac{2+1}{2+1}\right)=0
idf(′′this′′,D)=log(2+12+1)=0
T
F
−
I
D
F
(
′
′
t
h
i
s
′
′
,
d
1
)
=
1
5
∗
0
=
0
TF-IDF(''this'',d_1)=\frac{1}{5}*0=0
TF−IDF(′′this′′,d1)=51∗0=0
T
F
−
I
D
F
(
′
′
t
h
i
s
′
′
,
d
2
)
=
2
8
∗
0
=
0
TF-IDF(''this'',d_2)=\frac{2}{8}*0=0
TF−IDF(′′this′′,d2)=82∗0=0
所有单词计算结果如下:
词向量—主题模型
- 直接使用机器学习的主题模型相关算法将词袋法转换的文本单词特征属性句子转换为文本主题特征属性矩阵以及单词主题特征属性矩阵即可得到单词对应的特征向量以及文本对应的特征向量。
词向量_Word2Vec
Word2Vec可以认为是应用最广泛的词向量转换技术。
- 在聊 Word2vec 之前,先聊聊 NLP (自然语言处理)。NLP 里面,最细粒度的是 词语,词语组成句子,句子再组成段落、篇章、文档。所以处理 NLP 的问题,首先就要拿词语开刀。
- 举个简单例子,判断一个词的词性,是动词还是名词。用机器学习的思路,我们有一系列样本(x,y),这里 x 是词语,y 是它们的词性,我们要构建 f(x)->y 的映射,但这里的数学模型 f(比如神经网络、SVM)只接受数值型输入,而 NLP 里的词语,是人类的抽象总结,是符号形式的(比如中文、英文、拉丁文等等),所以需要把他们转换成数值形式,或者说——嵌入到一个数学空间里,这种嵌入方式,就叫词嵌入(word embedding),而 Word2vec,就是词嵌入( word embedding) 的一种
- 大部分的有监督机器学习模型,都可以归结为: f(x)->y ,在 NLP 中,把 x 看做一个句子里的一个词语,y 是这个词语的上下文词语,那么这里的 f,便是 NLP 中经常出现的『语言模型』(language model),这个模型的目的,就是判断 (x,y) 这个样本,是否符合自然语言的法则,更通俗点说就是:词语x和词语y放在一起,是不是人话。
- Word2vec 正是来源于这个思想,但它的最终目的,不是要把 f 训练得多么完美,而是只关心模型训练完后的副产物——模型参数(这里特指神经网络的权重),并将这些参数,作为输入 x 的某种向量化的表示,这个向量便叫做——词向量。
- 我们来看个栗子,如何用 Word2vec 寻找相似词:
- 对于一句话:『她们 夸 吴彦祖 帅 到 没朋友』,如果输入 x 是『吴彦祖』,那么 y 可以是『她们』、『夸』、『帅』、『没朋友』
- 这些词现有另一句话:『她们 夸 我 帅 到 没朋友』,如果输入 x 是『我』,那么不难发现,这里的上下文 y 跟上面一句话一样从而 f(吴彦祖) = f(我) = y,
- 所以大数据告诉我们:我 = 吴彦祖(完美的结论)
- Word2Vec实际是一种浅层的神经网络模型,它有两种网络结构,分别是CBOW(Continues Bag of Words)连续词袋和Skip-gram
- 如果是用一个词语作为输入,来预测它周围的上下文,那这个模型叫做 『Skip-gram 模型』
- 而如果是拿一个词语的上下文作为输入,来预测这个词语本身,则是 『CBOW 模型』
- 神经网络将词表中的词语作为输入(一般输入哑编码的单词),输 出一个低维度的向量表示这个词语,然后用反向传播的方法不断优化参数。输出的低维向量是神经网络第一层的输出,这一层通 常也称作Embedding Layer。
- 生成词向量的神经网络模型分为两种,一种是类似Word2Vec的方式,这 类模型的目的就是生成词向量,另一种是将词向量作为副产品产生,两 者的区别在于计算量不同。若词表非常庞大,用深层结构的模型训练词 向量需要许多计算资源。
- Word2Vec和GloVe(Global Vectors for Word Representation)的目的是训练可 以表示语义关系的词向量,它们能被用于后续的任务中;如果后续任务 不需要用到语义关系,则按照此方式生成的词向量并没有什么用。另一 种模型则根据特定任务需要训练词向量。当然,若特定的任务就是对语 言建模,那么两种模型生成的词向量非常相似了。
Skip-gram 和 CBOW 的简单情形
- y 是 x 的上下文,所以 y 只取上下文里一个词语的时候,语言模型就变成:用当前词 x 预测它的下一个词 y
- 一般的数学模型只接受数值型输入,这里的 x 该怎么表示呢? 显然不能用 Word2vec,因为这是我们训练完模型的产物,现在我们想要的是 x 的一个原始输入形式,那就是one-hot encoder。
- 所谓 one-hot encoder,其思想跟特征工程里处理类别变量的 one-hot 一样。本质上是用一个只含一个 1、其他都是 0 的向量来唯一表示词语。
假设全世界所有的词语总共有 V 个,这 V 个词语有自己的先后顺序,假设『吴彦祖』这个词是第1个词,『我』这个单词是第2个词,那么『吴彦祖』就可以表示为一个 V 维全零向量、把第1个位置的0变成1,而『我』同样表示为 V 维全零向量、把第2个位置的0变成1。这样,每个词语都可以找到属于自己的唯一表示。
OK,那我们接下来就可以看看 Skip-gram 的网络结构了,x 就是上面提到的 one-hot encoder 形式的输入,y 是在这 V 个词上输出的概率,我们希望跟真实的 y 的 one-hot encoder 一样。
- 首先说明一点:隐层的激活函数其实是线性的,相当于没做任何处理(这也是 Word2vec 简化之前语言模型的独到之处),我们要训练这个神经网络,用反向传播算法,本质上是链式求导。
- 当模型训练完后,最后得到的其实是神经网络的权重,比如现在输入一个 x 的 one-hot encoder: [1,0,0,…,0],对应刚说的那个词语『吴彦祖』,则在输入层到隐含层的权重里,只有对应 1 这个位置的权重被激活,这些权重的个数,跟隐含层节点数是一致的,从而这些权重组成一个向量 vx 来表示x,而因为每个词语的 one-hot encoder 里面 1 的位置是不同的,所以,这个向量 vx 就可以用来唯一表示 x。
- 此外,我们刚说了,输出 y 也是用 V 个节点表示的,对应V个词语,所以其实,我们把输出节点置成 [1,0,0,…,0],它也能表示『吴彦祖』这个单词,但是激活的是隐含层到输出层的权重,这些权重的个数,跟隐含层一样,也可以组成一个向量 vy,跟上面提到的 vx 维度一样,并且可以看做是词语『吴彦祖』的另一种词向量。而这两种词向量 vx 和 vy,正是 Mikolov 在论文里所提到的,『输入向量』和『输出向量』,一般我们用『输入向量』。
- 需要提到一点的是,这个词向量的维度(与隐含层节点数一致)一般情况下要远远小于词语总数 V 的大小,所以 Word2vec 本质上是一种降维操作——把词语从 one-hot encoder 形式的表示降维到 Word2vec 形式的表示。
CBOW
CBOW根据上下文预测当前单词
- CBOW获得中间词两边的的上下文,然后用周围的词去预测中间的词,把中间词当做y,把窗口中的其它词当做x输入,x输入是经过one-hot编码过的,然后通过一个隐层进行求和操作,最后通过激活函数softmax,可以计算出每个单词的生成概率,接下来的任务就是训练神经网络的权重,使得语料库中所有单词的整体生成概率最大化,而求得的权重矩阵就是文本表示词向量的结果。
- 例如,给定{The,cat,(),over,the, puddle}预测中心词是jumped的概率, 模型的结构如下:
Skip-gram
Skip-gram根据单词预测上下文
- skip-gram是通过当前词来预测窗口中上下文词出现的概率模型,把当前词当做x,把窗口中其它词当做y,依然是通过一个隐层接一个Softmax激活函数来预测其它词的概率
- 给定jumped,预测上 下文单词{The,cat,(),over,the, puddle}的概率,模型的结构如下:
上述所说的Word2Vec是最原始的结构,在计算过程中需要计算所 有单词(2m)和中心词之间的概率,比较耗时,所以在Word2Vec的 论文(Efficient Estimation of Word Representations in Vector Space)中, 作者Mikolov提出Hierarchical softmax(霍夫曼树)和Negative sampling(负样本采样)两种方法对Word2Vec的模型训练进行优化。 这也是Word2Vec能够大量真正应用于NLP领域的主要原因(不需要 依赖神经网络训练模型)。
优化方法
- 如果单单只是接一个softmax激活函数,计算量还是很大的,有多少词就会有多少维的权重矩阵,所以这里就提出层次Softmax(Hierarchical Softmax)
- 使用Huffman Tree来编码输出层的词典,相当于平铺到各个叶子节点上,瞬间把维度降低到了树的深度
- 可以看如下图所示。这课Tree把出现频率高的词放到靠近根节点的叶子节点处,每一次只要做二分类计算,计算路径上所有非叶子节点词向量的贡献即可。
哈夫曼树(Huffman Tree):给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
- 层次 Softmax 应用了哈夫曼树的思想,元素对应词,元素的权值对应词出现的频率,那么出现越频繁的词越接近哈夫曼树的根节点,其搜索的频率也越频繁。所以根据词频构建哈夫曼树。
那么哈夫曼树中的 0,1 路径又是如何得到的呢?答案就是 Sigmoid 函数。
σ ( x ; θ ) = 1 1 + e − z , z = x T θ + b σ(x;θ)=\frac{1}{1+e^{-z}},z=x^Tθ+b σ(x;θ)=1+e−z1,z=xTθ+b - Sigmoid 函数的取值范围为 (0, 1),刚好可以用来进行 0,1 输出,哈夫曼树是二叉树,那么每次进行路径选择可视为一个二分类,那么就变成了多次二分类,称为层次 Softmax.
- 对于当前词的上下文词,经过计算到投影层后,进入层次 Softmax。将上下文词向量的结果求和取平均,将结果推给 Sigmoid 函数。
- 在最终输出层,便用到了词在哈夫曼树根节点走向目标叶子结点的搜索路径。对于每一次决策左右,都是由 Sigmoid 计算得到的,而 Sigmoid 计算的结果都可以视为概率,那么我们可以将路径的概率相乘,计算最大似然,得到损失函数:
L ( x i ; θ ) = ∏ j = 2 l i [ σ ( x i ; θ ) ] 1 − y j [ 1 − σ ( x i ; θ ) ] y j L(x_i;θ)=∏^{l_i}_{j=2}[σ(x_i;θ)]^{1−y_j}[1−σ(x_i;θ)]^{y_j} L(xi;θ)=j=2∏li[σ(xi;θ)]1−yj[1−σ(xi;θ)]yj
- 其中
l
i
l_i
li为该词的搜索路径。
之后就可以像求解 Logistic 回归一样进行反向传播了。
负例采样(Negative Sampling):这种优化方式做的事情是,在正确单词以外的负样本中进行采样,最终目的是为了减少负样本的数量,达到减少计算量效果。将词典中的每一个词对应一条线段,所有词组成了[0,1]间的剖分,如下图所示,然后每次随机生成一个[1, M-1]间的整数,看落在哪个词对应的剖分上就选择哪个词,最后会得到一个负样本集合。
- 在层次 Softmax 中,如果要查询一个比较生僻的词,那么路径会非常长,搜索的深度也非常深。
- 搜索深度非常深的原因是,语料库中的词多,如果有 10000 个不重复词,那么哈夫曼树的深度则为 10000,而我们想要搜索的只有一个或滑动窗口大小个词,所以我们要对不相关的词进行精简。
精简的方法为负采样。
- 负采样的思想用一句话来描述:将真实词看作 正类,将非真实词看作 负类,在负类中进行采样,获取一部分样本。那么由此,原本的 10000 分类或者 10000 规模的层次Softmax 变成了二分类。
- 负采样的实现方法用到了赌博轮盘算法的思想,只不过将轮盘的原型展开,变为一条线。
- 将非真实词的负样本空间看作一条长度为 1 的线段,各个词在线段中占有一段长度,其长度对应词的词频。而后随机产生一个 (0,1) 的数,这个数在哪个词线段的区间内,这个词就被加入到采样的样本中。
- 假设随机产生一个数:0.66,066 ∈ (0.55, 0.95),所以词 “中国” 被选出,以此类推,进行多次实验,最终得到一定数量的负样本,而后利用 Sigmoid 函数进行二分类。
Word2Vec存在的问题
- 对每个local context window单独训练,没有利用包 含在global co-currence矩阵中的统计信息。
- 对多义词无法很好的表示和处理,因为使用了唯一的词向量
- word2vec模型的问题在于词语的多义性。比如duck这个单词常见的含义有水禽或者下蹲,但对于 word2vec 模型来说,它倾向于将所有概念做归一化平滑处理,得到一个最终的表现形式。
词嵌入为何不采用one-hot向量
- 虽然one-hot词向量构造起来很容易,但通常并不是⼀个好选择。⼀个主要的原因是,one-hot词向量⽆法准确表达不同词之间的相似度,如我们常常使⽤的余弦相似度。由于任何两个不同词的one-hot向量的余弦相似度都为0,多个不同词之间的相似度难以通过one-hot向量准确地体现出来。
- word2vec⼯具的提出正是为了解决上⾯这个问题。它将每个词表⽰成⼀个定⻓的向量,并使得这些向量能较好地表达不同词之间的相似和类⽐关系。
词向量-Char2Vec
词向量-Doc2Vec
引用
https://blog.csdn.net/weixin_37352167/article/details/90260358
https://github.com/NLP-LOVE/ML-NLP/tree/master/NLP/16.1%20Word%20Embedding