ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

正负样本定义与采样策略:从翻车现场到工程落地全解析

正负样本定义与采样策略:从翻车现场到工程落地全解析 1. 从一个真实翻车现场说起为什么正负样本的定义值得单独拎出来讲刚带团队那会儿我遇到过一次挺典型的翻车。一个做内容审核模型的小组离线评估报告上准确率 96%F1 也漂亮得不行结果灰度上线第一天线上误杀率直接飙到 8%业务方电话打到我这里。排查了两天代码没问题、特征没问题、模型结构也没问题最后发现问题出在一个特别基础的地方——他们把“负样本”的采样逻辑写反了把大量本该是正样本的优质内容当成了负样本喂进去模型学到的决策边界完全是歪的。这件事之后我养成了一个习惯任何跟分类、检索、排序、推荐相关的项目评审第一件事就是问一句“你的正样本和负样本到底是怎么定义的怎么采的”。因为正样本Positive Sample和负样本Negative Sample这两个词看起来是机器学习里最基础的概念但恰恰是最容易在工程落地时被想当然、被糊弄过去的地方。定义偏一点采样偏一点后面所有的调参、加特征、换模型都是在错误的地基上盖楼。这篇内容我想把这两个概念彻底讲透。不是教科书那种“正样本就是标签为 1 的样本”一句话带过而是从定义、来源、采样策略、常见陷阱、不同任务下的差异一直到实际项目里怎么落地检查全部摊开讲。适合刚入门机器学习、正在做第一个分类或检索项目的同学也适合已经工作几年、但一直没系统梳理过样本体系的老手——我见过太多工作三五年的人对这两个词的理解还停留在“正就是好的负就是坏的”这种模糊层面。先把最核心的一句话放在这里正样本和负样本不是数据的固有属性而是相对于你当前要解决的那个任务目标而言的。同一张图片在“识别猫”的任务里是正样本在“识别狗”的任务里就是负样本。这个相对性是后面所有坑的根源。2. 正负样本的本质它们到底在定义什么2.1 从二分类说起标签只是表象决策边界才是目的大多数人第一次接触这两个词都是在二分类任务里。比如垃圾邮件识别垃圾邮件是正样本正常邮件是负样本比如疾病诊断患病是正样本健康是负样本。这时候很容易形成一个直觉正样本就是“我们想要找出来的那一类”负样本就是“其他的”。这个直觉在二分类里基本够用但它掩盖了一个更重要的事实模型真正在学的不是“什么是正样本”而是“正样本和负样本之间的决策边界在哪里”。换句话说负样本的作用不是“凑数”而是和正样本一起把那条边界“夹”出来。我举个具体的例子你就明白了。假设你要做一个“识别图片中是否包含某个特定商品”的模型。如果你只给模型看这个商品的图片正样本模型会学到什么它会学到“这个商品长什么样”但它完全不知道“什么不是这个商品”。上线之后任何一张没见过的图片模型都可能给出高分因为它没见过“反例”。这就是为什么负样本的质量往往比正样本的数量更决定模型的上限。提示很多人调模型时习惯性先加正样本觉得正样本越多模型越准。实际上在大多数场景下负样本的多样性和难度才是决定决策边界质量的关键。2.2 相对性同一个样本在不同任务里的身份切换前面提到的那句“正负是相对的”值得单独展开。我拿推荐系统里的一个真实场景来说明。假设你在做一个“用户是否会点击某商品”的点击率预估模型。对某个用户 U 和商品 A 的组合如果 U 最终点击了 A这个 (U, A) 对就是正样本如果 U 曝光了 A 但没点击这个 (U, A) 对就是负样本。但如果你换一个任务做的是“用户是否会购买某商品”那么“点击了但没买”的这个样本在新任务里就变成了负样本而“点击且购买”才是正样本。同一批行为数据任务目标一变正负的划分就完全变了。再比如目标检测里的 IoU 阈值。一个预测框和真实框的 IoU 是 0.6在阈值设为 0.5 的任务里它是正样本在阈值设为 0.7 的任务里它就变成了负样本。阈值本身就是人为设定的所以正负的边界也是人为设定的。这一点如果不清楚你在看论文或者复现别人代码时会经常被“为什么他的正样本定义和我不一样”搞晕。2.3 多分类与多标签下的“正负”变形二分类之外正负样本的概念会发生变形但内核不变。多分类任务里通常用 one-hot 或者 softmax 来处理严格来说每个类别都有自己的“正负”。比如三分类猫、狗、鸟对“猫”这个类别而言猫是正狗和鸟都是负。训练时 softmax 会同时考虑所有类别但如果你用“一对多”One-vs-Rest的策略那就是拆成三个二分类问题每个问题都有自己的正负样本集。多标签任务更典型。一张图片可以同时有“猫”和“沙发”两个标签。对“猫”这个标签这张图是正样本对“狗”这个标签这张图是负样本。同一个样本在不同标签维度上同时扮演正负两种角色这是多标签任务里最容易被忽略的地方。我见过有人做多标签时把“包含任意一个标签”的样本统一当正样本结果模型完全学不出区分度。2.4 检索与排序任务正负样本的“配对”本质到了检索、召回、排序这类任务正负样本的概念从“单个样本的标签”变成了“样本对的关系”。以向量召回为例你有一个查询Query要从海量文档里找出相关的。这时候正样本是 (Query, 相关文档) 这样的配对负样本是 (Query, 不相关文档) 这样的配对。模型学的是“让 Query 和正样本文档在向量空间里靠近和负样本文档远离”。这里的关键在于负样本不是随便找一篇不相关文档就行。随机负样本太容易区分模型学不到东西真正有价值的是“难负样本”Hard Negative也就是那些看起来相关、但实际不相关的文档。这个后面会专门讲。3. 负样本的采集策略决定模型上限的隐形战场3.1 随机负采样简单但别指望它撑起效果随机负采样是最朴素的做法从全体候选里随机抽一批当负样本。它的优点是实现简单、成本低缺点是绝大多数随机负样本都是“简单负样本”模型闭着眼睛都能分对。我做过一个实验在一个商品召回任务里用纯随机负采样训练出来的模型离线 AUC 能到 0.92看起来不错。但上线后 Top-10 召回的相关性很差。原因就是模型只学会了区分“明显相关”和“明显不相关”对于“有点相关”和“相关”之间的细微差别完全没有分辨力。后来换成混合采样AUC 掉到 0.88但线上效果反而好了很多。离线指标和线上效果背离很多时候就是负采样策略的问题。随机负采样不是不能用它适合作为负样本池的“基底”但绝不能是全部。3.2 难负样本挖掘让模型在“边界地带”反复练习难负样本Hard Negative指的是那些模型当前容易分错的负样本。挖掘思路通常是先用一个基础模型跑一遍把那些被打了高分、但实际是负样本的挑出来加入训练集重新训练。这个过程可以迭代多轮。我一般的做法是第一轮用随机负样本训练一个基础模型用这个模型对全量负样本打分取分数最高的 Top-K 作为难负样本把难负样本和随机负样本按一定比例混合训练第二轮模型重复 2-3 步直到线上指标不再提升。这里有个坑要提醒难负样本不能挖得太狠。如果负样本全是模型当前分错的训练集里就全是“边界样本”模型会过度关注这些难例反而丢失了对整体分布的把握。我通常会把难负样本的比例控制在 30%-50%剩下的用随机负样本兜底。注意难负样本挖掘有个隐患叫“假阴性”。有些被模型打高分的“负样本”其实是因为标注错误或者标注不全它本身可能就是正样本。如果不做清洗直接拿来当难负样本等于在教模型学错的东西。所以挖掘出来的难负样本最好人工抽检一批。3.3 负样本的“难度梯度”设计比单纯挖难负样本更进一步的是设计一个有难度梯度的负样本体系。我把它分成三档难度档位来源作用建议占比简单负样本随机采样稳定训练、防止模型跑偏40%-50%中等负样本同类别不同实例、相似但不相关提升区分度30%-40%难负样本模型高分误判、边界样本逼近决策边界10%-20%这个比例不是固定的要根据任务调整。检索类任务难负样本可以多一些分类任务则要控制否则容易过拟合到难例上。3.4 负样本数量正负比例到底怎么定“正负样本比例多少合适”是我被问得最多的问题之一。网上流传的“1:1”“1:3”“1:10”各种说法都有但没有一个通用答案。我的经验是分场景数据均衡、任务简单1:1 到 1:3 都行看实际效果正样本稀少如欺诈检测、疾病诊断负样本远多于正样本这时候要么下采样负样本要么用类别权重、Focal Loss 之类的损失函数来处理而不是硬凑比例检索召回负样本通常远多于正样本1:4 到 1:10 都常见关键看负样本质量。有个反直觉的结论负样本不是越多越好。当负样本数量超过某个点后边际收益急剧下降反而增加训练成本。我一般会先固定一个比例跑基线然后在这个比例上下各调一档看验证集指标的变化找到那个“拐点”。4. 正样本这边也不是省油的灯4.1 正样本的标注质量假阳性比假阴性更致命大家讨论样本问题时注意力往往在负样本上但正样本的坑一点不少。最常见的就是假阳性——把本该是负样本的标成了正样本。在内容审核场景里假阳性意味着把正常内容标成了违规。这种错误对模型的伤害是双重的一方面模型学到了错误的“违规特征”另一方面这些特征会污染决策边界导致线上误杀。我处理过一个案例标注团队把一批“擦边但合规”的内容标成了违规正样本结果模型上线后对正常内容的误杀率居高不下。假阳性正样本的危害往往比假阴性更大因为它直接教模型学错。4.2 正样本的多样性别让模型只认识“一种正”正样本的多样性同样关键。如果你的正样本全是某一种风格、某一个来源、某一个时间段的数据模型学到的“正”就是有偏的。举个我亲历的例子。做一个“优质评论识别”的模型训练集里的正样本全部来自某个垂类的长评论。模型上线后对短评论、其他垂类的优质评论识别率极低。原因就是正样本的分布太窄模型把“长”和“某垂类”当成了“优质”的特征。后来我们补充了各垂类、各长度的正样本问题才解决。正样本的采集要刻意追求覆盖度不同来源、不同长度、不同风格、不同时间段的都要有。这一点在冷启动阶段尤其重要因为冷启动时你对“正”的理解本身就不完整。4.3 正样本数量不足时的几条出路正样本稀少是很多真实场景的常态。除了前面说的用损失函数处理类别不平衡还有几条路数据增强图像任务里旋转、裁剪、加噪文本任务里同义替换、回译。但要注意增强后的样本不能改变语义否则就是制造噪声。半监督与伪标签用已有模型对未标注数据打标把高置信度的加入训练集。这条路要小心确认偏差模型错了会越错越离谱。迁移学习用相关任务上预训练的模型做初始化减少对正样本数量的依赖。主动学习优先标注那些模型最不确定的样本用最少的标注量换最大的信息增益。这几条路我都在项目里用过效果因场景而异。主动学习在正样本稀少时性价比最高但需要一套能跑起来的标注-训练闭环。5. 不同任务下正负样本的“变脸”实录5.1 目标检测IoU 阈值一改正负全变目标检测里的正负样本划分核心是 IoU交并比阈值。一个锚框Anchor和真实框的 IoU 超过阈值就是正样本低于另一个阈值就是负样本中间的是“忽略样本”。这里的关键参数是阈值怎么设。设高了正样本太少模型学不动设低了正样本质量差定位不准。早期 Faster R-CNN 用 0.7/0.3后来很多工作发现 0.5/0.4 效果更稳。这个阈值没有理论最优只有针对你的数据集和任务调出来的经验值。更麻烦的是小目标。小目标的 IoU 天然就低用统一阈值会导致小目标几乎没有正样本。所以现在很多检测器会用“自适应阈值”或者“ATSS”这类方法根据统计分布动态划分正负。如果你在做检测任务发现小目标召回一直上不去先别急着换 backbone去看看正负样本的划分策略。5.2 推荐系统曝光未点击就是负样本吗推荐系统里有个经典争议曝光未点击Exposure but No Click到底算不算负样本。严格来说曝光未点击包含了多种情况用户没看到、看到了不感兴趣、看到了但当时没空点。把它统一当负样本会引入噪声。但如果不当负样本又很难找到其他可靠的负样本来源。业界的常见做法是分场景处理对“用户确实看到了但没点”的当负样本对“曝光位置靠后、大概率没看到”的降权或者当忽略样本用“随机负采样”补充一部分确定性的负样本。这个问题的本质是负样本的“确定性”。越确定的负样本训练价值越高。曝光未点击的确定性中等所以要么降权要么配合其他负样本一起用。5.3 对比学习正负样本是“构造”出来的对比学习Contrastive Learning把正负样本的概念推到了一个新高度——样本本身没有标签正负是构造出来的。以 SimCLR 为例同一张图片做两次不同的数据增强得到两个视图这两个视图互为正样本同一批次里其他图片的视图都是负样本。模型的目标是让正样本对在向量空间里靠近负样本对远离。这种范式下负样本的数量和质量直接决定了学习效果。批次越大负样本越多效果通常越好——这也是为什么 SimCLR 需要超大 batch size。后来 MoCo 用动量队列把负样本池和 batch size 解耦才让对比学习在普通硬件上也能跑。对比学习里最值得关注的是“假负样本”问题同一批次里可能有两张图片本来就是同一类但被当成了负样本。这会误导模型。所以现在很多工作在做“去偏”或者“软标签”本质上都是在处理正负样本定义的模糊地带。5.4 大模型时代RLHF 里的正负样本到了大模型对齐阶段正负样本又以新的形式出现。RLHF基于人类反馈的强化学习里奖励模型训练用的就是“偏好对”同一个 prompt 下人类更喜欢的回答是正样本更不喜欢的回答是负样本。这里的正负样本不是“对错”而是“相对好坏”。模型学的是排序关系而不是绝对标签。这也意味着正负样本的质量取决于标注者的一致性。如果不同标注者对“哪个回答更好”的判断差异很大奖励模型就会学得摇摆不定。所以 RLHF 里通常要做标注者一致性校验把分歧大的样本剔除或重新标注。6. 实操中怎么检查你的正负样本有没有问题6.1 一套可复用的样本体检清单每次项目上线前我都会跑一遍下面这套检查。你可以直接拿去用定义检查正负样本的定义是否和任务目标严格对齐有没有把“中间态”样本硬塞进某一类分布检查正负样本在关键特征上的分布是否有异常差异比如正样本全是某个时间段的数据。标注一致性检查随机抽 100-200 个样本让不同人重新标一遍看一致率。低于 90% 就要警惕。难易度检查用当前模型对负样本打分看分数分布。如果绝大多数负样本分数都很低说明负样本太简单。泄漏检查训练集和验证集之间有没有样本泄漏尤其是同一用户、同一商品的不同行为很容易跨集泄漏。比例检查正负比例是否在合理范围极端不平衡时是否用了合适的损失函数这套清单看起来基础但每一条我都见过有人栽跟头。尤其是第 5 条样本泄漏隐蔽性极强往往要等到线上效果和离线对不上才被发现。6.2 用混淆矩阵反推样本问题混淆矩阵不只是看模型效果的工具也是诊断样本问题的利器。假阳性高可能是负样本不够难或者正样本里混入了假阳性假阴性高可能是正样本多样性不足或者负样本里混入了假阴性某一类特别差去看这一类样本的数量和分布大概率是样本不均衡或者标注质量问题。我习惯把混淆矩阵和样本分布图放在一起看。有一次发现某个类别的召回特别低一查发现这个类别的正样本只有几十条而且全是早期数据。补充样本后指标立刻上来了。6.3 线上效果和离线对不上时的排查顺序这是最让人头疼的情况。我的排查顺序是先查样本泄漏训练集和验证集有没有重叠特征里有没有包含未来信息再查样本分布偏移训练时的样本分布和线上真实分布差异有多大然后查负采样策略离线用的负样本和线上实际面对的负样本是不是一回事最后查评估指标离线指标和线上业务指标的相关性如何有时候是指标本身选错了。这个顺序是从“最可能出问题”到“最不可能出问题”排的。实际经验里前两步能解决 80% 的离线线上不一致问题。7. 几个我踩过或见别人踩过的坑7.1 把“未标注”当成“负样本”这是新手最容易犯的错。手里有一批数据只标了正样本剩下的没标就直接当负样本用。问题是未标注不等于负样本它可能是“还没标到的正样本”。我见过一个团队做实体识别只标了一部分实体剩下的全当负样本。结果模型学到的“非实体”特征里混进了大量真实体上线后召回惨不忍睹。正确做法是要么把未标注样本单独处理比如用 PU learning要么先抽样标注确认未标注里正样本的比例。7.2 负样本采样引入的“位置偏差”推荐和搜索场景里负样本往往来自曝光日志。但曝光本身是有位置偏差的——排在前面的更容易被点击排在后面的即使相关也可能没被点。如果直接用曝光未点击当负样本模型会学到“排在后面 不相关”而不是真正的相关性。处理办法通常是做位置纠偏或者在采样时对位置做加权。这个问题在排序模型里特别普遍做推荐的同学一定要留意。7.3 正负样本的时间穿越时序数据里用未来信息构造的样本去训练预测过去的模型就是时间穿越。比如用用户今天的购买行为当正样本去预测用户昨天的点击这在逻辑上就不成立。任何涉及时序的任务样本构造必须严格按时间切分。训练集用过去的数据验证集用之后的数据测试集用更之后的数据。我见过有人随机切分时序数据离线指标虚高得离谱上线直接崩盘。7.4 难负样本挖太狠导致过拟合前面提过这里再强调一次。难负样本挖掘是个双刃剑。挖得太少模型学不到边界挖得太多模型过拟合到难例对普通样本的判断反而变差。我的经验是难负样本的比例不要超过负样本总量的一半而且要定期重新挖掘。因为随着模型迭代原来的难负样本会变简单需要挖新的。如果一直用同一批难负样本模型会在这批样本上过拟合。8. 写在最后一点个人体会正样本和负样本这两个词简单到几乎每个入门教程都会提但真正把它们用好需要的不是背定义而是对任务目标的深刻理解和对数据分布的持续观察。我自己这些年最大的体会是模型效果上不去的时候先别急着换模型、调超参回去看看你的正负样本。十次里有七八次问题就出在样本上——要么定义偏了要么采样偏了要么标注质量不行。把样本理顺了很多所谓的“模型问题”会自己消失。另外分享一个小习惯我会给每个项目维护一份“样本定义文档”写清楚正样本是什么、负样本是什么、怎么采的、比例多少、有哪些已知问题。这份文档在团队交接、问题排查、复现实验时特别有用。看起来是额外工作实际上省下的时间远超投入。如果你正在做分类、检索、排序、推荐相关的项目不妨现在就打开你的训练数据按第 6 节那份清单过一遍。大概率你会发现至少一两个之前没注意到的问题。发现了就是赚到改了就有效果。
返回列表