文章

07 负采样(Negative Sampling)

07 负采样(Negative Sampling)

这一节在讲什么

  这一节讲怎么解决上一节 Word2Vec 的最大问题:

softmax 太慢。

  办法就是把“大词表多分类”改造成“少量二分类”,这就是负采样。

核心思路

  与其问:

“orange 的附近到底是哪一个词?”

  不如改成问:

“orange 和 juice 这两个词,是不是一对真的邻近词?”

  这就从一个巨大的多分类问题,变成了很多个更容易的二分类问题。

正样本怎么来

  如果在语料中:

  • orange 附近真的出现了 juice

  那么这对词就是正样本:

\[(c,t,y) = (\text{orange}, \text{juice}, 1)\]

负样本怎么来

  固定上下文词 orange,再从词表里随机抽一些词:

  • king
  • book
  • the
  • of

  这些通常不是 orange 的真实邻近词,于是构成负样本:

\[(\text{orange}, \text{king}, 0)\] \[(\text{orange}, \text{book}, 0)\]

  等等。

每个正样本要配几个负样本

  课程里记为 $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 函数

  如果:

  • orangejuice 很搭

  那么:

\[\theta_t^T e_c\]

  应该更大,sigmoid 后更接近 1。

  如果:

  • orangeking 很不搭

  那这个值就该更小,sigmoid 后更接近 0。

为什么它更快

  因为它不再每次都更新整个词表的 softmax。

  原来一次更新要管所有 $V$ 个词;
现在一次只更新:

\[K+1\]

  个二分类器。

  这在大词表下会快很多很多。

负样本怎么抽最合适

  课程提到两个极端都不好:

  • 完全按真实词频抽:高频词太多
  • 完全均匀抽:又不符合自然语言分布

  经验上,Word2Vec 常用下面这个分布:

\[P(w_i)=\frac{f(w_i)^{3/4}}{\sum_{j=1}^{V} f(w_j)^{3/4}}\]

  其中 $f(w_i)$ 是词在语料中的频率。

  这个 $3/4$ 次方是一个经验技巧,能在高频词和低频词之间取得更好的平衡。

小白怎么理解负采样

  它有点像这样:

  • 我给你一对词:orangejuice
  • 你判断:它们像不像常一起出现的一对

  再给你:

  • orangeking
  • orangebook

  你再判断它们不像。

  做久了之后,模型就会知道哪些词彼此更“搭”。

这一节最该记住的公式

二分类目标

\[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}$。

这一节一句话总结

  负采样的本质,是把“预测整个词表里的哪个词”简化成“判断这一对词是不是合理共现对”,从而用更少计算代价学到质量很高的词向量。

本文由作者按照 CC BY 4.0 进行授权