内容来自https://www.bilibili.com/video/BV1FT4y1E74V,仅为本人学习所用。
文章目录
- 词表特征
- 词嵌入的类比推理
- 嵌入矩阵
- 词嵌入
- Word2Vec
- 跳字模型
- 模型细节
- 负采样
- GloVe词向量(了解)
- 情绪分类
词表特征
使用 one-hot 对词汇进行编码时,一个缺点是每个词之间彼此是独立的,联系能力不强。如果使用特征化的表示:
有6个关键词“Man”、“Woman”、“King”、“Queen”、“Apple”、“Orange”。在词嵌入空间中,每个词都被表示为一个向量,图中这些词向量在多个维度。例如,在Gender维度上,“Man”取值为 -1 ,“Woman”取值为 1 ,体现了性别差异;“King”在Royal维度上取值为 0.93,“Queen”在Royal维度上取值为 0.95 ,体现了其的皇室属性;“Apple”和“Orange”在Food维度上取值分别为 0.95 和 0.97 ,体现了其的食物属性。
如果有一个300维的词嵌入,使用t-SNE算法可视化到二维空间中,可以看到,一些特征相似的词分布的更近。
词嵌入的类比推理
假设有一个对应任务:男人对应女人,国王对应什么?国王应该对应王后。是否有一种算法来自动推导出这个关系?
在词嵌入空间中,给出这些词的相关系数,在这里,使用
e
m
a
n
e_{man}
eman表示man在空间中的位置,其他的类似。如图右下角,
e
m
a
n
−
e
w
o
m
a
n
e_{man}-e_{woman}
eman−ewoman的结果和
e
k
i
n
g
−
e
q
u
e
e
n
e_{king}-e_{queen}
eking−equeen的结果相似,都与性别有关系。
上述的做法写成式子: e m a n − e w o m a n ≈ e k i n g − e q u e e n e_{man} - e_{woman} \approx e_{king} - e_{queen} eman−ewoman≈eking−equeen ,即“男人”的词向量减去“女人”的词向量,近似等于“国王”的词向量减去“王后”的词向量。公式是 arg max w s i m ( e w , e k i n g − e m a n + e w o m a n ) \underset{w}{\argmax} \ sim(e_w, e_{king} - e_{man} + e_{woman}) wargmax sim(ew,eking−eman+ewoman) s i m ( u , v ) = u T v ∥ u ∥ 2 ∥ v ∥ 2 sim(u, v)=\frac{u^Tv}{\|u\|_2\|v\|_2} sim(u,v)=∥u∥2∥v∥2uTv表示在给定词嵌入空间中,寻找一个词 w w w ,使得它的词向量 e w e_w ew 与 e k i n g − e m a n + e w o m a n e_{king} - e_{man} + e_{woman} eking−eman+ewoman 的相似度( s i m sim sim )最大。在这个类比关系中,通过这样的词向量运算和相似度计算,可以推断出与“king”(国王)相对应的女性角色“queen”(王后)。
s i m sim sim余弦相似度公式中, ∥ u ∥ 2 \|u\|_2 ∥u∥2 和 ∥ v ∥ 2 \|v\|_2 ∥v∥2 分别是向量 u u u 和 v v v 的 L 2 L_2 L2 范数(欧几里得范数),值越接近 1 表示两个向量越相似,即对应的词语在语义上越相近。
嵌入矩阵
词嵌入矩阵E是一个二维矩阵,维度为 10000×300。矩阵的每一行代表一个维度,共 300 维;每一列对应一个单词,这里有 10000 个单词。单词“orange”(序号 6257 ),在词嵌入矩阵中对应一列,表示为
O
6257
O_{6257}
O6257,即在6257位置上置1。
要获取该单词的词向量,将嵌入矩阵 E E E(10000×300)与一个 one-hot 编码向量 o 6257 o_{6257} o6257 (10000×1 )相乘,得到单词“orange”的词向量 e 6257 e_{6257} e6257 (300×1 ) 。因此,有 E ⋅ O i = e i E \cdot O_i = e_i E⋅Oi=ei O i O_i Oi 是单词 i i i 的 one-hot 编码, e i e_i ei 是单词 i i i 的词向量。但是在实践中,不会做乘法运算,而是使用专门的函数来单独寻找该列。比如在TensorFlow中,使用使用 keras的 Embedding 层获取对应的词向量。
词嵌入
在早期处理词嵌入时,对于句子“I want a glass of orange ?.”,每个单词都有对应的索引,如“I”对应4343,“want”对应9665等。这些单词首先被转换为 one - hot 编码向量,如 o 4343 o_{4343} o4343、 o 9665 o_{9665} o9665等。
one - hot 编码向量 o i o_i oi乘以嵌入矩阵 E E E,得到对应的词向量 e i e_i ei,如 e 4343 = E ⋅ o 4343 e_{4343} = E \cdot o_{4343} e4343=E⋅o4343。
将得到的词向量输入到后续的神经网络层,经过一系列计算,最后通过Softmax层输出。Softmax层的输出维度为词表大小,预测下一个单词的概率分布。
更常见的是通过固定大小的历史窗口,比如4个大小的窗口(只看前4个单词)。在这个算法下,苹果和橙子学到了相似的嵌入。
经过不断的演变,如果目标是学习一个嵌入向量,那么可以使用不同类型的上下文;目标是建立语言模型,一般选取目标词的前几个词作为上下文。
在句子“I want a glass of orange juice to go along with my cereal.”中:
- 上下文和目标词:图中以“orange”为例,标注了它作为目标词,其上下文可以有多种定义方式。
- 上下文窗口设定:
- “Context: Last 4 words”表示将目标词前面的 4 个词作为上下文。
- “4 words on left & right”指目标词左右各 4 个词作为上下文。
- “Last 1 word”即目标词前面的 1 个词为上下文。
- “Nearby 1 word”这种方式与跳字模型相关,跳字模型通常是根据一个词预测其附近的词。
Word2Vec
Word2Vec是基于分布式假设,即语义相近的词在文本中出现的上下文相似。通过对大规模文本语料库训练,将每个单词映射为低维实数向量。其中一个主要架构是跳字模型:
跳字模型
在句子“I want a glass of orange juice to go along with my cereal.”中,选取上下文和目标配对,比如选“orange”作为Context,随机在一定距离选另外一个词作为Target。比如“juice”“glass”“my”等。模型会根据“orange”这个词去预测这些在其附近出现的词。通过大量这样的训练样本,模型能够学习到词语之间的语义关系,并生成有效的词嵌入向量,使得语义相近的词在向量空间中位置接近。
模型细节
词表大小(Vocab size)为10,000,即模型处理的词汇量为10,000个单词。
上下文词(Context):“orange”,其索引为6257。目标词(Target):“juice”,索引为4834。
计算过程是:给定一个词,将这个词的one - hot编码计算词向量,再经过softmax得到预测值用于预测这个词左侧或者右侧跳过几个词后的某一个词应该是什么。
- 词嵌入:上下文词的 one - hot 编码 o c o_c oc乘以嵌入矩阵 E E E,得到上下文词的词向量 e c e_c ec,即 e c = E ⋅ o c e_c = E \cdot o_c ec=E⋅oc。
- Softmax层计算:将词向量 e c e_c ec输入到Softmax层,计算在给定上下文词 c c c的情况下,目标词 t t t出现的概率 p ( t ∣ c ) p(t|c) p(t∣c)。计算公式为 p ( t ∣ c ) = e θ t T e c ∑ j = 1 10000 e θ j T e c p(t|c)=\frac{e^{\theta_t^T e_c}}{\sum_{j = 1}^{10000}e^{\theta_j^T e_c}} p(t∣c)=∑j=110000eθjTeceθtTec,其中 θ t \theta_t θt是与目标词 t t t相关的参数。
- 损失函数:使用交叉熵损失函数 L ( y ^ , y ) = − ∑ i = 1 10000 y i log y ^ i L(\hat{y}, y)=-\sum_{i = 1}^{10000}y_i \log \hat{y}_i L(y^,y)=−∑i=110000yilogy^i来衡量预测概率 y ^ \hat{y} y^与真实标签 y y y之间的差异。真实标签 y y y是一个 one - hot 编码向量,对应目标词“juice”的位置为1,其余位置为0。
在计算 p ( t ∣ c ) p(t|c) p(t∣c)时,分母的求和会消耗大量的时间,使用负采样进行优化。
负采样
对这样一个句子,假设选取context词为"orange",在该词的句子上下文中另外选择一个word,比如"juice",橙子汁是有关联的,将target手动标记为1,是一个正样本。在词表中随机又选了一个词"king"(不一定是上下文),"orange"与"king"关联不大,标记为0,是一个负样本…每组中,第一个是正样本,剩下的k个是负样本。算法将 c o n t e x t − w o r d context - word context−word 对作为 x x x输入,将 t a r g e t target target作为 y y y输出。算法要学习如何分辨是正样本还是负样本,这样,生成了一个训练集。
k的取值是:若数据集较大,k值建议在2-5;若数据集较小,k值建议在5-20。
采用负采样的方法,公式变为
P
(
y
=
1
∣
c
,
t
)
=
σ
(
θ
t
T
e
c
)
P(y = 1|c, t)=\sigma(\theta_t^T e_c)
P(y=1∣c,t)=σ(θtTec) ,
θ
t
\theta_t
θt 是与目标词
t
t
t 相关的参数向量,
e
c
e_c
ec 是上下文
c
c
c 的词向量。
以“orange”(索引为6257 )为例:
- 首先将其 one-hot 编码 o 6257 o_{6257} o6257 乘以嵌入矩阵 E E E ,得到词向量 e 6257 e_{6257} e6257 。
- 然后通过计算 θ t T e 6257 \theta_t^T e_{6257} θtTe6257 并经过sigmoid函数,判断当前词(如“juice”“king”等,词表大小为10000 )是否为“orange”合理的上下文相关词(即判断是否为正样本)。如果是正样本, y = 1 y = 1 y=1;如果是负样本, y = 0 y = 0 y=0 。这个过程用于训练模型区分正样本(语义相关词)和负样本(语义无关词)。之前的公式是计算整整一万个分类,而采用负采样后,只计算一个正样本和k个负样本。
GloVe词向量(了解)
GloVe是另一个词嵌入的方式。定义
x
i
j
x_{ij}
xij是词
i
i
i在词
j
j
j中出现的次数,如果上下文和目标词的范围在其左右各10个词之内,有对应关系
x
i
j
=
x
j
i
x_{ij}=x_{ji}
xij=xji;如果上下文的范围是目标词的前一个,就没有此对应关系。在该算法中,定义上下文和目标词是任意两个位置相近的单词,假设是左右各10词的距离,公式是
GloVe:
J
=
∑
i
=
1
V
∑
j
=
1
V
f
(
X
i
j
)
(
θ
i
T
e
j
+
b
i
+
b
j
′
−
log
X
i
j
)
2
J = \sum_{i=1}^{V}\sum_{j=1}^{V} f(X_{ij}) (\theta_i^T e_j + b_i + b_j' - \log X_{ij})^2
J=i=1∑Vj=1∑Vf(Xij)(θiTej+bi+bj′−logXij)2
- V V V:表示词表的大小,即词表中单词的总数。
- X i j X_{ij} Xij:表示单词 j j j 在单词 i i i 的上下文中出现的次数。反映了单词之间的共现关系。
- f ( X i j ) f(X_{ij}) f(Xij):是一个加权函数,作用是调整不同共现次数的权重。当 X i j = 0 X_{ij}=0 Xij=0 时, f ( X i j ) = 0 f(X_{ij}) = 0 f(Xij)=0,这避免了对没有共现关系的单词对进行不必要的计算,同时也防止了 log 0 \log 0 log0 这种无定义的情况出现。一般来说,对于共现次数较少的单词对给予较高的权重,对于共现次数较多的单词对适当降低权重,以平衡不同频率单词对的影响。
- θ i \theta_i θi 和 e j e_j ej:是待学习的词向量参数。 θ i \theta_i θi 可以看作是单词 i i i 作为上下文词时的向量表示, e j e_j ej 是单词 j j j 作为目标词时的向量表示 。通过训练不断调整,使得模型能够捕捉到单词之间的语义关系。
- b i b_i bi 和 b j ′ b_j' bj′:分别是与单词 i i i 和单词 j j j 相关的偏置项,用于对模型的预测进行微调。
该公式定义了一个需要最小化的损失函数 J J J 。通过最小化这个损失函数,模型可以学习到合适的词向量 θ i \theta_i θi 和 e j e_j ej 以及偏置项 b i b_i bi 和 b j ′ b_j' bj′ 。GloVe模型基于单词共现矩阵,利用这个公式来拟合单词之间的共现概率关系,得到能够反映单词语义信息的词嵌入向量,使得语义相近的单词在向量空间中的距离较近。
情绪分类
情绪分类任务是看一段文本,分辨这个人是否喜欢他们讨论的内容。
因为可标记的训练集没那么多,所以采用词嵌入能够带来更好的效果。将每个单词的 one-hot 编码(如
o
8928
o_{8928}
o8928、
o
2468
o_{2468}
o2468等)乘以嵌入矩阵
E
E
E,得到对应的词向量(如
e
8928
e_{8928}
e8928、
e
2468
e_{2468}
e2468等),这里词向量维度为300维,然后把所有词向量进行平均操作(将所有单词的意思平均起来),得到一个综合的文本特征向量,继续综合特征向量输入Softmax层,输出1 - 5星级的情感评分(
y
^
\hat{y}
y^),判断文本的情感倾向,这里星级越高表示情感越积极。
但是该算法有个缺点:没考虑词序。比如下面一段话,good出现了很多次,但是意思确实完全相反的。该算法会认为这个人给了个好评。
考虑词序问题,可以使用RNN。将RNN用于情感分类的循环神经网络,属于多对一的结构。
句子“Completely lacking in good… ambience”中的每个单词(如“Completely”“lacking”等),首先通过嵌入矩阵
E
E
E转换为对应的词向量(如
e
1852
e_{1852}
e1852、
e
4966
e_{4966}
e4966等)。词嵌入将单词映射为低维实数向量,以捕捉单词语义信息。
在RNN部分,RNN初始隐藏状态 a < 0 > a^{<0>} a<0> 。对于每个时间步,当前单词的词向量输入到RNN中,与上一个时间步的隐藏状态一起计算得到当前时间步的隐藏状态。例如, e 1852 e_{1852} e1852与 a < 0 > a^{<0>} a<0>参与计算得到 a < 1 > a^{<1>} a<1>,以此类推。这种结构使得RNN能够处理序列数据,并捕捉序列中的上下文信息。
最后一个时间步的隐藏状态 a < 10 > a^{<10>} a<10>输入到Softmax层,Softmax层将其转换为情感分类的概率分布,输出预测的情感类别 y ^ \hat{y} y^ 。