Skip to content

ラベリングエンジンのコントラクト

ラベリングエンジンが人手ラベルに対して検定する6種類のコントラクト。選択的リスクやPPI区間から代替アノテーター検定まで、それぞれの内容と、どんな場合に満たされないかを説明します。

コントラクトとは、完成したラベルについての主張で、ラベリングエンジンがランダムサンプル上の人手ラベルに対して検定します。各コントラクトは1つのアノテーションスキーマ(schema)を指定し、主張が成り立つ確率であるconfidence(デフォルトは0.9)を持ちます。したがって、confidenceが0.9なら、満たされたコントラクトが誤っている可能性が10%残ります。

6つの種類はそれぞれ異なる主張をし、適した研究も異なります。

種類主張用途
selective_risk受理した機械ラベルのうち、誤っているものは最大でerrorの割合各ラベルがそのまま使える必要のあるデータセットや学習セット
ppi各ラベルの出現率(または平均スコア)についての区間で、機械の品質にかかわらず有効「投稿の12%が有害 [10.5, 13.6]」のような割合の報告
no_worse_than_human機械が少なくとも人と同程度に人と一致するアノテーターやLLM判定者の置き換え
budget_first人手ラベルの予算で何が得られるか支出前の計画
distributional機械のラベル分布が人の判断の分かれ方に近い意見の不一致そのものがデータである主観的なタスク
threshold_legacyなし。固定の信頼度を超えるものを受理する変換された設定でのみ使用

これらのコントラクトはいずれも、ラベルに誤りがないとは述べていません。selective_riskは受理したラベルの誤り率に上限を設けるものであり、機械を検定するどのコントラクトも、サンプルにラベルを付けた人々を基準に機械を測定します。

コントラクトのステータス

すべてのコントラクトは5つのステータスのいずれかを持ち、管理ページ、potato label status、証明書に表示されます。

ステータス意味
met現在のカスケードで検定に合格した。
insufficient人手ラベルがまだ足りない。あといくつ必要かの見積もりが付く。その見積もりがコーパスに残っているサンプル可能な数を上回る場合、ステータスはこのコーパスでは目標に到達できないことを示す。
infeasibleラベルは十分だが、合格する受理ルールがない。たとえば、機械の信頼度が正しい答えと誤った答えを分けられていない場合。
violated受理したラベルの監査で、誤り率が目標を上回っている(デフォルトで有効なfeatures.driftを使う場合)。
stale前回の検定以降に、ソース、プロンプト、スキーマのいずれかが変わった。受理されていたラベルはpending_recertで待機する。

機械ラベルが受理されるのは、そのスキーマ上のすべてのselective_riskおよびthreshold_legacyコントラクトが満たされ、かつそのラベルを受理する場合だけです。コントラクトはラベルが満たすべき条件を述べるものなので、満たされていないコントラクトは読み飛ばされるのではなく受理を妨げます。ステータス、管理ページ、証明書には、満たされていないコントラクトの名前が示されます。有効にできるルールがなく、これ以上サンプルを抽出する予定もない場合(コントラクトが実行不能である、キャリブレーションのサンプルが完了している、あるいは何も見積もれなかった場合)、まだラベルのない項目はbudgets.human_labelsの範囲内で人に回ります。

devとcertの分割

エンジンは、ルールを選ぶラベルと、それを検定するラベルを分けて保持します。キャリブレーションの依頼は、包含確率を記録したうえでランダムに抽出され、常にブラインドで、それぞれがランダムに2つの分割のどちらかに入ります。

  • dev(humans.dev_fraction、デフォルトは半分)は、較正器の当てはめとしきい値の選択に使います。
  • certは選んだルールを検定するためのもので、それ以外の用途では読まれません。

ルック

コントラクトを新たに検定するたびに、より厳しい水準で実行されるため、ラベルが届くたびに検定し直しても信頼度は水増しされません。ルックkには誤りの予算のうち(1 - confidence) * 6 / (pi^2 k^2)が割り当てられます。これはありうるすべてのルックにわたって合計すると予算全体になり、最初のルックにはその61%が割り当てられます。

  • ルックはコントラクトごとに数えられます。 そのコントラクトが検定されたすべてのカスケードを通じて数え、名前を変えたコントラクトは古いidのルックを引き継ぎます。合格するまでプロンプトやモデルを試すと、そのたびにルックを1つ消費します。以前のカスケードに戻すことも新しいルックになり、以前の結果は復元されません。
  • 同じデータの再検定は新しいルックになりません。 同じcertラベル、同じ予測、devで選んだ同じルールであれば、保存済みの結果が返ります。たとえばあるクラスにcertラベルがなく実行できなかった検定は、何も消費しません。
  • potato label certifyは、新しいcertラベルと新しい予測をまとめて検定します。 REST、MCP、SDKの同等の機能も同じです。devラベルだけが変わった場合は、devが別のルールを選ぶようになったという注記とともに保存済みの結果を返し、--retestを付けるとそのルールを次のルックで検定します。
  • プランナーはラベルが届くにつれて自動的に証明を行います。 満たされたselective_riskコントラクトはそのカスケードでは満たされたままで、監査がそれを見守ります。満たされていないコントラクトは、ラベルが4分の1増え、かつ10以上増えた時点で再び検定されます。ppi、distributional、no_worse_than_humanの結果は合否の検定ではなく推定値なので、プランナーは同じ節目で再推定し、キャリブレーションのサンプルが完了したときにもう一度推定します。
  • 編集されたcertラベルは新しいデータです。 アノテーターが答えを変更しても、その編集にかかるコストは新しいラベル1つ分を超えません。すでに検定した状態に編集で戻した場合は、その検定の結果が戻ります。編集後に保存済みの結果のどの検定でも誤りが増えていなければ、結果とそのルックはそのまま有効です。そうでない場合、プランナーは最初の編集からラベルが4分の1増えるまで待つので、一連の修正は1回の検定にまとまります。その間、受理されたラベルは受理されたままで、コントラクトに注記が付きます。これ以上ラベルが来ない場合はすぐに検定し、明示的に証明を実行すると次のルックで検定します。

機械の答えを見た後で人が付けたラベル(検証の依頼)や、エンジンの依頼以外で付けられたラベルは、証明にも推定にも一切使われません。蒸留モデルの学習には使えます。

selective_risk

selective_riskは、受理した機械ラベルのうち誤っているものの割合に上限を設けます。errorキーは受理したラベルの中で許容する最大の誤り率で、必須です。

yaml
- id: accuracy
  kind: selective_risk
  schema: sentiment
  error: 0.05          # required: largest tolerated error among accepted labels
  confidence: 0.9
  per_class: true      # test each predicted class separately
  tolerance: 0.5       # graded families only: loss at or below this counts as correct

ルールはカスケードの段ごとの信頼度しきい値で、per_classを指定すると予測クラスごとのしきい値になります。最後の段以外では、しきい値をdevで選び、certで1回検定します。最後の段では、devで選んだしきい値から、より緩いしきい値へと順に試し、それぞれを検定して、最初に不合格になったところで止めます。この手順は固定順序のLearn-then-Test(Angelopoulos et al., 2025)です。各検定は、受理したラベルの誤りがerrorを上回るかどうかについての片側二項検定で、水準は段とクラスに分割されます。不合格になった段は何も受理せず、その項目は人に回ります。

何を「正しい」とみなすかはスキーマの系統によって異なります。各系統の損失は表のとおりで、損失がtolerance以下であればラベルは正しいとみなされます。

スキーマの系統損失デフォルトのtolerance
N択の単一選択(radio、select)同じラベルなら00
順序(likert)尺度上の距離 / (段階数 - 1)0
連続値(slider、number)距離 / (最大値 - 最小値)0.05
マルチラベル(multiselect)1 - Jaccard重複度0
画像領域(image_annotation)1 - 対応付けた図形の平均IoU0.5
音声・動画のセグメント、temporal_grounding、tiered_annotation1 - 平均時間IoU0.5
3Dオブジェクト(spatial_annotation)1 - 平均3D IoU0.5
エージェントトレース(process_reward、trajectory_eval、...)双方がラベルを付けたステップのうち、ラベルが異なる割合0

領域、セグメント、3Dオブジェクト、トレースの損失は、/admin/iaaの一致度レポートが使うものと同じです。そのため、機械と人は、2人の人同士と同じ方法でスコア付けされます。自由記述とペアワイズのスキーマにはまだ系統がなく、証明書では未対応として一覧に示されます。

この検定では、検定対象となるcert項目の各グループが一様なサンプルである必要があります。項目が異なる確率で抽出されたグループは検定されず、結果にその名前が示されます。

最後の段では、devの誤りが目標の半分以下で、かつ最初の検定に合格するのに十分なcertラベルが見込まれる場合にのみ、devでしきい値を選びます。あといくつラベルが必要かの見積もりでは、そのようにして選べるしきい値だけを数えます。見積もりが求めた数のラベルがすでにcertにあるのに検定が不合格の場合、次の見積もりではdevだけの誤り率ではなく、devとcertを合わせた誤り率を使います。devの最小の誤りが目標を下回るものの目標の半分を上回る場合は、何も検定せず、何も見積もりません。結果にはその旨と誤りの値が示されます。ラベルを増やしても、誤りが実際にはもっと低いと判明した場合にしか役に立たないためです。

metrics.accepted_by_tierは、キャリブレーション項目を含む母集団全体に対するルールのカバレッジであり、実際に提供された機械ラベルの数ではありません。そちらは証明書の「Machine labels accepted, by source」の行が数えます。

トレースの損失は双方がラベルを付けたステップだけを比較するので、一部のステップにだけ印を付けた人は、そのステップについてだけ比較されます。誰もラベルを付けていないステップは確認されず、ステップ0だけにラベルを付けてそこで判定者と一致した人は、トレース全体のラベルについて一致したとみなされます。すべてのステップを確認する必要がある場合は、すべてのステップにラベルを付けるよう人に依頼してください。

ppi

ppiは、各ラベルの出現率、または平均スコアについて、機械の誤りを補正した区間を報告します。

yaml
- id: prevalence
  kind: ppi
  schema: sentiment
  estimand: prevalence   # or mean, for numeric scores
  by: language           # optional: an interval per value of this item field
  confidence: 0.95
  max_width: 0.05        # optional: met once every interval is at most this wide

予測駆動型推論(prediction-powered inference)(Angelopoulos et al., 2023)は、人手でラベルを付けたサンプル上での機械の誤りを使って、機械の推定値を補正します。区間は機械の品質にかかわらず有効です。良い機械なら人だけの場合よりも区間が狭くなり、悪い機械でも区間が広がることはありません。包含確率が等しい場合、エンジンは重みを調整したPPI++を使い、等しくない場合(層化抽出や不確実性に基づく抽出)はHorvitz-Thompson差分推定量を使います。使われる機械ラベルは、カスケードが提供するはずのものです。byフィールドは、項目の登録時に項目からコピーされます。max_widthがない場合、報告に足るラベルが集まった時点でコントラクトは満たされます。

no_worse_than_human

no_worse_than_humanは、機械が人と一致する頻度が、少なくとも1人の人が他の人と一致する頻度と同程度かどうかを問います。

yaml
- id: replaces-a-person
  kind: no_worse_than_human
  schema: verdict
  epsilon: 0.1

このコントラクトは代替アノテーター検定(alternative annotator test)(Calderon et al., 2025)を実行します。1人ずつ順に除外し、機械が残りの人々と一致する頻度が、除外した人が残りの人々と一致する頻度と、epsilonの範囲内で少なくとも同程度かどうかを検定します。人々全体での偽発見率を制御したうえで、機械が少なくとも半数の人に勝てば合格です。

この検定には、複数の人がラベルを付けた項目が必要です。humans.overlap(サンプルのうち複数回ラベルを付ける割合)とhumans.overlap_k(項目あたりの人数、3以上)を設定してください。検定には、それぞれ30項目を担当したアノテーターが少なくとも3人必要です。それがそろうまで、コントラクトはinsufficientのままです。固定の正解率の目標がアノテーターのノイズばかりを測ることになりそうな場合に、このコントラクトを使ってください。注意深い2人の一致率が85%なら、どのラベル付け手についても95%「正しい」と示すことはできません。

budget_first

budget_firstは、人手ラベルの予算を使う前に、その予算で何が得られるかを見積もります。

yaml
- id: plan
  kind: budget_first
  schema: sentiment
  human_labels: 500      # or human_usd, priced at the crowd reward

見積もりは、それまでに集まったdevラベルから求めます。グリッド上の各誤り目標について、この予算で機械がラベルを付けると証明できるコーパスの割合と、各出現率の区間の幅を示します。見積もりに足るdevラベルが集まった時点で、コントラクトはmetになります。このコントラクトはラベルについて何も約束しません。それを約束するのは、ラベルがそろった後のselective_riskとppiです。

distributional

distributionalは、データに含めるべき理由で人の意見が分かれる主観的なタスクについて、機械のラベル分布を人の判断の分かれ方と比較します。

yaml
- id: disagreement
  kind: distributional
  schema: offensiveness
  max_distance: 0.15     # optional
  groups_by: age_band    # optional: a prestudy question whose answer groups the annotators

複数の人(humans.distribution_k、デフォルトは5人)がラベルを付けた各項目には、人のラベル分布があります。コントラクトは、機械の分布と人の分布の間の平均Jensen-Shannon距離を、ブートストラップ区間とともに報告します。また、各項目で人々をランダムに2つに分けたときの両者の間の同じ距離を、ノイズの上限として報告します。人同士の距離よりも人に近い機械は、データが許す限り近いことになります。

機械の分布は、ソースが確率を与える場合(意思決定モデル、k_sample、logprob)はその確率、そうでない場合はラベルをone-hotベクトルにしたものです。コントラクトが満たされるのは、区間の上端がmax_distance以下のとき、またはmax_distanceがない場合は3人以上がラベルを付けた項目が20個そろったときです。区間の下端がmax_distanceを上回る場合はinfeasibleになります。項目を増やしても、大きすぎる距離のまわりで区間が狭まるだけだからです。

groups_byを指定すると、同じ数値がアノテーターのグループごとに報告されます。ある項目での各グループの分布は、指定した事前調査の質問への回答から読み取った、そのグループの人だけから作られます。誰もその質問に回答していない場合、コントラクトはその旨を示します。

threshold_legacy

threshold_legacyは、固定の信頼度を超える機械ラベルを受理し、統計的な検定は一切行いません。

yaml
- id: old-rule
  kind: threshold_legacy
  schema: sentiment
  threshold: 0.8

potato label migrate-configは、icl_labelingに対して、以前のconfidence_thresholdの値でこのコントラクトを書き出します。そのため、変換された設定は以前と同じように動作します。手で書くこともできます。証明書はこれらのラベルを未証明として示し、キャリブレーションのラベルで測定した誤りを報告します。エクスポートではこれらのラベルにaccepted_uncertifiedというステータスが付きます。

研究例の結果

examples/labeling-engine/以下の3つの研究例は、コミットされた設定が使うOllamaのモデルの代わりに、LLM、判定者、視覚のソースをvLLMサーバー上のGemma 12Bに向けて実行しました。各例のREADMEには変更したソースのブロックが示されており、Ollamaのデフォルトでは数値が異なります。

  • テキストの感情分析(レビュー481件、最後の段はlogprobの信頼度を使うGemma 12B)。10%、0.9のselective_riskは165個の人手ラベルで満たされ、316個の機械ラベルが受理されました。真のラベルに対して測定したその誤りは7.6%で、PPIの区間は3つのラベルすべての真の出現率を含んでいました。
  • 画像(COCOの画像128枚、YOLOv8nと、視覚モデルとしてのGemma 12B)。「人がいる」ラベルは10%で証明されました。ボックスのコントラクトはinsufficientのままでした。IoU 0.5で、YOLOv8nのボックスはdev画像の32%で誤っていたためです。
  • エージェントトレース(トレース288件、判定者としてのGemma 12B)。判定者はトレースの80%で正しかったものの、信頼度が常に1.0だったため、selective_riskは実行不能でした。代替アノテーター検定はラベル不足で、機械は0.82、人は0.93でした。PPIはタスク成功率を0.66 [0.57, 0.76]と推定しました。真の値は0.60で、判定者だけでは0.76と、16ポイント高くなっていました。

参考資料

実装の詳細については、ソースドキュメントを参照してください。

参考文献

  1. Angelopoulos, A. N., Bates, S., Candès, E. J., et al. (2025). Learn then test: Calibrating predictive algorithms to achieve risk control. The Annals of Applied Statistics. https://doi.org/10.1214/24-AOAS1998
  2. Angelopoulos, A. N., Bates, S., Fannjiang, C., et al. (2023). Prediction-powered inference. Science, 382(6671). https://doi.org/10.1126/science.adi6000
  3. Angelopoulos, A. N., Duchi, J. C., and Zrnic, T. (2023). PPI++: Efficient prediction-powered inference. arXiv. https://arxiv.org/abs/2311.01453
  4. Calderon, N., Reichart, R., and Dror, R. (2025). The alternative annotator test for LLM-as-a-judge: How to statistically justify replacing human annotators with LLMs. Proceedings of ACL 2025. https://aclanthology.org/2025.acl-long.782/