想象你经营一家餐厅,想给招牌菜定一个“公正得分”。你请来七位风格迥异的美食评审:有人嗜甜,有人重辣,有人匆匆吃一口就打分,还有一位当天心情不好。七张评分卡摆在你面前,要怎么合成一个可信的最终分数?——这就是“多人标注聚合”要做的事。在 AI 世界,“菜品”是待标注的数据样本,“评审”是众包标注者,评分卡是每个人打出的标签。面对同一张图片有人说猫有人说狗,算法工程师必须设计规则,把参差不齐的人群意见提炼成一个可靠标签。最简单的办法是少数服从多数(多数投票法),进阶做法是按评审资历加权(加权投票法),再聪明一点,让算法在迭代中同时估计“谁靠谱”和“真相是什么”(Dawid-Skene 的 EM 算法),最后还要请“神秘嘉宾”复评检验聚合效果(效果评估)。这篇文章,就带你走完整个评审流程。

岗位关联

标注聚合是数据质检的最后一公里。掌握它,你就能在众包、医疗、自动驾驶等场景中把“多份毛坯标签”锤炼成高置信度的训练数据,这是数据科学家和算法工程师的硬核基本功。

目录
  1. 可视化演示
  2. 聚合问题的舞台:众包标注的评审团
  3. 多数投票法:少数服从多数
  4. 加权投票法:给行家更高权重
  5. 标注者可靠性:谁在认真打分
  6. Dawid-Skene:互相校准的评审团
  7. 算法效果评估:怎么知道审得准
  8. 工程实践要点:让评审团真正落地
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示多数投票、加权投票和Dawid-Skene EM迭代三种聚合方法,从多标注者结果中提取最可靠标签。

本节配有交互动效(进入视口后自动加载,约 3KB)。

多数投票法 各标注者独立标注同一样本 少数服从多数取最终标签 y=mode(y1,...,yn) 简单高效但未区分标注者质量

聚合问题的舞台:众包标注的评审团

把一道招牌菜交给七位评审,有的人按色泽打分,有的人按咸淡打分,还有人干脆凭心情。你盯着七张评分卡,想知道“这道菜到底值几分”——这就是聚合问题最朴素的模样。在众包标注里,“菜”是一个个待标注的样本,“评审”是能力、耐心、主观倾向各不相同的标注者,而“聚合算法”就是那个端坐在评审桌尽头、负责把七嘴八舌收拢成一个结论的人。

要让结论可计算,先把问题形式化:假设有 N 个样本、J 位标注者、K 个候选类别(比如“猫狗鸟”三选一),第 j 位标注者对第 i 个样本打出的标签记作 l_{ij}。由于标注者可能漏做,l_{ij} 允许缺失。所有标签拼在一起,就得到一张“评分总表”:

为什么同一个样本会有互相打架的标签?因为标注者三观不同:有人把“半杯水”标成正面,有人标成中立;有人对某个类别有刻板印象,有人干脆随机乱点。聚合算法的使命,就是从这张乱糟糟的总表里,为每个样本求出唯一的最终标签 ŷ_i——也就是替所有评审“吵出一个共识”。评审团的裁决质量,决定了这家数据餐厅的招牌菜能否端上桌,所以选对聚合规则,是众包标注项目成败的第一块多米诺骨牌。

L={ lij∣i∈{1,…,N}, j∈{1,…,J}, lij∈{1,…,K} }L = \{\, l_{ij} \mid i \in \{1,\dots,N\},\ j \in \{1,\dots,J\},\ l_{ij} \in \{1,\dots,K\} \,\}
  1. 样本下标i 代表数据集里第几个待标注样本,取值范围是 1 到 N,相当于“第几道菜”。
    i∈{1,…,N}i \in \{1,\dots,N\}
  2. 标注者下标j 代表第几位评审,取值范围是 1 到 J,相当于“第几位评审打分”。
    j∈{1,…,J}j \in \{1,\dots,J\}
  3. 标签取值l_{ij} 只能取 1 到 K 之间的整数,像“正面、中立、负面”三选一,不允许出现第 K+1 种答案。
    lij∈{1,…,K}l_{ij} \in \{1,\dots,K\}

多数投票法:少数服从多数

家庭聚餐点菜,最简单的方式是每人报一个菜,得票最多的上桌。“三个臭皮匠顶个诸葛亮”的直觉,催生了标注聚合最基础的方法——多数投票法。它的规则和点菜一样直白:每个样本统计 K 个类别各自收到多少票,票数最高的标签直接胜出。

多数投票之所以流行,是因为它零参数、零训练、好解释,在任何项目里都能三分钟落地。它骨子里依赖两个假设:第一,每一位标注者的能力水平差不多;第二,错误是随机独立的,不会出现“一大半人集体错成同一个方向”。在这两个假设成立时,投票人数越多,正确率越高——就像点菜时人越多,众口难调的风险越低。

投票公式写出来只有一行:

但多数投票有个致命的盲区:如果评审团里混进大量外行呢?假设五个人评审一道菜,三个人是走神的小学生,两个人是米其林主厨,小学生们齐刷刷给 1 分,主流结论就被带偏。这类系统性偏差——能力悬殊、类别难辨、恶意刷票——多数投票统统看不见,因为它只数人头、不看质量。点菜可以靠人多,评米其林不能只靠人多,于是我们想到:与其人人一票,不如给行家多一票。

y^i=arg⁡max⁡c∈{1,…,K}∑j=1J1[ lij=c ]\hat{y}_i = \arg\max_{c \in \{1,\dots,K\}} \sum_{j=1}^{J} \mathbb{1}[\, l_{ij} = c \,]
  1. 示性函数\mathbb{1}[l_{ij}=c] 表示“第 j 位标注者是否把样本 i 标成了类别 c”,是就记 1,不是就记 0,相当于评审投出的一张票。
    1[ lij=c ]∈{0,1}\mathbb{1}[\, l_{ij} = c \,] \in \{0, 1\}
  2. 求和\sum_{j=1}^{J} 把 J 位标注者的票全部累加,得到类别 c 的总票数,好比把所有评审给“这道菜算正面”的票数收拢在一起。
    ∑j=1J1[ lij=c ]\sum_{j=1}^{J} \mathbb{1}[\, l_{ij} = c \,]
  3. 取最大\arg\max_c 在 K 个类别的得票数里挑出最大的那个,输出它的类别编号,这就是最终标签 ŷ_i。
    y^i=arg⁡max⁡c\hat{y}_i = \arg\max_{c}

加权投票法:给行家更高权重

同样是打 10 分,米其林主厨的 10 分和一星食客的 10 分,含金量完全不同。加权投票法的灵感正源于此:给每位评审挂上一块“信任度胸牌”,权重越高,嗓门越大。在标注场景里,每一位标注者都分到一个权重 w_j,投票时先把每张票乘以权重再加总,最终票数最高的类别胜出。

权重从哪来?最常用的办法是“金标准测试题”:在正式任务里悄悄夹带几道已知答案的题目(比如已经把正确答案确认过的样张),标注者答对的比例就是他的初始权重。答对率高的人权重高,答错多的人权重低,这一来,专家的意见自然压过小学生。

计算公式与多数投票几乎同构,只在求和号里多乘了一个 w_j:

加权投票比多数投票聪明,但仍有两个短板。第一,权重是全局固定的——一个评审可能对“猫狗分类”很在行,对“车辆检测”却是外行,同一个权重覆盖不了所有样本。第二,标定权重依赖金标准题,假如测试题数量少、代表性差,标出来的权重本身就失真。更麻烦的是,真相和可靠性像两只互相咬尾的猫:不知道真实标签就没法判断谁靠谱,不知道谁靠谱就没法推断真相。要解开这个死结,得先认真刻画“评审的评分风格”。

y^i=arg⁡max⁡c∈{1,…,K}∑j=1Jwj⋅1[ lij=c ]\hat{y}_i = \arg\max_{c \in \{1,\dots,K\}} \sum_{j=1}^{J} w_j \cdot \mathbb{1}[\, l_{ij} = c \,]
  1. 权重w_j 是标注者 j 的可靠度分数,通常由金标准测试题的正确率标定,范围在 0 到 1 之间,相当于评审团里“话语权”的大小。
    wj∈[0,1]w_j \in [0, 1]
  2. 加权票数w_j \times \mathbb{1}[l_{ij}=c] 表示这位标注者投向类别 c 的票被放大或缩小,专家的票乘以大权重,新手的票乘以小权重。
    wj⋅1[ lij=c ]w_j \cdot \mathbb{1}[\, l_{ij} = c \,]
  3. 加权求和与取最大把所有加权后的票累加,再像多数投票一样用 \arg\max_c 选出总分最高的类别,得到最终标签。
    y^i=arg⁡max⁡c∑j=1Jwj⋅1[ lij=c ]\hat{y}_i = \arg\max_{c} \sum_{j=1}^{J} w_j \cdot \mathbb{1}[\, l_{ij} = c \,]

标注者可靠性:谁在认真打分

评审团里每个人都有独特的“评分风格”:有人严谨、有人宽松、有人对甜品苛刻,还有人永远打中庸分。要量化这种风格,光看一个总分不够,得看一张“评分习惯表”——在机器学习里,这张表叫做混淆矩阵。假设有三类标签,某位标注者的混淆矩阵就是一个 3×3 的方阵,第 r 行第 c 列记的是:当真实类别确实是 r 时,他有多少概率标成 c。

混淆矩阵的对角线是“标对的概率”,对角线越高,说明这位标注者越可靠;非对角线则暴露了他的习惯性误标方向——比如把“猫”错成“狗”的倾向远大于错成“鸟”。形式化地,将标注者的可靠性定义为条件概率:

有了混淆矩阵,就能回答“谁在认真打分”:对角线接近 1 的是严谨专家,对角线稀疏的是摸鱼选手。但问题紧接着出现——要算混淆矩阵,必须先知道每个样本的真实类别;而真实类别恰恰是我们要聚合出来的东西。这就好比想用评委的评分风格判断菜的品质,可判断风格又得先知道菜的品质。这个“鸡生蛋”的循环,正是 Dawid-Skene 算法登场的理由。

Mj(r,c)=Pr⁡( lij=c∣yi=r )M_j^{(r,c)} = \Pr(\, l_{ij} = c \mid y_i = r \,)
  1. 真实类别r 是样本 i 的真实类别,也就是我们最终想求的“正确答案”,在矩阵里代表行。
    r∈{1,…,K}r \in \{1,\dots,K\}
  2. 标注类别c 是这位标注者实际给出的标签,在矩阵里代表列,可能等于 r(标对),也可能不等于 r(标错)。
    c∈{1,…,K}c \in \{1,\dots,K\}
  3. 条件概率\Pr(l_{ij}=c \mid y_i=r) 表示“在真相是 r 的前提下,标注者 j 标成 c 的概率”,整行概率之和等于 1。
    ∑c=1KMj(r,c)=1\sum_{c=1}^{K} M_j^{(r,c)} = 1

Dawid-Skene:互相校准的评审团

美食节目里有个经典桥段:第一轮,大家凭直觉打分,主持人先求平均分,把它当作“假想的菜品真相”;接着,比较每位评审与平均分的偏差,偏差小的人被授予更高权重;再用新权重重新算平均分……如此反复,评审团越评越准。1979 年,统计学家 Dawid 和 Skene 把这种直觉形式化,提出了著名的Dawid-Skene 模型,它把标注过程想象成一个概率生成故事:每个样本先按类别先验 \pi_c 拥有一个隐藏的真实标签 y_i,然后每位标注者 j 根据他自己的混淆矩阵 \theta_j 把标签“吐”出来,成为我们观察到的 l_{ij}。

模型里有两组未知量:一是真实标签 y_i(我们真正想要的),二是标注者的混淆矩阵 \theta_j 与类别先验 \pi_c(刻画可靠性的参数)。两者互相依赖,直接求解是死路——于是算法采用了 EM 迭代:E 步先固定参数推标签,M 步再固定标签推参数,来回校准。E 步的公式是,在已知所有标注和当前参数时,样本 i 属于类别 c 的后验概率与先验及所有标注者的一致性成正比:

M 步再把角色互换:固定这些软标签,重新估计每个标注者的混淆矩阵。核心公式是,用所有样本的软标签做加权统计,得到“真实类别为 c 时,标注者 j 给出标签 l 的比例”:

E 步与 M 步交替进行,直到 \pi 和 \theta 的变化小于某个阈值,我们便认为算法收敛。收敛后取每个样本后验概率最大的类别作为最终标签。整个流程就像一场持续整晚的评审复盘:先猜测菜的真实水平,再修正评委的评分习惯,然后用修正后的习惯重新猜菜,循环往复。七嘴八舌的评审团,就此变成一台不断自我修正的“群体智慧处理器”。

qi(c)=Pr⁡(yi=c∣Li)∝πc×∏j=1Jθj(c, lij)q_i^{(c)} = \Pr(y_i = c \mid \boldsymbol{L}_i) \propto \pi_c \times \prod_{j=1}^{J} \theta_j^{(c,\, l_{ij})}
  1. 分子加权计数\sum_{i=1}^{N} q_i^{(c)} \cdot \mathbb{1}[l_{ij}=l] 把每个样本对“真实类别为 c”的信心当作权重,只统计那些标注者 j 恰好标成 l 的样本,得到“疑似标成 l”的期望次数。
    ∑i=1Nqi(c)⋅1[ lij=l ]\sum_{i=1}^{N} q_i^{(c)} \cdot \mathbb{1}[\, l_{ij} = l \,]
  2. 分母归一化\sum_{i=1}^{N} q_i^{(c)} 是“真实类别疑似为 c”的所有样本总权重,相当于把分子换算成比例,保证矩阵每行和为 1。
    ∑i=1Nqi(c)\sum_{i=1}^{N} q_i^{(c)}
  3. 更新可靠性两者相除得到的 \theta_j^{(c,l)},就是下一轮用来评价该标注者可靠性的新参数——它比上一轮更准确,因为它吸收了最新估计的真相。
    θj(c, l)←加权次数总权重\theta_j^{(c,\,l)} \leftarrow \dfrac{\text{加权次数}}{\text{总权重}}

算法效果评估:怎么知道审得准

评审团吹得再天花乱坠,终究得请一位“神秘嘉宾”来复评,看看团队结论和资深评审差距多大。聚合算法也一样,上线前必须接受效果评估。最直接的办法是准备一批金标准样本——真实标签已知的数据(比如人工专家反复确认过的样张),把聚合结果和它对比,算出准确率:

准确率直观易懂,但真实业务里金标准往往稀缺——如果每个样本都知道标准答案,何必还要众包标注?这时可以退而求其次,用“自洽性信号”评估聚合质量:比如计算标注者两两之间的一致性系数(Cohen's Kappa),一致性越高说明评审们越有共识;或者观察 EM 收敛后样本后验熵是否集中——熵越低,说明算法对每个样本的结论越笃定;再或者看混淆矩阵的平均对角线条目,若整体偏低,就要警惕标注任务本身是否难到“大家都靠猜”。

评估环节还有个隐藏价值:它能指出“哪些样本还值得复标”。当某个样本的软标签熵很高(正反意见五五开)时,说明评审团分歧严重,应该把它挑出来送资深专家仲裁,或者丢回任务池追加标注。就像餐厅里顾客评价两极分化的菜,最值得主厨亲自尝一口。给评审团“考试”的分数,反过来指导我们换人、补标、换算法——这才是评估真正的意义。

Acc=1N∑i=1N1[ y^i=yi∗ ]\text{Acc} = \dfrac{1}{N}\sum_{i=1}^{N} \mathbb{1}[\, \hat{y}_i = y_i^* \,]
  1. 正确判定\mathbb{1}[\hat{y}_i = y_i^*] 表示第 i 个样本的聚合结果是否与金标准一致,一致记 1,否则记 0。
    1[ y^i=yi∗ ]∈{0,1}\mathbb{1}[\, \hat{y}_i = y_i^* \,] \in \{0, 1\}
  2. 求平均\frac{1}{N}\sum_{i=1}^{N} 把 N 个样本的正确判定累加后除以 N,得到“答对的比例”,即准确率。
    1N∑i=1N…\frac{1}{N}\sum_{i=1}^{N} \dots

工程实践要点:让评审团真正落地

把评审团从演播厅搬进真实餐厅,麻烦事接踵而至:预算有限请不起那么多专家、评审迟到导致标注缺失、大众评委水平参差——工程上怎么应对?第一个问题是冷启动:新项目上线时没有任何金标准,也没跑过一轮 EM,该拿什么初始化?最稳妥的答案是用多数投票先跑一版伪标签,作为 EM 的“种子”。在算法里,这等价于先给每个类别一个先验的平滑计数 \alpha_c,再进行一轮带先验的投票:

第二个问题是小样本退化。当样本量很少而标注者很多时,DS 要估计的参数数量(J×K×K 个混淆矩阵元素)远超数据量,EM 极易过拟合成乱猜的极端解。工程上的对策是给混淆矩阵加平滑先验,或者直接先用多数投票、等样本攒够了再切到 DS。第三个问题是缺失标注:好在 DS 天然支持缺失值,E 步的连乘会跳过缺失项,不会因为某位评审没打分而报错。实践中还应把“人机协同”补充进来:AI 先粗标一遍,标注者只负责修正机器没把握的样本,聚合算法则持续给每位标注者做能力画像,及时淘汰恶意刷量的人。

从冷启动的“先跑起来”、到迭代中的“慢慢校准”、再到置信度检查的“把好最后一道关”,工程落地的核心哲学与美食节目的评审流程如出一辙——不要指望第一轮就完美,而是让算法在迭代中逼近真理。评审团不是一次定稿的,聚合算法也不是一锤子买卖的。

y^i=arg⁡max⁡c∈{1,…,K}(αc+∑j=1J1[ lij=c ])\hat{y}_i = \arg\max_{c \in \{1,\dots,K\}} \left( \alpha_c + \sum_{j=1}^{J} \mathbb{1}[\, l_{ij} = c \,] \right)
  1. 先验伪计数\alpha_c 是类别 c 的初始票数,可以来自业务经验(比如历史上正面样本占六成),用来避免某些类别因为冷启动而零票落选。
    αc≥0\alpha_c \ge 0
  2. 实际票数\sum_{j=1}^{J} \mathbb{1}[l_{ij}=c] 是当前标注者投给类别 c 的真实票数,两者相加得到“平滑后的总票数”。
    αc+∑j=1J1[ lij=c ]\alpha_c + \sum_{j=1}^{J} \mathbb{1}[\, l_{ij} = c \,]
  3. 取最大\arg\max_c 选出平滑后票数最高的类别,作为初始化标签,喂给后续的 DS 迭代。
    y^i=arg⁡max⁡c(⋯ )\hat{y}_i = \arg\max_{c} \left( \cdots \right)

AI 应用场景

医疗影像的多医生读片聚合

阶段:数据准备与质量控制

解决的问题:传统方式下,每个病例由多名医生独立读片,遇到分歧就开讨论会仲裁,一场会动辄一两个小时,成本极高且标准难以统一。用 Dawid-Skene 模型把各医生的诊断意见聚合后,系统能自动给出高置信度的最终标签,并标出分歧严重的病例,只有这些“疑难杂症”才需要送资深专家复核。

具体案例:某医疗 AI 团队积累肺结节 CT 影像标注,5 名医生对同一张片子分别给出“良性/恶性/待查”的判断。用 DS 算法 EM 迭代 20 轮后,自动识别出一位对早期结节存在系统误判的医生,并在后续项目中降低其权重,聚合结果与三甲专家复评的一致率从 82% 提升到 94%。

众包平台的数据质量控制

阶段:数据质量控制与验收

解决的问题:众包平台(如亚马逊 MTurk 或国内微众包)每天流转海量任务,传统抽检只能覆盖极小比例,大量低质量标签混入数据集。平台把每个任务分配给 3~5 个众包工人,用加权投票或 DS 聚合出最终标签,并实时更新每个工人的可靠性矩阵,对持续低分者自动降权或拉黑。

具体案例:一个电商评论情感分类项目,2 万条评论由 4 个工人分别标注。引入 DS 后,系统挑出 367 个置信度极低的“争议评论”送回人工仲裁,最终模型的训练准确率比纯多数投票提升了 11 个百分点,质检人力反而下降了四成。

自动驾驶感知标注的多人校验

阶段:数据标注流水线质检

解决的问题:自动驾驶的每一帧影像都需要多人框选车辆、行人、路标,传统做法是人工质检逐帧复核,效率极低。聚合算法把多个标注员的结果(可能框位不一致、类别有分歧)合并成最终物体框,同时给标注员持续建立“能力画像”,让训练数据既干净又有据可查。

具体案例:某自动驾驶公司为 50 万帧雨夜场景打框,每个任务由 3 个标注员完成。使用加权投票 + DS 的混合方案后,行人检测框的 IoU 一致性提升了 18%,且质检工作量从逐帧审核降为只检查低置信度帧,整体标注成本下降约三分之一。

Python 演示

python73 行
import numpy as np class DawidSkene:    def __init__(self, n_classes, max_iter=50, tol=1e-3):        self.n_classes = n_classes        self.max_iter = max_iter        self.tol = tol        self.pi = None        self.theta = None     def fit(self, labels):        n_items, n_workers = labels.shape        n_classes = self.n_classes         pi = np.full(n_classes, 1.0 / n_classes)        theta = np.full((n_workers, n_classes, n_classes), 0.2)        for j in range(n_workers):            np.fill_diagonal(theta[j], 0.8)            theta[j] /= theta[j].sum(axis=1, keepdims=True)         for it in range(self.max_iter):            post = self._e_step(labels, pi, theta, n_workers)            pi_new, theta_new = self._m_step(labels, post, n_workers, n_classes)            if np.max(np.abs(pi_new - pi)) < self.tol and np.max(np.abs(theta_new - theta)) < self.tol:                break            pi, theta = pi_new, theta_new         self.pi, self.theta = pi, theta        return post, np.argmax(post, axis=1)     def _e_step(self, labels, pi, theta, n_workers):        n_items = labels.shape[0]        n_classes = self.n_classes        post = np.zeros((n_items, n_classes))        for i in range(n_items):            for c in range(n_classes):                score = np.log(pi[c])                for j, lab in enumerate(labels[i]):                    if lab >= 0:                        score += np.log(theta[j, c, lab])                post[i, c] = np.exp(score)            post[i] = np.maximum(post[i], 1e-12)            post[i] /= post[i].sum()        return post     def _m_step(self, labels, post, n_workers, n_classes):        pi = post.mean(axis=0)        theta = np.zeros((n_workers, n_classes, n_classes))        for j in range(n_workers):            for c in range(n_classes):                denom = post[:, c].sum()                if denom < 1e-12:                    theta[j, c, c] = 1.0                    continue                for lab in range(n_classes):                    mask = labels[:, j] == lab                    theta[j, c, lab] = post[mask, c].sum() / denom        return pi, theta  if __name__ == '__main__':    labels = np.array([        [0, 0, 1],        [1, 1, 1],        [2, 2, 1],        [0, 0, 0],        [1, 1, 2],    ])    model = DawidSkene(n_classes=3)    post, pred = model.fit(labels)    print('聚合标签:', pred)    print('标注者0的混淆矩阵:')    print(np.round(model.theta[0], 3))
目的:用不足 100 行实现 Dawid-Skene 的 EM 迭代,输入多位标注者的标签矩阵(-1 表示缺失),输出每个样本的聚合标签与每位标注者的混淆矩阵,直观演示“先猜真相、再评人、再修正真相”的完整流程。
  1. theta = np.full((n_workers, n_classes, n_classes), 0.2)初始化所有标注者的混淆矩阵,每个元素先给一个均匀小值,对角线上赋 0.8 表示“初始默认比较靠谱”,随后按行归一化。
  2. score += np.log(theta[j, c, lab])E 步核心:把“真实类别为 c 时,该标注者给出 lab 标签”的对数概率累加,若标注缺失(lab = -1)则跳过,天然支持缺失数据。
  3. post[i] /= post[i].sum()归一化得到软标签 q_i^{(c)},也就是样本属于每个类别的后验概率,它不像多数投票那样只给一个硬答案,而是保留不确定性。
  4. theta[j, c, lab] = post[mask, c].sum() / denomM 步核心:用全部样本的软标签作为权重,重新估计标注者 j 在真实类别 c 下给出标签 lab 的比例,更新混淆矩阵。
  5. if np.max(np.abs(pi_new - pi)) < self.tol收敛判据:当类别先验和混淆矩阵的最新估计与上一轮相比变化极小,说明 EM 已进入稳定区,停止迭代。

常见误区

误区所有标注者的票数一下,选最多的标签不就行了吗?搞什么复杂的概率模型?多数投票简单、零成本、效果也不差,肯定是工程首选。

正解多数投票隐含“大家水平接近、错误随机且独立”的假设。回到美食评审团的例子:三位走神的小学生加两位米其林主厨,多数票被小学生带偏。当标注者能力悬殊、存在系统性偏差或少数专家被大量新手淹没时,加权投票和 Dawid-Skene 能通过可靠性估计显著纠正偏差。

为何常见:多数投票直观、零参数、好解释,很多入门教程只讲它,给人一种“够用”的错觉;而且在小规模、高质量标注者的小项目里,它确实往往表现不错,容易让人以偏概全。

误区众包平台人多力量大,任务多分几个人,把标注者数量凑上去,投票结果自然越来越可靠。

正解数量不能替代质量。混入大量低质量标注者,多数投票会被噪声淹没,DS 虽然能通过混淆矩阵识别并降权,但标注者过多也会放大参数估计的方差。正确做法是监控每位标注者的可靠性曲线,持续淘汰异常者,而非盲目堆人数。

为何常见:“三个臭皮匠顶个诸葛亮”的直觉深入人心,众包平台也常按“每人做几份”来设计流程,忽略了数据质量的高度异质性——不是每个“皮匠”都真有诸葛亮。

误区E 步是估计标注者可靠性的,M 步是更新真实标签的——“E“代表评估人,”M”代表改标签。

正解正好相反。E 步固定当前可靠性参数,推断每个样本的真实标签后验(软标签);M 步固定这些软标签,重新估计混淆矩阵和类别先验。用评审团比喻:E 步是“根据评委的评分风格猜菜的真实水平”,M 步是“看了最新猜测再校准每位评委的风格”。

为何常见:EM 算法本身就是“两步交替”的绕口令,初学者死记缩写含义、背反方向十分常见,尤其容易把“更新标签”直觉上归给 M 步。

误区DS 是更高级的算法,只要是聚合任务,无脑上 DS 就对了,多数投票这种简单基线可以直接淘汰。

正解DS 要估计的参数很多(每位标注者一个 K×K 矩阵),样本量小时容易过拟合甚至收敛到退化解。好比评审团只有两道菜、七位评委,硬要拟合出每个评委的完整风格,纯属瞎猜。此时带平滑的多数投票反而更稳,实践中通常先用多数投票打底,数据量充足后再切 DS。

为何常见:看到“概率模型 + EM”就默认它一定碾压简单基线,忽略了模型复杂度与数据量必须匹配这一基本统计原则。

面试题

Q1. 多数投票法最核心的隐含假设是什么?

单选题 · easy

  • A.标注者彼此独立且水平相近← 正确答案
  • B.标注者人数必须超过十人
  • C.每个样本须有九个标注
  • D.标注标签一定是二分类

答案:A。多数投票把每个标注者的票等权相加,默认大家能力相近、错误相互独立且随机。好比七个人点菜,如果六个人口味相似,唯一的川菜爱好者必输——多数票反映的是主流偏好而非绝对真相。B、C、D 都是毫无根据的附加条件,不是算法的隐含假设。

Q2. 加权投票法中的权重 w_j 主要代表什么?

单选题 · easy

  • A.标注者回答问题的速度
  • B.标注者历史标注的正确率← 正确答案
  • C.标注者任务完成的报酬
  • D.标注者所在团队的人数

答案:B。权重 w_j 用历史表现标定,代表标注者比“平均人”可靠多少,相当于评审团里米其林主厨的评分比路人更有分量。A 反映效率、C 反映成本、D 反映规模,均与标注质量无关,不能作为投票权重。

Q3. 混淆矩阵对角线上的数值反映了什么?

单选题 · easy

  • A.标注者把真实类别标对的比例← 正确答案
  • B.标注者把真实类别标错的数量
  • C.所有样本类别比例的分布
  • D.标注者每次标注的耗时时长

答案:A。混淆矩阵第 r 行第 c 列表示真实类别为 r 时被标成 c 的概率,对角线即“标对概率”,越高越可靠,非对角线则揭示习惯性误标方向。B 只统计数量未归一化,C 是类别先验的范畴,D 是时间开销,均与可靠性无关。

Q4. Dawid-Skene 算法中 E 步的作用是什么?

单选题 · mid

  • A.估计样本的真实标签后验概率← 正确答案
  • B.估计标注者的混淆矩阵参数
  • C.估计每个类别出现的先验概率
  • D.直接输出聚合后的硬标签结果

答案:A。E 步固定混淆矩阵和先验,用贝叶斯公式计算每个样本属于各类的后验概率(软标签)——相当于先认定评委的评分风格,再反推每道菜的“真实水平”。B、C 是 M 步的职责,D 是最终输出,都不属于 E 步。

Q5. Dawid-Skene 算法中 M 步更新什么?

单选题 · mid

  • A.标注者混淆矩阵与类别先验← 正确答案
  • B.每个样本的真实隐藏标签变量
  • C.输入数据的划分比例和批次数量
  • D.模型学习率与训练轮次的上限

答案:A。M 步用 E 步给出的后验概率作为权重,重新估计每位标注者的混淆矩阵与类别先验——好比看了菜品最新推断,回头修正每位评委的评分偏差。B 是 E 步的任务,C、D 属于深度学习的训练细节,与 DS 模型无关。

Q6. 下列哪些情况会让多数投票失效?

多选题 · mid

  • A.多数标注者存在系统性偏差← 正确答案
  • B.标注者个体能力差异悬殊← 正确答案
  • C.标注者完全独立且水平接近
  • D.少数专家反复被多数新手淹没← 正确答案

答案:ABD。多数投票要成立,前提是多数人正确且错误随机。若多数标注者有一致的偏见、能力强弱悬殊、或少数专家被大量新手淹没,多数票就会被带偏——就像小学生集体给 1 分,主厨的 9 分被淹没。C 恰好是前提成立的条件,所以是正确的反例,不应选。

Q7. Dawid-Skene 模型需要估计的参数包含哪些?

多选题 · mid

  • A.标注者可靠性混淆矩阵← 正确答案
  • B.各类别先验概率分布← 正确答案
  • C.样本真实标签后验分布← 正确答案
  • D.梯度下降的学习率参数

答案:ABC。DS 把标注过程建模为“真实标签 → 标注者按混淆矩阵生成标注”,因此需要估计混淆矩阵(可靠性)和类别先验;真实标签后验是 E 步计算的辅助量,也是参数估计的中介。D 是神经网络训练的超参数,与 DS 的概率模型无关。

Q8. 样本量极小而标注者众多时,DS 算法最可能遇到什么问题?

单选题 · hard

  • A.混淆矩阵估计过拟合失真← 正确答案
  • B.少数投票法比多数投票法更耗时
  • C.加权权重的取值会退化成为负数
  • D.标注者可靠性会自动变得完全相同

答案:A。样本量小、参数多时,混淆矩阵每个元素的估计方差很大,EM 容易过拟合训练数据,甚至收敛到极端解。此时多数投票虽简单但方差小、更稳健。B 把时间开销与统计性能混为一谈,C 的权重本就允许归一化后非负,D 并非 DS 的典型退化形态。

Q9. 在没有金标准标签的情况下,可评估聚合效果的手段有哪些?

多选题 · hard

  • A.标注者两两一致性统计量← 正确答案
  • B.收敛后后验熵的集中程度← 正确答案
  • C.依赖人工重新复检全部样本← 正确答案
  • D.直接比较所有原始标注文件

答案:ABC。无金标准时可算标注者两两一致率(Cohen's Kappa)、检查 EM 收敛后后验熵是否集中,也能用人工复检小样本做抽查评估。D 只是把原始标注文件摆在一起,并没有计算任何反映聚合质量的指标,信息量为零。

Q10. 冷启动阶段没有任何金标准样本时,以下哪种初始化最稳妥?

单选题 · extreme

  • A.用多数投票产生的标签初始化 DS 的 E 步← 正确答案
  • B.随机猜测真实标签并固定不参与迭代
  • C.把所有标注者可靠性统一设为零值
  • D.只保留第一位标注者的结果作为初始化

答案:A。冷启动没有金标准,最稳妥的是先用多数投票产生伪标签,作为 E 步的起点,让 DS 平滑启动——相当于先让评审团凭直觉投一轮,再进入互相校准。B 随机初始化方差大且固定标签违背 EM 精神,C 把可靠性设零会让后验失去区分度,D 只取一人完全丢弃了群体信息。