正负样本
正样本
正样本:曝光而且有点击的用户-物品二元组(用户对物品感兴趣)
问题:少部分物品占据大部分点击,导致正样本大多是热门物品
解决方案:过采样冷门物品,或降采样热门物品
- 过采样 up-sampling 让一个样本出现多次
- 降采样 down-sampling 让一些样本被抛弃
正样本不需要抽样
正样本是用户真实点击的行为,本身就有监督标签,不需要采样。
负样本
如何选取负样本?
简单负样本:全体物品
未被召回的物品,大概率是用户不感兴趣的
未被召回的物品 几乎可以等于 全体物品
所以其实就可以从全体物品中做抽样,作为负样本
问题就在于 均匀抽样 还是 非均匀抽样?
均匀抽样
对冷门物品不公平
正样本 大多数是热门物品,也就是小部分热门物品占据大部分点击的
如果做均匀抽样产生负样本,会导致负样本大多数都是冷门物品
非均匀抽样
目的是打压热门物品
负样本抽样概率与热门程度(点击次数)正相关
抽样概率 正向关于 点击次数的多少次放,一般取值为0.75,如果是0,那就是完全均匀抽样,冷门物品占比过高,如果是1则完全按点击次数,热门物品非常容易被采到,极度冷门的物品几乎不可能被抽到,极端情况下,正负样本分布高度相似,模型难以学到判别边界,太偏向热门
简单负样本:Batch内负样本
在推荐系统中,常用的一种负样本采样方法是 Batch 内负采样(In-batch Negative Sampling)。也就是说,每个 batch 中有 $n$ 个正样本,每个正样本对应的用户会把其他 $n - 1$ 个物品视为负样本,因此一个 batch 会构造出 $n \times (n - 1)$ 个负样本。这种方式非常高效,训练速度快,而且不需要额外采负样本。
但它有一个很大的问题:因为正样本来自用户点击日志,所以热门物品更容易出现在 batch 中。也就是说,一个物品成为负样本的概率实际上和它的点击次数成正比,即
$$
P(i) \propto (\text{点击次数}_i)^1
$$
但我们理想中希望负样本的采样概率不要太偏向热门物品,否则模型会过度打压这些热门物品。更合理的采样方式应是点击次数的 0.75 次方,也就是
$$
P(i) \propto (\text{点击次数}_i)^{0.75}
$$
这样可以在保持一定“热门倾向”的同时,避免热门物品出现频率过高,从而在训练时被“误判”为大量用户都不喜欢。遗憾的是,Batch 内负采样天然就是按点击次数的一次方来取负样本的,这和我们的理想采样分布是有偏差的。
为了解决这个问题,我们可以在 loss 函数中做一个重要性修正。具体来说,对于每一个负样本对 $(a, b_i)$,其中 $a$ 是用户,$b_i$ 是某个物品,我们预估用户对它的兴趣分为 $\cos(a, b_i)$,同时我们知道该物品出现在 batch 中作为负样本的概率为 $p_i$,那么我们可以调整这个负样本的打分为:
$$
\cos(a, b_i) - \log p_i
$$
这个 $-\log p_i$ 项的作用就是“削弱”热门物品在负样本中出现太多带来的打压。也就是说,如果某个物品是热门的,那么它的 $p_i$ 比较大,$\log p_i$ 就也比较大,整体负样本打分会被“往上调”,避免模型惩罚得太狠。
比如某个热门物品 A 的点击次数多,导致 $p_A = 0.05$,而 $\cos(a, b_A) = 0.3$,那么:
$$
\text{Adjusted score} = 0.3 - \log(0.05) \approx 0.3 + 3.0 = 3.3
$$
可以看到,这个调整大大降低了热门物品作为负样本时的惩罚力度,让模型更“公平”地学习它的特征。
这个思想本质上是 Noise Contrastive Estimation(NCE)的一个具体体现:我们知道我们的负样本分布与目标分布不一致,那么就用 $-\log(\text{noise prob})$ 来进行纠偏。
总的来说,Batch 内负采样虽然高效,但存在对热门物品的惩罚偏高问题。通过在训练时减去 $\log p_i$,我们可以有效地实现重要性加权,让负样本分布和我们理想的 $ (\text{点击次数})^{0.75} $ 分布更加一致,从而提升推荐模型的表现,线上召回的时候不用减,还是用原来的余弦相似度