Skip to content
Guides2 min read

带误差棒的标签:把项目反应理论用到标注上

多数投票把标注者告诉你的东西丢掉了大半。项目反应理论给每个标签一个后验概率和一段置信区间,估计标注者能力和条目难度,还能找出坏掉的标注手册条目,既不需要黄金标签,也不需要 LLM。

Potato Team

多数投票把每位标注者都当成同样可靠,把每个条目都当成同样难,而且它报出来的是一个计数而不是一个概率。项目反应理论(IRT)把这两条假设都扔掉:它只从一致性的模式本身估计每位标注者的能力和每个条目的难度,然后把每个标签报成一个带置信区间的后验概率。它不需要黄金标签,也不需要 LLM。 在 Potato 里这就是心理测量学引擎,而且它随着标注进来实时运行。

三位标注者标了同一个条目。两个说 sarcastic,一个说 sincere。多数投票判它是 sarcastic,然后翻篇,而你的数据集记下这个结果时的置信度,跟三个人全都一致的条目一模一样。

这是在扔掉信息。那个持异议的人可能是你最可靠的标注者。这个条目也可能是所有人都觉得难的。这两件事在计数里都活不下来。

实时估计的标注者能力及其置信区间,让每个标签都有后验,而不只是一次光秃秃的投票带置信区间的标注者能力

什么是项目反应理论?

项目反应理论来自心理测量学,最初是为标准化考试打分而造的。它的洞察是,一场考试同时告诉你两件事:每个考生有多强,以及每道题有多难。你可以只凭作答模式把两者联合估计出来,因为它们互相约束。厉害的学生做错的题就是难题。能做对难题的学生就是厉害的学生。

标注的形状是一样的。标注者是考生,条目是题目,而没有人手里有标准答案。

Potato 拟合的是 GLAD 的多分类推广(Whitehill et al. 2009),它同时估计三样东西:

  • 每个条目的真实标签,形式是一个概率分布
  • 每位标注者的能力(θ),带标准误
  • 每个条目的难度,以及一个按条目给出的区分度诊断量

拟合是确定性的,在标注研究这个规模上只需毫秒级时间,所以它可以持续运行,而不必作为事后的批处理作业。

打开它

yaml
psychometrics:
  enabled: true
  schema: sarcasm
  confidence_threshold: 0.95
  min_annotators_per_item: 2

光是这样就能给你分析层。你的导出会从这样:

text
sarcastic    (2 of 3 votes)

变成这样:

text
sarcastic    p = 0.94 [0.88 – 0.97]

这个概率是模型后验,它权衡的是投的票,而不只是投了多少票。区间则是在能力估计上的一条敏感性带。

到了下游,这个数字很值。你可以用软标签训练,把评测集筛成置信度高于某个下限的条目,或者把低概率条目当成真正有歧义的样本,而不是悄悄被标错的样本。分歧不再是需要被平均掉的噪声,这一点值得和分歧是信号,不是噪声一起读。

标注者能力,如实呈现

能力是从一致性模式估计出来的。1.0 是新标注者的先验值,0 表示这位标注者的标签不携带任何信息,负值表示系统性地做错。

每个估计值都带标准误,而这件事比点估计本身更重要。只标了 12 条的标注者,误差线很宽,仪表板也就画得很宽。不要根据一根很宽的误差线做人事决定。 这些标准误是近似的(众数处的 Fisher 信息量),并且按其构造方式会略偏乐观。它们存在是为了拦住你过度解读一个数字,而不是为了给开除谁背书。

如果你只想在任意分类方案上快速看一眼能力,MACE 是它那位年长的表亲,至今仍是一个好工具。区别在于 MACE 是批量分析,而心理测量学坐在分配循环里,在研究进行当中就对它起作用。

标注手册问题检测器

这是让人意外的那部分。

除了难度,模型还估计区分度:在某个给定条目上,标注者能力与“同意共识”之间是否相关。正常情况下是相关的。能力强的标注者更常和最终答案一致,这大致就是“能力强”的意思。

当区分度强烈地转为,就说明有问题了。你最好的那批标注者在这个条目上系统性地不同意多数意见。最可能的解释不是他们突然变差了,而是指南对这种情形有歧义或者干脆写错了,而认真的标注者正是注意到这一点的人。

Potato 把这些条目集中列在“可能的标注手册问题”下面。它们通常是整个研究里价值最高的条目,因为每一条都是工具本身的缺陷,而不是某个人的缺陷。先把指南改好,再重新标。标准对齐房间是团队一起把它们过一遍的好地方。

把标注预算花在能买到东西的地方

固定冗余度,也就是“永远每条三位标注者”的规矩,在所有人都同意的条目和把团队劈成两半的条目上花的钱一样多。这是反的。

yaml
assignment_strategy: psychometric
num_annotators_per_item: 4
psychometrics:
  enabled: true
  confidence_threshold: 0.95
  cost_per_judgment: 0.08

这样一来,当标注者来要活儿时,Potato 会按这位具体标注者标注这个具体条目的期望信息增益,给剩余条目排序。后验已经越过 confidence_threshold 的条目干脆不再发出去。仪表板会统计你因此不必购买的判断数,如果设了 cost_per_judgment 还会折算成钱。

打开它之前有两点值得知道:

  • 冷启动。 在标签数够多之前,分配会退回随机。模型需要标注者之间有重叠才能把能力和难度分开,它也不会假装自己能。这个阶段仪表板上显示的是一个预热进度条。
  • 批量。 队列越短,排序就越新鲜。一次给每位标注者塞 200 个条目会稀释自适应的效果,因为排序是在那些标签里大部分还不存在的时候算出来的。

花钱之前先定好冗余度

每个项目都在猜的问题是:每个条目需要几位标注者。研究设计器不猜,而是用一次蒙特卡洛模拟来回答:

bash
python -m potato.psychometrics.design --items 500 --accuracy 0.75 \
    --classes 3 --target-ci 0.10 --cost 0.08
text
ann/item   alpha     95% interval   width  majority acc  judgments       cost
       2   0.392 [ 0.330,  0.439]   0.109         0.751       1000      80.00
       3   0.388 [ 0.338,  0.431]   0.093         0.864       1500     120.00  <- recommended

推荐值是让 Krippendorff's α 的 95% 区间仍窄于你目标的最便宜的冗余度。--accuracy 这个输入应该用一次小规模试标来测,而不是靠猜。

同样的计算也能在浏览器里跑,如果你不想为了回答这个问题而装任何东西的话。

它做不到什么

IRT 不是魔法。几条实话实说的限制:

  • 它建模的是单选的分类方案,radiolikert。多选不建模。
  • 它需要标注者之间有重叠。如果每个条目都由不同的人来标,就没有一致性结构可学,模型会告诉你它还在预热。
  • 只有一位标注者,或者到处都是完全一致的标签时,拟合按设计就是退化的。这是正确行为,不是 bug。

它给你的回报是:一个每个标签都自带不确定性的数据集,一支你了解的标注者队伍,以及一份你的标注手册在哪里坏掉的清单。

延伸阅读