负采样(Negative Sampling)理论与推导
分类: 词向量与表示学习 · 难度: 进阶 · 关联讲座: L02
负采样(Negative Sampling)理论与推导
负采样是 Word2Vec 训练中最关键的加速技巧——将 softmax 的 O(∣V∣) 计算复杂度降至 O(K)。本文从动机出发,完整推导负采样的目标函数与梯度,并通过数值示例和理论分析说明其为什么有效。
1. 完整推导
📐 负采样(Negative Sampling)的完整推导
动机:Full softmax 每次更新需要遍历整个词表 V(∣V∣ 可达数十万),计算代价 O(∣V∣)。能否只更新少量词的向量?
核心思想:将多分类问题转化为二分类问题——区分”真实的上下文词对”和”随机拼凑的词对”。
第 1 步:定义二分类目标
对于一个真实的 (中心词, 上下文词) 对 (c,o),我们希望:
P(真实对∣c,o)=σ(uoTvc)=1+exp(−uoTvc)1
对于随机采样的”负样本”词 k,我们希望:
P(非真实对∣c,k)=1−σ(ukTvc)=σ(−ukTvc)
第 2 步:构建目标函数
对每个正样本 (c,o),采样 K 个负样本 {n1,n2,…,nK},最大化:
J=logσ(uoTvc)+∑k=1Klogσ(−unkTvc)
取负号即为要最小化的损失。
第 3 步:对 vc 求梯度
利用 sigmoid 的性质 σ′(x)=σ(x)(1−σ(x)) 和 dxdlogσ(x)=1−σ(x):
∂vc∂J=(1−σ(uoTvc))⋅uo+∑k=1K(−1)(1−σ(−unkTvc))⋅unk
化简(利用 1−σ(−x)=σ(x)):
=(1−σ(uoTvc))⋅uo−∑k=1Kσ(unkTvc)⋅unk
第 4 步:对 uo(正样本)求梯度
∂uo∂J=(1−σ(uoTvc))⋅vc
Slide 21
第 5 步:对 unk(负样本)求梯度
∂unk∂J=−σ(unkTvc)⋅vc
采样分布:负样本按 P(w)=∑w′f(w′)3/4f(w)3/4 采样,其中 f(w) 是词频。3/4 次幂使低频词被采到的概率相对提高,避免只采高频词。
计算复杂度:从 O(∣V∣) 降到 O(K),通常 K=5-20,加速数千倍。
2. 目标函数的另一种表述
📐 负采样目标函数推导
问题:完整 softmax 的计算瓶颈在分母 ∑w∈Vexp(uwTvc),需要遍历整个词汇表(数十万次)。
解决方案:把预测任务改成二分类——区分真实上下文词(正样本)和随机噪声词(负样本)。
新目标(对于一个 (center, context) 对):
最大化真实上下文词的出现概率 + 最大化随机词不出现的概率:
Jneg(o,c)=logσ(uoTvc)+∑k=1Klogσ(−ukTvc)
其中 σ(x)=1+e−x1,负样本 uk 从噪声分布 P(w)∝U(w)3/4(unigram 的 3/4 次方,提升低频词被采样的概率)。
为什么有效:
- σ(uoTvc) 大 → 中心词和上下文词的向量相似(正确)
- σ(−ukTvc) 大 ↔ σ(ukTvc) 小 → 中心词和负样本词的向量不相似(正确)
复杂度:从 O(V)(全词汇表 softmax)降至 O(K)(K 通常取 5-20)。
3. 数值计算示例
🔢 数值计算:负采样(K=2)
设定:沿用之前的词表,中心词 cat,真实上下文词 dog,负样本为 fish 和 cat 自身。
| 词 | 角色 | uwTvcat |
|---|
| dog | 正样本 | 0.7×0.5+0.1×0.3=0.38 |
| fish | 负样本 1 | 0.3×0.5+0.5×0.3=0.30 |
| cat | 负样本 2 | 0.2×0.5+0.8×0.3=0.34 |
Step 1:计算 sigmoid 值:
σ(0.38)=1+e−0.381=1+0.6841=0.594
σ(0.30)=1+e−0.301=1+0.7411=0.574
σ(0.34)=1+e−0.341=1+0.7121=0.584
Step 2:计算目标函数值:
J=log(0.594)+log(1−0.574)+log(1−0.584)
Slide 22
=log(0.594)+log(0.426)+log(0.416)
Slide 23
=−0.521+(−0.854)+(−0.877)=−2.252
Step 3:计算对 vcat 的梯度:
∂vcat∂J=(1−0.594)⋅udog−0.574⋅ufish−0.584⋅ucat
=0.406⋅[0.7,0.1]−0.574⋅[0.3,0.5]−0.584⋅[0.2,0.8]
=[0.284,0.041]−[0.172,0.287]−[0.117,0.467]
=[−0.005,−0.713]
解读:梯度在第二维分量很大(−0.713),说明 vcat 的第二维需要大幅减小。直觉上,这是因为负样本(fish, cat)的 u 向量在第二维都较大,模型需要让 vcat 远离它们。
对比 full softmax:full softmax 需要对所有 ∣V∣ 个词计算 softmax 概率再求梯度;负采样只需要 1+K=3 个词的 sigmoid 计算。当 ∣V∣=100,000 时,这是 33,000× 的加速。
🔢 SGD 更新一步示例
设定:词汇表 V={the, cat, sat, on, mat},d=2,学习率 α=0.1
中心词 “cat”,真实上下文词 “sat”,负样本 “the”(K=1):
- vcat=[0.5,0.3],usat=[0.4,0.6],uthe=[−0.2,0.1]
计算损失的梯度:
-
spos=usatTvcat=0.4×0.5+0.6×0.3=0.38
-
sneg=utheTvcat=−0.2×0.5+0.1×0.3=−0.07
-
∂vcat∂J=−(1−σ(0.38))usat−(−σ(−0.07))uthe
=−(1−0.594)[0.4,0.6]−(−0.517)[−0.2,0.1]
≈[−0.163,−0.244]+[0.103,−0.052]
=[−0.060,−0.296]
-
更新:vcatnew=[0.5,0.3]−0.1×[−0.060,−0.296]=[0.506,0.330]
观察:vcat 向 usat 方向移动,远离 uthe。
4. 为什么负采样有效?
💡 为什么负采样有效?
负采样看起来是一个粗暴的近似——把 softmax 换成了几个 sigmoid,真的靠谱吗?
理论保证:Mikolov et al. (2013b) 和 Goldberg & Levy (2014) 证明,当 K→∞ 时,负采样的目标函数等价于最大化:
uoTvc≈logP(独立∣o,c)P(共现∣o,c)=PMI(o,c)−logK
即点积在学习逐点互信息(PMI)——这正是统计 NLP 中衡量词共现强度的经典指标。
Slide 24
直觉理解:
- 正样本项 logσ(uoTvc):推动真实共现词对的向量靠近
- 负样本项 ∑logσ(−ukTvc):推动随机词对的向量远离
- 两股力平衡后,向量空间自然编码了词的共现模式
为什么 K=5-20 就够了?
因为大部分词和中心词都没有关系(随机采的词大概率是负例),少量负样本就足以提供”什么是不相关的”的信号。更多负样本带来的信息增益递减,但计算成本线性增长。经验上:小数据集 K=5-15,大数据集 K=2-5。
5. 常见误区
⚠️ 负采样的常见误区
Slide 25
- 误区:负样本随机均匀采样 → 正确:使用 P(w)∝f(w)3/4 分布。如果均匀采样,罕见词几乎永远不会被选为负样本,导致它们的向量得不到有效训练。3/4 次幂是实验发现的最优值——比均匀分布更偏向高频词,但没有按词频等比例那么极端。
- 误区:K 越大越好 → 正确:K 过大会使负样本中意外包含真实上下文词的概率增加(假负例),反而降低性能。而且 K 过大接近 full softmax 的计算量,失去了负采样的意义。
- 误区:负采样和 softmax 学到的向量一样 → 正确:它们学到的向量不完全相同。负采样优化的是二分类损失(sigmoid),softmax 优化的是多分类损失。在实践中,负采样在词类比任务上表现与 softmax 相当甚至更好,但在需要精确概率估计的任务中 softmax 更合适。
⚠️ 常见误区
- 误区:负采样是近似算法,会导致词向量质量下降 → 正确:负采样改变了优化目标,但优化的是更适合词向量学习的目标(二分类而非多分类),实践中效果很好。
- 误区:SGD 每步只更新一个词向量 → 正确:每步更新窗口内所有词的向量(2m 个上下文词 + 1 个中心词),以及 K 个负样本的向量。