最優-最差量表(Best-Worst Scaling)
在 Potato 中執行最優-最差量表:標註者在每個元組裡選出最好和最差的項目,再由計數法、Bradley-Terry 或 Plackett-Luce 換算成分數。
v2.3.0 新增
Best-Worst Scaling(BWS),也叫 MaxDiff,把一組項目(通常是四個)擺在標註者面前,請他按某個標準選出最好的和最差的。每個元組點兩下,得到的資訊比打一次分更多;而且因為判斷是比較式的,它繞開了"一個標註者的 7 分相當於另一個標註者的 5 分"這個麻煩。
以下情況值得為 BWS 做這套配置:
- 直接打數值分會受到標註者之間量表使用習慣差異的影響
- 你需要在成百上千個項目上得到一份可靠的排名
- 品質維度本身就是相對的,比如哪個譯文讀起來最流暢
Best-worst scaling interface for comparative annotation in Potato
配置
一個 BWS 任務分成兩部分。方案規定問標註者什麼,頂層的 bws_config 塊規定元組怎麼生成、怎麼評分。
bws_config:
tuple_size: 4 # items shown at once
min_item_appearances: 8 # how often each item must appear across tuples
seed: 42
scoring:
method: counting # counting | bradley_terry | plackett_luce
annotation_schemes:
- annotation_type: bws
name: fluency
description: "Select the BEST and WORST translation by fluency"
tuple_size: 4
best_description: "Most Fluent"
worst_description: "Least Fluent"
sequential_key_binding: true
label_requirement:
required: true方案只接受 tuple_size、best_description、worst_description、sequential_key_binding 和 label_requirement,此外沒有別的。凡是和生成元組或給元組評分有關的,都寫在 bws_config 裡。
缺了 bws_config 塊的 bws 方案,會在一個空的項目列表上渲染問題——BWS 任務開啟是一片空白,通常就是這個原因。
bws_config 選項
| 選項 | 說明 |
|---|---|
tuple_size | 一個元組裡同時顯示多少個項目 |
num_tuples | 總共生成多少個元組 |
min_item_appearances | 每個項目至少要出現在多少個元組裡 |
seed | 固定取樣,使一次執行可以復現 |
scoring.method | counting、bradley_terry 或 plackett_luce |
調高 min_item_appearances 會收緊每個項目的分數,代價是更多的比較次數。分數出來噪聲大的時候,擰的就是這個旋鈕。
資料格式
資料檔案的每一行是一個項目,Potato 從這個池子裡取樣出元組。
{"id": "sys_a", "text": "Le chat s'est assis sur le tapis."}
{"id": "sys_b", "text": "Le chat a assis sur le tapis."}
{"id": "sys_c", "text": "Le chat etait assis sur le mat."}
{"id": "sys_d", "text": "Le chat se tenait sur le tapis."}元組生成會讓整個設計保持平衡:每個項目出現的次數大致相同,需要相互比較的配對共同出現得足夠頻繁,分數才有可比性。設了 seed,這套分配就可以復現。
評分
評分在收集完成之後進行,從命令列執行:
python -m potato.bws_scoring --config config.yaml --method counting結果寫到輸出目錄下的 bws_scores.tsv,除非 --output 指定了別的路徑。參數一共三個:--config、--method 和 --output。
計數法
預設方法,也是最透明的一個。一個項目的分數,是它被選為最好的比例減去被選為最差的比例,所以分數落在 -1.0 到 +1.0 之間。它不需要額外依賴;如果你希望讀者能自己手算一遍來核對,報這個方法。
python -m potato.bws_scoring --config config.yaml --method counting --output scores.tsvBradley-Terry
在每個元組隱含的成對比較上擬合一個模型:最好的項目勝過元組裡其餘所有項目,其餘所有項目又都勝過最差的那個。資料稀疏時,它比計數法處理得更好。
python -m potato.bws_scoring --config config.yaml --method bradley_terryPlackett-Luce
把每次判斷看作兩次選擇:先從整個元組中選出最好的,再從剩下的項目中選出最差的,這正是 MaxDiff 對最優-最差判斷如何做出的建模。它用最大似然為每個項目擬合一個效用值。2.10.2 之前,它擬合的是與 Bradley-Terry 相同的成對比較,返回的分數完全相同;如果你報告過它的結果,請用 2.10.2 或更高版本重新計算分數。
python -m potato.bws_scoring --config config.yaml --method plackett_luce選擇方法
| 方法 | 速度 | 使用的資訊 | 適用場景 |
|---|---|---|---|
counting | 快 | 最好和最差的計數 | 探索性分析,以及希望別人容易核對的結果 |
bradley_terry | 中等 | 隱含的成對比較 | 通常的預設選擇 |
plackett_luce | 較慢 | 每一次最好和最差的選擇,按做出的先後順序 | 對判斷本身的似然模型 |
bradley_terry 需要 pip install choix。plackett_luce 用的是 scipy,Potato 已經自帶安裝。
一次評多個維度
在同一批項目上放兩個 BWS 方案,每個元組就收集兩次判斷,代價是多點一對按鈕,而不是把語料再跑一遍:
annotation_schemes:
- annotation_type: bws
name: fluency
description: "Select the BEST and WORST by fluency"
tuple_size: 4
best_description: "Most Fluent"
worst_description: "Least Fluent"
- annotation_type: bws
name: adequacy
description: "Select the BEST and WORST by meaning preservation"
tuple_size: 4
best_description: "Most Accurate"
worst_description: "Least Accurate"輸出裡有什麼
每個方案記錄下被選為最好的項目和被選為最差的項目:
{
"fluency": {"best": "sys_d", "worst": "sys_c"},
"adequacy": {"best": "sys_a", "worst": "sys_c"}
}分數不在這個檔案裡。它們是事後由 potato.bws_scoring 算出來的——正因為如此,你可以換一種方法給一項已經做完的研究重新評分,而不必重新收集任何資料。
監控
管理面板有一個 BWS 標籤頁,顯示標註進度和當前的項目分數,這樣你可以在決定停止收集之前,先看看排名有沒有穩定下來。
完整示例
annotation_task_name: "MT System Ranking (BWS)"
task_dir: "."
data_files:
- "data/mt_systems.jsonl"
item_properties:
id_key: id
text_key: text
bws_config:
tuple_size: 4
min_item_appearances: 8
seed: 42
scoring:
method: bradley_terry
annotation_schemes:
- annotation_type: bws
name: overall_quality
description: "Select the BEST and the WORST translation"
tuple_size: 4
best_description: "Best Translation"
worst_description: "Worst Translation"
sequential_key_binding: true
label_requirement:
required: true
output_annotation_dir: "annotation_output/"
export_annotation_format: jsonl
user_config:
allow_all_users: true先收集標註,再給它們評分:
potato start config.yaml -p 8000
python -m potato.bws_scoring --config config.yaml --method bradley_terry延伸閱讀
有關實現細節,請參閱源文件。