引言
在自然语言处理(NLP)中,词嵌入(Word Embedding)是表示词汇语义的关键技术。2013年,Google提出的Word2Vec模型彻底改变了这一领域,其核心思想是通过无监督学习将单词映射到低维稠密向量空间中,使得语义相似的词在向量空间中距离相近。Word2Vec包含两种主要模型:
- CBOW(Continuous Bag-of-Words):通过上下文预测中心词。
- Skip-Gram:通过中心词预测上下文。
1.Word2Vec概述
核心思想,Word2Vec基于分布式假设:
“具有相似上下文的词,其语义也相似。”
例如,句子 "The cat sits on the mat"
和 "A dog lies on the rug"
中,cat
和 dog
的上下文相似,因此它们的向量表示应接近。
1.1 训练方法:Skip-Gram vs CBOW
假设每个单词与其邻近的单词之间存在最紧密的联系,即每个单词都是由其周围的单词所定义的(CBOW模型的核心理念)。或者,从另一个角度来看,每个单词都对其相邻的单词起到了决定性的作用(Skip-gram模型的主要原理)
模型 | 输入 | 输出 | 适用场景 |
---|---|---|---|
CBOW | 上下文词 | 中心词 | 高频词预测 |
Skip-Gram | 中心词 | 上下文词 | 低频词捕捉、更通用 |
实际上后者用的更多、效果也相对较好,本文重点解析Skip-Gram的数学模型。
2.Skip-Gram模型架构
Skip-Gram的目标是:给定中心词,预测其窗口内的上下文词。例如,对于窗口大小=2的句子 "I love natural language processing"
:
- 中心词:
love
- 上下文词:
I
,natural
,language
网络结构
- 输入层:中心词的one-hot编码(维度=词汇表大小
V
)。 - 投影层:将输入映射到低维稠密向量(维度=
d
,即嵌入维度)。 - 输出层:通过权重矩阵计算上下文词的概率分布。
Embedding的概念:Embedding 其实是训练出一个维度为 的词向量矩阵 ,其中 是词汇表大小, 是每个词的向量维度。样本经过 One-hot 编码后会变成一个 的稀疏向量,其中仅有一个位置为 1(表示中心词)。与 矩阵进行矩阵乘法 和 后得到一个 的向量,表示中心词的词向量。由于 One-hot 编码的稀疏性质,实际上是从 中抽取了某一行作为该词的向量表示,所以这个训练好的矩阵也被称为查找表(lookup table)。
2.1 Skip-Gram的数学模型
Skip-Gram 模型的目标是通过给定中心词 来最大化上下文词 的条件概率。我们用 表示中心词,用 表示上下文词, 的上下文范围为 (通常是一个小窗口,例如 5 个词)。
Skip-Gram 模型的目标是最大化以下概率:
其中, 表示给定中心词 ,预测上下文词 的概率。
2.2 概率计算
为了计算 ,我们需要对每个上下文词的概率进行建模。Skip-Gram 模型使用 Softmax 函数来计算概率:
其中:
- 是中心词 的词向量。
- 是上下文词 的词向量。
- 是词汇表的大小。
Softmax 函数通过计算词向量之间的点积来衡量中心词和上下文词之间的相似度。
值得注意的是,参考最上面的模型架构图
- 和并不在同一个向量空间中。
- 模型有两个矩阵,分别为输入矩阵,输出矩阵, 输入向量转变为Embedding是通过
输入层到隐藏层的权重矩阵Q
,但是输出向量并不是直接从输入矩阵中获取,而是通过输出矩阵获取,所以可以看到输入向量即Embedding 与输出矩阵相乘其实就是在算他与其他词向量的点积 再通过softmax计算相似性。
2.3 训练目标
Skip-Gram 模型的目标是通过优化损失函数来最大化条件概率。所以采用极大似然估计法,加上负号(注意原文是求最大值,但是加上负号求最小值其实是一样,并且更符合损失函数定义),并取对数形式,得到损失函数表示如下
其中:
- 是句子的总词数。
- 是上下文窗口的大小。
通过优化这个损失函数,模型能够学习到每个词的低维向量表示,从而捕捉到词与词之间的语义关系。
2.4 Skip-Gram 模型的训练过程
- 初始化: 为每个词语初始化一个随机向量。
- 遍历语料: 对每个中心词 ,选择一个上下文窗口,遍历窗口中的上下文词 。
- 计算概率: 使用 Softmax 计算 。
- 更新词向量: 使用梯度下降法优化模型,更新词向量。
2.5 代码实现
class Embedding(nn.Module):
def __init__(self, input_dim, emb_dim):
"""
初始化 Embedding 层。
:param input_dim: 输入特征的维度。
:param emb_dim: 嵌入的维度。
"""
super(Embedding, self).__init__()
self.input_matrix = nn.Parameter(torch.randn(input_dim,emb_dim)) #输入特征的嵌入矩阵
self.output_matrix = nn.Parameter(torch.randn(emb_dim,input_dim)) #输出特征的嵌入矩阵
def forward(self,x):
"""
前向传播函数。
:param x: 输入张量,形状为 (batch_size, input_dim)。
:return: 返回样本与整个词汇表的点积,形状为 (batch_size, input_dim)。
"""
embedding = torch.matmul(x,self.input_matrix) #获取输入特征的嵌入表示
product = torch.matmul(embedding, self.output_matrix) #计算输入特征与整个词汇表的点积
return torch.softmax(product,-1) #对点积进行softmax归一化 (batch_size, input_dim)
3优化方法
直接计算全量Softmax(复杂度 O(V)
)在大词汇表下不可行。上面也可以看到,每个样本在softmax那块都需要计算整个词汇表的输出概率,这样的计算开销实际上是非常大的,常用优化方法:
1.负采样:为了提高训练效率,Skip-Gram 模型通常使用负采样(Negative Sampling),即只对一部分负样本进行训练,而不是对整个词汇表进行训练。
推导过程如下:
用以下损失近似原始目标:
其中:
σ
是sigmoid函数- 表示给定中心词 c的Embedding向量 和上下文词(正样本)的向量,负样本向量
K
是负样本数(通常5~20)- 是噪声分布(如词频的3/4次方)
这里对进行扩展
其中: 是词 在语料库中的频率。
- 是语料库中每个词 的频率。
选择词频的 3/4 次方作为噪声分布的权重,有以下几个原因:
- 减少高频词的选择概率:高频词(如 "the"、"is" 等常见功能词)并不太有助于捕捉语义信息,因此通过降低其选择概率,避免其过多出现在负样本中。
- 提高低频词的选择概率:低频词对于模型学习更具挑战性和语义信息,因此提高低频词的选择概率,有助于模型学习到更加丰富的语义表示。
推导过程如下:
符号表示
表示给定中心词 和上下文词 的正样本概率, 表示负样本概率。
优化目标:
接下来,利用 Sigmoid 函数的定义 ,将模型的预测概率表达为:
于是,上式变为:
为了符合损失函数形式,我们取负号,求最小值,得到最终的优化目标即为:
2.Hierarchical Softmax:通过使用哈夫曼树优化 Softmax 计算,进一步提高训练效率。
总结
- Skip-Gram的优势:
- 擅长捕捉低频词。
- 生成的高质量词向量可应用于语义分析、推荐系统召回等。
- 数学本质:
通过最大似然估计,学习词向量以编码上下文相似性。 - 实际应用:
- 预训练词向量(如GloVe、BERT的基础)。
- 相似词检索、文本分类、命名实体识别等。
参考文献
- Mikolov et al. (2013). Efficient Estimation of Word Representations in Vector Space.
- Goldberg & Levy (2014). word2vec Explained.
- Rong, Xin. "word2vec Parameter Learning Explained." arXiv, November 2014. University of Michigan
- 王喆《深度学习推荐系统》
- word2vec跳字模型skip-gram详解,使用Pytorch实现