07 负采样(Negative Sampling)
这一节在讲什么
这一节讲怎么解决上一节 Word2Vec 的最大问题:
softmax 太慢。
办法就是把“大词表多分类”改造成“少量二分类”,这就是负采样。
核心思路
与其问:
“orange 的附近到底是哪一个词?”
不如改成问:
“orange 和 juice 这两个词,是不是一对真的邻近词?”
这就从一个巨大的多分类问题,变成了很多个更容易的二分类问题。
正样本怎么来
如果在语料中:
orange附近真的出现了juice
那么这对词就是正样本:
\[(c,t,y) = (\text{orange}, \text{juice}, 1)\]负样本怎么来
固定上下文词 orange,再从词表里随机抽一些词:
kingbooktheof
这些通常不是 orange 的真实邻近词,于是构成负样本:
等等。
每个正样本要配几个负样本
课程里记为 $K$。
- 小数据集常取 $K=5$ 到 $20$
- 大数据集常取 $K=2$ 到 $5$
所以一次训练只处理:
- 1 个正样本
- $K$ 个负样本
学习目标变成什么
现在模型要判断一对词 $(c,t)$ 是否是真实共现对。
课程里的公式是:
\[P(y=1 \mid c,t) = \sigma(\theta_t^T e_c)\]其中:
- $e_c$ 是上下文词嵌入
- $\theta_t$ 是目标词参数
- $\sigma$ 是 sigmoid 函数
如果:
orange和juice很搭
那么:
\[\theta_t^T e_c\]应该更大,sigmoid 后更接近 1。
如果:
orange和king很不搭
那这个值就该更小,sigmoid 后更接近 0。
为什么它更快
因为它不再每次都更新整个词表的 softmax。
原来一次更新要管所有 $V$ 个词;
现在一次只更新:
个二分类器。
这在大词表下会快很多很多。
负样本怎么抽最合适
课程提到两个极端都不好:
- 完全按真实词频抽:高频词太多
- 完全均匀抽:又不符合自然语言分布
经验上,Word2Vec 常用下面这个分布:
\[P(w_i)=\frac{f(w_i)^{3/4}}{\sum_{j=1}^{V} f(w_j)^{3/4}}\]其中 $f(w_i)$ 是词在语料中的频率。
这个 $3/4$ 次方是一个经验技巧,能在高频词和低频词之间取得更好的平衡。
小白怎么理解负采样
它有点像这样:
- 我给你一对词:
orange和juice - 你判断:它们像不像常一起出现的一对
再给你:
orange和kingorange和book
你再判断它们不像。
做久了之后,模型就会知道哪些词彼此更“搭”。
这一节最该记住的公式
二分类目标
\[P(y=1 \mid c,t) = \sigma(\theta_t^T e_c)\]负样本采样分布
\[P(w_i)=\frac{f(w_i)^{3/4}}{\sum_{j=1}^{V} f(w_j)^{3/4}}\]这一节最该记住的要点
要点 1:负采样把大词表多分类改成少量二分类
这是它高效的根本原因。
要点 2:每个正样本只配少量负样本
所以训练成本大幅下降。
要点 3:模型学的是“这对词是否像真实共现对”
这比直接做完整 softmax 便宜很多。
要点 4:负样本分布不是均匀抽,也不是完全按词频抽
常用 $f(w)^{3/4}$。
这一节一句话总结
负采样的本质,是把“预测整个词表里的哪个词”简化成“判断这一对词是不是合理共现对”,从而用更少计算代价学到质量很高的词向量。