Best-Worst Scaling
Annotazione comparativa efficiente con Best-Worst Scaling, generazione automatica di tuple e calcolo dei punteggi.
Best-Worst Scaling
Novità nella v2.3.0
Il Best-Worst Scaling (BWS), noto anche come Maximum Difference Scaling (MaxDiff), è un metodo di annotazione comparativa in cui agli annotatori viene mostrata una tupla di elementi (in genere 4) e viene chiesto di selezionare l'elemento migliore e il peggiore secondo un determinato criterio. Il BWS produce punteggi scalari affidabili a partire da semplici giudizi binari, richiedendo molte meno annotazioni rispetto alle scale di valutazione dirette per ottenere la stessa potenza statistica.
Il BWS è particolarmente utile quando:
- Le valutazioni numeriche dirette risentono del bias dell'annotatore (l'utilizzo della scala varia tra le persone)
- È necessaria una classifica affidabile di centinaia o migliaia di elementi
- La dimensione della qualità è intrinsecamente relativa (ad es., "quale traduzione è più scorrevole?")
- Si vuole massimizzare le informazioni per annotazione (ogni giudizio BWS fornisce più bit rispetto a una valutazione Likert)
Configurazione di base
annotation_schemes:
- annotation_type: best_worst_scaling
name: fluency
description: "Select the BEST and WORST translation by fluency"
# Items to compare
items_key: "translations" # key in instance data containing the list of items
# Tuple size (how many items shown at once)
tuple_size: 4 # typically 4; valid range is 3-8
# Labels for best/worst buttons
best_label: "Most Fluent"
worst_label: "Least Fluent"
# Display options
show_item_labels: true # show "A", "B", "C", "D" labels
randomize_order: true # randomize item order within each tuple
show_source: false # optionally show which system produced each item
# Validation
label_requirement:
required: true # must select both best and worstFormato dei dati
Ogni istanza nel file di dati deve contenere un elenco di elementi da confrontare. Potato genera le tuple da questo elenco automaticamente.
Opzione 1: tutti gli elementi in un'unica istanza
Se si dispone di un singolo insieme di elementi da classificare (ad es., traduzioni di una frase):
{
"id": "sent_001",
"source": "The cat sat on the mat.",
"translations": [
{"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."}
]
}Opzione 2: tuple pre-generate
Se si desidera il controllo completo su quali elementi appaiono insieme, fornire tuple pre-generate:
{
"id": "tuple_001",
"translations": [
{"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."}
]
}Generazione automatica di tuple
Quando l'elenco degli elementi è più lungo della dimensione della tupla, Potato genera automaticamente le tuple. L'algoritmo di generazione garantisce:
- Ogni elemento appare approssimativamente nello stesso numero di tuple
- Ogni coppia di elementi co-occorre in almeno una tupla (per un punteggio relativo affidabile)
- Le tuple sono bilanciate in modo che nessun elemento sia sempre mostrato per primo o per ultimo
Configura la generazione di tuple:
annotation_schemes:
- annotation_type: best_worst_scaling
name: fluency
items_key: "translations"
tuple_size: 4
tuple_generation:
method: balanced_incomplete # balanced_incomplete or random
tuples_per_item: 5 # each item appears in ~5 tuples
seed: 42 # for reproducibility
ensure_pair_coverage: true # every pair co-occurs at least oncePer un insieme di N elementi con dimensione della tupla T e tuples_per_item = K, Potato genera approssimativamente N * K / T tuple totali.
Metodi di generazione
balanced_incomplete (predefinito): Utilizza un disegno a blocchi incompleto bilanciato per massimizzare l'efficienza statistica. Ogni elemento appare ugualmente spesso e la co-occorrenza delle coppie è il più uniforme possibile. Consigliato per la maggior parte dei casi d'uso.
random: Campiona casualmente le tuple con sostituzione. Più veloce per set di elementi molto grandi (N > 10.000) ma statisticamente meno efficiente. Da usare quando il bilanciamento esatto non è critico.
Pre-generazione di tuple tramite CLI
Per progetti su larga scala, genera le tuple in anticipo:
python -m potato.bws generate-tuples \
--items data/items.jsonl \
--tuple-size 4 \
--tuples-per-item 5 \
--output data/tuples.jsonl \
--seed 42Metodi di punteggio
Dopo l'annotazione, Potato calcola i punteggi degli elementi dai giudizi BWS utilizzando tre metodi.
1. Conteggio (predefinito)
Il metodo più semplice. Il punteggio di ogni elemento è la proporzione di volte in cui è stato selezionato come "migliore" meno la proporzione di volte in cui è stato selezionato come "peggiore":
Punteggio(elemento) = (conteggio_migliore - conteggio_peggiore) / totale_apparizioni
I punteggi variano da -1,0 (sempre peggiore) a +1,0 (sempre migliore).
python -m potato.bws score \
--config config.yaml \
--method counting \
--output scores.csv2. Bradley-Terry
Adatta un modello Bradley-Terry ai confronti a coppie impliciti dai giudizi BWS. Ogni selezione "migliore" implica che l'elemento migliore è preferito a tutti gli altri elementi nella tupla; ogni selezione "peggiore" implica che tutti gli altri elementi sono preferiti al peggiore.
Bradley-Terry produce punteggi su una scala log-odds con migliori proprietà statistiche rispetto al conteggio, specialmente con dati sparsi.
python -m potato.bws score \
--config config.yaml \
--method bradley_terry \
--max-iter 1000 \
--tolerance 1e-6 \
--output scores.csv3. Plackett-Luce
Una generalizzazione di Bradley-Terry che modella la classifica completa implicita da ogni giudizio di tupla (migliore > elementi medi > peggiore). Plackett-Luce estrae più informazioni da ogni annotazione rispetto a Bradley-Terry.
python -m potato.bws score \
--config config.yaml \
--method plackett_luce \
--output scores.csvConfronto dei metodi di punteggio
| Metodo | Velocità | Efficienza dei dati | Gestisce dati sparsi | Modello statistico |
|---|---|---|---|---|
| Conteggio | Veloce | Bassa | Sì | Nessuno (descrittivo) |
| Bradley-Terry | Medio | Media | Moderata | Confronto a coppie |
| Plackett-Luce | Più lento | Alta | Moderata | Classifica completa |
Per la maggior parte dei progetti, Bradley-Terry è il miglior predefinito. Usa il Conteggio per un'analisi esplorativa rapida e Plackett-Luce quando hai bisogno della massima efficienza statistica da annotazioni limitate.
Configurazione del punteggio in YAML
È anche possibile configurare il punteggio direttamente nella configurazione del progetto per il calcolo automatico:
annotation_schemes:
- annotation_type: best_worst_scaling
name: fluency
items_key: "translations"
tuple_size: 4
scoring:
method: bradley_terry
auto_compute: true # compute scores after each annotation session
output_file: "output/fluency_scores.csv"
include_confidence: true # include confidence intervals
bootstrap_iterations: 1000 # for confidence interval estimationIntegrazione con il pannello di amministrazione
Il pannello di amministrazione include una scheda BWS dedicata che mostra:
- Distribuzione dei punteggi: Istogramma dei punteggi attuali degli elementi
- Avanzamento delle annotazioni: Quante tuple sono state annotate rispetto al totale
- Copertura per elemento: Quante volte ogni elemento è stato visualizzato
- Coerenza tra annotatori: Affidabilità split-half dei punteggi BWS
- Convergenza dei punteggi: Grafico a linee che mostra come i punteggi si stabilizzano man mano che vengono raccolte più annotazioni
Accedi alle analisi BWS dalla riga di comando:
python -m potato.bws stats --config config.yamlBWS Statistics
==============
Schema: fluency
Items: 200
Tuples: 250 (annotated: 180 / 250)
Annotations: 540 (3 annotators)
Score Summary (Bradley-Terry):
Mean: 0.02
Std: 0.43
Range: -0.91 to +0.87
Top 5 Items:
sys_d: 0.87 (±0.08)
sys_a: 0.72 (±0.09)
sys_f: 0.65 (±0.10)
sys_b: 0.51 (±0.11)
sys_k: 0.48 (±0.09)
Split-Half Reliability: r = 0.94
Dimensioni BWS multiple
È possibile eseguire più schemi BWS sullo stesso insieme di elementi per valutare diverse dimensioni di qualità:
annotation_schemes:
- annotation_type: best_worst_scaling
name: fluency
description: "Select BEST and WORST by fluency"
items_key: "translations"
tuple_size: 4
best_label: "Most Fluent"
worst_label: "Least Fluent"
- annotation_type: best_worst_scaling
name: adequacy
description: "Select BEST and WORST by meaning preservation"
items_key: "translations"
tuple_size: 4
best_label: "Most Accurate"
worst_label: "Least Accurate"Entrambi gli schemi condividono le stesse tuple (Potato genera un set di tuple per ogni items_key), quindi gli annotatori vedono ogni tupla una volta ma forniscono due giudizi.
Formato di output
Le annotazioni BWS vengono salvate per tupla:
{
"id": "tuple_001",
"annotations": {
"fluency": {
"best": "sys_d",
"worst": "sys_c"
},
"adequacy": {
"best": "sys_a",
"worst": "sys_c"
}
},
"annotator": "user_1",
"timestamp": "2026-03-01T14:22:00Z"
}Esempio completo
Configurazione completa per la valutazione di sistemi di traduzione automatica:
task_name: "MT System Ranking (BWS)"
task_dir: "."
data_files:
- "data/mt_tuples.jsonl"
item_properties:
id_key: id
text_key: source
instance_display:
fields:
- key: source
type: text
display_options:
label: "Source Sentence"
annotation_schemes:
- annotation_type: best_worst_scaling
name: overall_quality
description: "Select the BEST and WORST translation"
items_key: "translations"
tuple_size: 4
best_label: "Best Translation"
worst_label: "Worst Translation"
randomize_order: true
show_item_labels: true
tuple_generation:
method: balanced_incomplete
tuples_per_item: 5
seed: 42
scoring:
method: bradley_terry
auto_compute: true
output_file: "output/quality_scores.csv"
include_confidence: true
output_annotation_dir: "output/"
output_annotation_format: "jsonl"Ulteriori letture
- Confronto a coppie -- confronto più semplice tra due elementi
- Scale Likert -- alternativa con valutazione diretta
- Multirate -- valutazioni dirette multidimensionali
- Formati di esportazione -- esporta i dati BWS per l'analisi
Per i dettagli di implementazione, consulta la documentazione sorgente.