老周开了家美食评测工作室,手握 10 个免费试吃名额,要从几百家新开的小店里挑出最值得「花名额」的店。第一直觉是挑口碑最两极分化的店——争议大说明口味独特,试吃后信息量最大。可实践下来他发现不对劲:那些开在犄角旮旯、周围没几步路的「重口味孤店」,争议确实大,但试吃完拍个照就完事了,参考价值极低;反倒是开在繁华街区、周边同类型店扎堆、口碑又分歧的店,一尝就能摸清一整片区域的饮食偏好。这个经验,恰好就是机器学习里「密度加权采样」的核心直觉:选样本不能只看「模型多拿不准」,还要看「这个样本周围有多少同类邻居」。前者叫不确定性,后者叫密度。两者相乘,才是真正值得标注的样本。主动学习就像探店,预算有限,每一次试吃(标注)都得花在刀刃上。
掌握密度加权采样,是 AI 从业者在数据标注成本高昂的现实中「用最少标注换最高模型性能」的必修课。它直接决定你手上的数据预算花得值不值,是数据科学工程师与算法工程师协作时最常用的采样策略之一。
可视化演示
展示SGD、Momentum、Adam三种优化器在损失曲面上的收敛轨迹,对比不同优化策略的收敛速度和稳定性,支持切换优化器模式和步进控制。
本节配有交互动效(进入视口后自动加载,约 3KB)。
三种优化器对比 SGD: 基础梯度下降,可能振荡 Momentum: 累积动量加速收敛 v_t = β·v_{t-1} + (1-β)·g_t
主动学习概述
老周的试吃名额只有 10 个,打电话叫同行帮忙也没用——专业品鉴师按小时收费,每尝一家店都得付钱。他总不能把几百家店全试一遍。聪明的做法是:先随便试几家,摸清整个街区的口味分布规律,然后根据已有经验,挑「信息量最大」的店接着试。这就是主动学习的本质:让模型自己决定下一个该学什么,而不是被动地等着喂数据。
在传统监督学习中,训练数据大多靠随机抽样标注,模型没得选。但真实业务里,几十万条未标注数据摆在那,人工标注又贵又慢。主动学习的做法是维护一个「查询策略循环」:先用少量已标注数据训练一个弱模型,让模型对未标注池里的每个样本打分,选出最有价值的样本交给人工标注,再把它纳入训练集重新训练。如此往复,用最少的标注预算撬动最大的模型性能。
1. 训练集 D:当前已经标注好的数据集合,相当于老周已经试吃完并写好评价报告的店铺清单。
2. 选中样本 x\*:查询策略挑出的「最值得标注」的样本点,相当于从候选清单里选出下一家要试吃的店。
3. 人工标注 y\*:人类专家给样本打上的标签,相当于品鉴师给出试吃评价。
4. 集合并运算 ∪:把新标注的样本并入训练集,使 D 变大,相当于把新店的评价报告装进档案夹。
这样一来,「店越试越多、口味判断越来越准」的循环就转起来了。主动学习的全部学问,都浓缩在一个问题上:到底按什么规则给候选样本打分排序?老周的第一版答案天真又直白——哪家争议大选哪家。
不确定性采样
老周的第一版选店规则很简单:看点评平台上的口味评价,评分两极分化越严重(一堆五星配一堆一星)的店越值得试。理由很直接:评价一致说明口味稳定,试了也学不到新东西;评价分裂才说明这家店藏着模型判断不了的「意外」。这个直觉在机器学习里对应着最经典的查询策略——不确定性采样。
不确定性采样的逻辑是:训练完模型后,让模型对未标注样本做预测,最「拿不准」的样本优先标注。怎么量化「拿不准」?常用方法有三种:看预测最高概率有多低、看最高两个概率的差距(分类边距)有多小、看类别的熵有多大。最常用的是边距法:
1. 最大概率 p₁(x):模型认为样本 x 最可能属于的类别概率,相当于「店里好评率最高的口味方向」。
2. 次大概率 p₂(x):模型心中第二可能的类别概率,相当于「好评之下隐藏的第二口味方向」。
3. 相减得到边距:两个概率越接近,边距越小,模型越分不清它们,说明这家店的「口味信号」真的矛盾。
靠这个规则选出来的样本,大多分布在模型决策边界附近,对提升模型精度确实立竿见影。但老周很快发现了 bug:他试了一家开在废弃工厂旁、周围五百米没有第二家饭馆的「孤岛重辣店」,评价确实吵翻天,可吃完发现,它的口味极端得毫无规律,既不代表川菜也不代表湘菜,对后续选店毫无参考价值。机器学习里这叫离群点,是纯不确定性采样最容易踩的坑——把宝贵的标注预算浪费在「与人无关的怪店」上。
密度加权思想
老周复盘后悟出一个道理:一家店值不值得试吃,不能只看「争议度」,还要看「周边的店多不多、人流旺不旺」。开在美食街上的店,口味风格自然会辐射到周围的同类店铺,试吃一家就能推断整片街区的偏好;开在荒郊野外的店,口碑再分裂也只是一家孤例。于是他把选店公式升级为:试吃价值 = 口味争议度 × 街区人流密度。
这正是密度加权采样的核心思想:给不确定性采样加一个「代表性」约束。候选样本不但要让模型困惑,还得处在特征空间中样本密集的区域,这样标注它的收益才能通过「邻居」扩散到一大片相似数据上。形式化地写,就是综合得分等于不确定性与密度的乘积:
1. 不确定性 u(x):衡量模型对样本 x 的困惑程度,延续上一节的边距定义,等价于「口碑争议度」。
2. 密度 ρ(x):衡量 x 周围邻居的聚集程度,等价于「街区人流热度」,下一节会给出具体算法。
3. 乘法连接:任何一项为 0,综合得分都是 0。争议再大但周围没人,价值归零;人流再旺但模型毫无困惑,同样不值得标注。
这个乘积公式朴素却深刻。它回答了主动学习里的一个根本问题:什么叫「好的样本」?答案不是「模型最不懂的」,也不是「数据里最典型的」,而是既让模型困惑、又能代表数据分布的复合体。老周把这个公式写在工作室白板最上方,旁边配了行批注:别再做孤岛探店人。
密度计算方法
到这一步,老周需要把「街区的热闹程度」量化成能算的数字。他很快定下方案:以目标店铺为圆心,看离它最近的 k 家店的平均距离——平均距离越近,说明店铺越扎堆,密度越高。如果距离远得离谱,说明这家店开在餐饮荒漠里,密度趋近于零。
在数学上,这个直觉对应「k 近邻平均距离的倒数」。设样本 x 的 k 个最近邻为 x(1), x(2), …,x(k),距离度量常用欧氏距离,则密度项为:
1. k 个最近邻:与 x 距离最近的 k 个样本,对应「离我最近的 k 家店」。k 是超参数,通常取 5~20。
2. 距离函数 d:计算两个样本点在特征空间中的欧氏距离,对应两家店之间的「真实距离」。使用前必须做特征归一化,否则量纲大的特征会霸占距离。
3. 平均距离:把 k 个邻居的距离求平均,得到「平均多远能找到一家同类店」。
4. 取倒数加常数 ε:平均距离越小,倒数越大,密度越高;ε 防止分母为 0,同时让极端聚集点不爆表。
除了 k 近邻距离法,还有一种更直观的「半径计数法」:以 x 为圆心画一个半径 r 的圆,数一数圈里有多少个样本点,数量越多密度越大。半径计数法理解简单,但半径 r 不好调;k 近邻法对邻域尺度自适应,是工程上的主流选择。老周的街区热力图终于做出来了——他要做的,就是在这张热力图上叠加「口碑争议分布」,找出两者同时高亮的坐标。
批量采样技巧
老周现在是美食街的「首席选店师」,每次能拿到 10 个试吃名额。他发现一个尴尬问题:如果单纯按综合得分取 Top 10,这 10 家店很可能开在同一条街上甚至隔壁——试吃 1 家和试吃 5 家得到的信息几乎一样,名额被白白浪费。批量场景需要额外一重考量:多样性。
主动学习里的批量采样(Batch Mode)正面临同样的问题。每轮要选 b 个样本,不能机械地取分数最高的 b 个,而是要让选出的这批样本内部尽量互不相同,避免信息冗余。常见做法是引入「冗余惩罚」:每当一个样本被选中,就把它的分数分给它的邻居们「降温」,让附近相似度高的样本在下一轮评分中自动降权:
1. 已选集合 B:当前轮次已经确定要标注的样本集合,对应「已经拿到试吃名额的店」。
2. 相似度 sim:两个样本在特征空间中的接近程度,可用距离的倒数或核函数刻画,对应「两家店风格有多像」。
3. 惩罚总和:x 与所有已选样本的相似度总和。一条街上已选 5 家,周围店的惩罚就极重。
4. 原始得分减去惩罚:每个候选样本从 s(x) 里扣掉冗余项。λ 调大,多样性更强;λ 调小,更偏向原始综合得分。
这个技巧让老周的选店覆盖了整条美食街的各个片区:甜水巷选一家重辣的,书院街选一家清淡的,南门桥选一家异国风味的。每轮试吃完更新口碑档案,重新训练「口味模型」,下一轮再出发。数据在没有冗余的情况下一点点积累,模型的视野逐渐覆盖全城。
采样效果评估
跑了三个月的试吃项目后,老周想验证一个关键问题:密度加权到底比纯不确定性多赚了多少? 他把两种策略的试吃记录摊开对比,发现两组数据点的差异一目了然。纯不确定性采样的档案夹里堆满了孤独的怪店——口味的覆盖面东一块西一块;密度加权采样的档案夹则像一张完整的街区地图,每个区域都有代表性样本,每一类饮食风格都被均匀照顾到。
这种差异在机器学习评估中表现为三个可量化的指标。其一是样本效率:在相同标注预算下,密度加权策略训练出的模型通常比纯不确定性策略获得更高的测试精度,尤其在数据分布不均衡或存在大量离群点的场景下,差距会进一步拉大。其二是数据均衡性:纯不确定性倾向于反复纠结在决策边界附近的难样本,而密度加权通过「区域热度」天然把采样视线拉回主流数据区域,训练集的类别分布更接近真实分布。其三是模型鲁棒性:由于训练集不再混入大量「怪样本」,模型对噪声的抗干扰能力明显增强,部署到线上后预测波动更小。
实践中的典型收益是:在同样的 20~30 个标注样本预算下,密度加权比纯不确定性采样平均提升 3~8 个百分点的准确率,且这种优势随标注预算减少反而增大——预算越紧,每一发标注子弹越要打在密集目标区。老周把这个结论写成月度报告发给投资人,配了张图:两条学习曲线都在上升,但密度加权那条始终稳稳压在纯不确定性上面,像两条并行上行的山路,带密度权重的走得更快更稳。
工程实践要点
老周把三个月的经验提炼成了一份「选店 SOP」,贴在工作室墙上。第一条:k 值别拍脑袋。k 太小,比如 k=1,密度只看最近一位邻居,容易被偶然靠近的样本带偏;k 太大,比如 k=50,密度退化成全局平均值,区分度消失。工程上建议先用 k 近邻距离的分布直方图观察数据,取距离显著变化的拐点附近作为 k,通常落在 5~20 之间。
第二条:特征必须归一化。密度计算依赖距离,而欧氏距离对特征的量纲极其敏感。比如做客户分群时,「年龄」的波动范围是 0~100,而「年消费额」可能是 0~100000,直接算距离的话,年龄维度形同虚设,密度完全被消费额主导。用 StandardScaler 或 MinMaxScaler 把每个特征拉到同一尺度,是密度计算的地基工程。
第三条:不确定性度量要因模型而异。逻辑回归用分类边距、随机森林用置信度、神经网络用熵或 MC Dropout 估计,不同模型要选匹配的困惑度指标,但密度项的计算是通用的。最后还要记住:密度加权不是孤立策略,它可以与困难样本挖掘、类别平衡约束、核心集选择(Core-Set)等策略自由组合。老周的最后一条心得是:SOP 是死的,街区是活的,好顾问会看热力图微调参数,好工程师也会每轮采样后回头审查被选中样本的分布是否合理——毕竟采样策略服务于数据质量,而数据质量决定模型上限。
AI 应用场景
医学影像标注筛选
阶段:数据标注与管理
解决的问题:医院每天产生数千张 CT 影像,专业放射科医生标注一张图需 10 分钟,预算极其有限。随机抽样会造成大量标注落在「正常影像」上,纯不确定性采样则会被罕见的病灶变异影像带偏。密度加权采样在不损失罕见病召回率的前提下,优先标注「模型既拿不准、又具有典型结构特征」的影像,让有限的医生工时覆盖最有教学价值的病例。
具体案例:某三甲医院与 AI 公司合作开发肺结节检测系统,从 5 万张未标注 CT 中筛选 800 张进行标注。使用密度加权策略后,模型在测试集上的灵敏度达到 0.92,比纯不确定性采样高出 5 个百分点;且训练集中正常/异常比例与全院真实分布一致,避免了标注数据偏斜。
智能客服语料清理
阶段:数据准备与特征工程
解决的问题:企业积累的客服对话日志中,约 70% 是「查余额」「改密码」等高频简单问题,剩下 30% 是长尾复杂诉求。如果随机抽样标注,训练集全被高频问题塞满;如果只看不确定度,又会被那些「语气极端但毫无普适性」的一次性投诉带偏。密度加权让系统兼顾意图的多发性和代表性。
具体案例:某银行智能客服项目从 20 万条对话中挑选 3000 条标注意图。纯不确定性策略挑出的样本里有 200 多条是孤立的情绪发泄话术,无法归类;密度加权策略让意图类别覆盖率从 61% 提升到 89%,冷启动阶段的意图识别准确率提升 12%。
工业缺陷检测样本补充
阶段:模型迭代与数据闭环
解决的问题:产线质检相机每分钟拍 200 张产品图,其中缺陷样本占比不足 1%,且缺陷类型多达几十种。已有模型能稳定识别常见划痕,但对罕见但致命的「内腔裂纹」认知不足。密度加权采样会在「模型困惑度中等、但同类缺陷样本聚集」的区域持续补充标注,让模型不漏掉小概率灾难性缺陷。
具体案例:某汽车零部件厂商利用密度加权采样对 2 万张未标注图进行主动筛选,人工复核 500 张后,模型对罕见缺陷的召回率从 0.54 提升至 0.81,且未增加常见缺陷的误报率。
Python 演示
import numpy as npfrom sklearn.datasets import make_moonsfrom sklearn.linear_model import LogisticRegressionfrom sklearn.metrics import accuracy_scorefrom sklearn.neighbors import NearestNeighbors def score_samples(features, probs, k=5, eps=1e-6): probs = np.sort(probs, axis=1) margin = probs[:, -1] - probs[:, -2] # 分类边距 uncertainty = 1.0 - margin # 边距越小, 不确定度越大 nn = NearestNeighbors(n_neighbors=k + 1) # 多取1个, 因为第0个是自己 nn.fit(features) dist, _ = nn.kneighbors(features) density = 1.0 / (np.mean(dist[:, 1:], axis=1) + eps) # k近邻平均距离倒数 def normalize(v): return (v - v.min()) / (v.max() - v.min() + eps) return normalize(uncertainty) * normalize(density) # 两项乘起来 def active_learning(features, labels, budget=24, k=5, use_density=True): labeled_idx = [0, 100] # 两类各预热一个样本 for _ in range(budget - 2): model = LogisticRegression(max_iter=200) model.fit(features[labeled_idx], labels[labeled_idx]) probs = model.predict_proba(features) if use_density: score = score_samples(features, probs, k=k) else: probs = np.sort(probs, axis=1) margin = probs[:, -1] - probs[:, -2] score = 1.0 - margin score[labeled_idx] = -1.0 # 已标注样本不再参与挑选 labeled_idx.append(int(np.argmax(score))) model = LogisticRegression(max_iter=200) model.fit(features[labeled_idx], labels[labeled_idx]) return accuracy_score(labels, model.predict(features)), labeled_idx if __name__ == "__main__": features, labels = make_moons(n_samples=200, noise=0.2, random_state=42) acc_u, idx_u = active_learning(features, labels, use_density=False) acc_d, idx_d = active_learning(features, labels, use_density=True) print(f"uncertainty only acc: {acc_u:.3f} ({len(idx_u)} labeled)") print(f"density weighted acc: {acc_d:.3f} ({len(idx_d)} labeled)")
uncertainty = 1.0 - margin分类边距越小,模型越纠结,不确定度越大,等价于「口碑争议度」。nn = NearestNeighbors(n_neighbors=k + 1)建立 k 近邻索引,多取一个因为距离为 0 的自己不算邻居。density = 1.0 / (np.mean(dist[:, 1:], axis=1) + eps)最近 k 个邻居的平均距离取倒数,再加小常数防除零。normalize(uncertainty) * normalize(density)两项分别归一化到 0~1 后相乘,避免量纲不同导致某一边主导。labeled_idx = [0, 100]用两个预热样本保证初始模型能训练(两类各一个),否则单类数据逻辑回归会报错。score[labeled_idx] = -1.0已标注样本的分数设为负数,保证它们不会被重复选中。make_moons(n_samples=200, noise=0.2, random_state=42)生成两个月牙形分类数据,带随机噪声,分布不均但无离群点。
常见误区
误区我觉得密度加权就是把所有样本按密度排序,选密度最高的那批标注就行,密度越大代表性越强,肯定没错。
正解密度只代表「周围人多」,不代表「模型困惑」。如果模型已经稳定判断某片密集区域是 A 类,标 100 个也学不到新东西。密度加权的精髓在「乘积」:密度高但不确定性低的样本,综合得分依然接近 0。好比美食街中心有家百年老店,口味传承稳定、毫无争议,探店预算再充足也不会优先试它。
为何常见:人们容易抓住新概念里最直观的部分(密度),却忽略了公式里它和不确定性是乘法关系,任何一个因子为 0 都会让价值归零。
误区特征就是一堆数值,直接算欧氏距离不就行了?归一化是锦上添花,不太影响采样结果。
正解欧氏距离对量纲极度敏感。消费金额的数值范围可能是 0~100000,年龄是 0~100,距离几乎完全由金额维度决定,「年龄相似」的邻居完全排不上号。密度会失真,选出来的「密集区」其实是单维度上的伪聚集。归一化不是细节优化,而是密度计算正确性的前提。
为何常见:很多教程的示例数据恰好是同一量纲的,把关键步骤掩盖了;换到真实的多维异构特征时,坑才暴露出来。
误区每轮不是要选 b 个样本吗?那把 s(x) 算出来,从大到小取前 b 个,简单高效。
正解前 b 名极有可能是彼此挨着的「高密度高不确定区」,信息高度重叠。批量采样必须考虑内部多样性,对已选样本的邻居做冗余惩罚,否则 b 个名额只顶 1 个用。好比试吃名额全给同一条街的 10 家川菜馆,品类覆盖为 0。
为何常见:单样本策略推广到批量时,人们习惯性沿用 Top-k 思维,忽略样本之间并非独立这件事。
误区少数类样本少、密度低,密度加权会不会让多数类被大量选中?那它是不是天然就能平衡类别?
正解恰恰相反,多数类区域密度高,密度加权在类别不平衡时反而会偏向多数类,让采样更不平衡。若目标是平衡类别,需要在密度项上叠加类别权重,或者分别计算各类内部的密度再做相对比较。密度加权解决的是「离群点干扰」和「代表性不足」,不是类别平衡。
为何常见:把「数据分布的代表性」和「类别均衡」混为一谈,误以为代表性会自动带来均衡性。
面试题
Q1. 主动学习的核心目标是下列哪一项?
- A.减少模型参数数量
- B.降低人工标注成本← 正确答案
- C.提升在线推理速度
- D.生成更多合成数据
答案:B。主动学习的本质是在有限标注预算下,通过「模型主动选样本 + 人机协作标注」用更少标注达到更好效果。减少参数、提升推理速度与采样策略无关,合成数据也属于数据增强范畴而非主动学习。
Q2. 用分类边距度量不确定性,模型对某样本输出概率为 [0.6, 0.3, 0.1],则该样本的边距是多少?
- A.0.3← 正确答案
- B.0.6
- C.0.1
- D.0.5
答案:A。分类边距 = 最大概率 − 次大概率 = 0.6 − 0.3 = 0.3。边距越小,说明模型在前两个类别间越犹豫,不确定度越高。0.6 是第一类的概率本身,0.1 是最小类概率,0.5 是两类别概率之差算错。
Q3. 密度加权综合得分 s(x) = u(x) × ρ(x),下列哪类样本得分最高?
- A.高不确定且高密度← 正确答案
- B.高不确定但低密度
- C.低不确定但高密度
- D.低不确定且低密度
答案:A。两项相乘要求样本既让模型困惑(不确定度高)又处于密集区域(密度高),任何一项为 0 都会让乘积归零。高不确定低密度的样本是离群点,低确定高密度的样本是「已拿稳」的典型点,都不值得优先标注。
Q4. 使用 k 近邻平均距离倒数计算密度时,k 取值过小会带来什么后果?
- A.密度受局部噪声影响← 正确答案
- B.密度接近全局平均值
- C.距离计算显著变慢
- D.模型训练直接失败
答案:A。k 太小意味着只看最近的极少数邻居,一个偶然靠近的离群点就会把平均距离大幅拉近,导致密度虚高。k 太大才会让密度趋近全局平均;距离计算主要受样本量影响而非 k 值;模型训练失败与 k 无直接关系。
Q5. 批量采样(Batch Mode)中,如果不加冗余惩罚,最可能出现什么问题?
- A.样本间高度重复← 正确答案
- B.离群点占比过高
- C.密度权重失效
- D.标注无法复现
答案:A。Top-b 策略会选中一批高得分的相邻样本,信息高度重叠,b 个名额等于只覆盖了一个局部区域。离群点问题由不确定度单方面导致,密度权重失效与惩罚机制无关,标注可复现性也不受冗余影响。
Q6. 特征不做归一化直接计算欧氏距离,对密度项会产生什么影响?
- A.距离被大数值特征主导← 正确答案
- B.所有距离都变为零
- C.密度权重恒等于一
- D.不确定性无法再计算
答案:A。欧氏距离对量纲敏感,数值范围大的特征会主导距离计算结果,其他维度形同虚设,算出的「密集区」是单维伪聚集。距离不会因此归零或恒一,不确定性来自模型输出概率,与特征尺度无关。
Q7. 密度加权采样相对纯不确定性采样的主要优势是什么?
- A.训练集更具代表性← 正确答案
- B.模型推理速度更快
- C.特征维度自动降低
- D.标注不再需要人工
答案:A。密度项把「模型困惑」约束到「数据密集区域」,让选出的训练覆盖更均衡、更贴近真实分布,避免预算浪费在离群点上。推理速度、特征维度和标注方式都不受采样策略影响。
Q8. 以下哪些指标或方法常被用于量化「不确定性」?
- A.分类边界最小边距← 正确答案
- B.预测熵值最大← 正确答案
- C.最近邻数量最多
- D.分类置信度最低← 正确答案
答案:ABD。边距越小、熵越大、置信度越低,都表示模型对样本越没把握,是标准的不确定性度量。最近邻数量最多描述的是密度而非不确定性,属于密度项的计算范畴。
Q9. 下列哪些做法有助于提升密度加权采样的稳定性?
- A.特征标准化处理← 正确答案
- B.距离矩阵预计算← 正确答案
- C.分数独立归一化← 正确答案
- D.固定单一 k 值
答案:ABC。特征标准化让距离有意义;预计算距离矩阵避免每轮重复计算近邻;不确定度和密度分别归一化后相乘,防止量纲失衡。固定单一 k 值恰恰不利于稳定性——k 应根据数据尺度调参,甚至可以做多种 k 的集成。
Q10. 数据类别严重不平衡时,直接使用密度加权采样最可能的倾向是什么?
- A.稠密多数类主导采样← 正确答案
- B.稀有类样本被过度采样
- C.噪声点不再被选中
- D.决策边界自动修正
答案:A。多数类所在区域天然密度更高,乘上不确定性后依然容易霸榜,导致采样越来越偏向多数类、稀有类被进一步忽略。若目标是类别均衡,需要额外叠加类别权重或按类内密度比较,不能指望密度加权自动修正失衡。