Skip to content

Guide

Casi raggruppati

La maggior parte dell'aritmetica degli intervalli presuppone che ogni caso sia indipendente da ogni altro. Tre turni di una stessa conversazione non lo sono: quando la conversazione va male, tendono ad andare male tutti e tre. Una suite che li tratta come indipendenti riporta un intervallo più stretto di quanto l'evidenza sostenga, e un gate può passare su di esso.

Dichiarare un cluster

Un caso indica il proprio cluster con group_id, al livello superiore della riga accanto a id:

{"id": "conv00_t0", "group_id": "conv00", "input": {"question": "Conversation 0 turn 0: refund please (garbled)"}, "expected": {"label": "refund"}}
{"id": "conv00_t1", "group_id": "conv00", "input": {"question": "Conversation 0 turn 1: where is my order (garbled)"}, "expected": {"label": "other"}}
{"id": "conv00_t2", "group_id": "conv00", "input": {"question": "Conversation 0 turn 2: refund please (garbled)"}, "expected": {"label": "refund"}}

Non appena un caso ne dichiara uno, l'intera suite viene analizzata per cluster. Non esiste un interruttore per metrica per tornare indietro: trattare casi raggruppati come indipendenti è la direzione non sicura, quindi non viene offerta.

Che cosa cambia

Gli stessi 108 turni di 36 conversazioni, una conversazione su sei alterata dal primo all'ultimo turno. Senza group_id:

│ exact_label │ 83.3%    │ [74.9%, 89.9%] │ 90 / 108 observed · 0 missing · 0 excluded │

Con esso:

│ exact_label │ 83.3%    │ [65.2%, 94.6%] │ 90 / 108 observed · 0 missing · 0 excluded · 36 clusters · approximate │

La stima è identica. L'intervallo è circa il doppio più ampio, perché la suite contiene 36 osservazioni indipendenti anziché 108. Con una soglia minima di 0.70, con l'adesione esplicita descritta di seguito, la prima esecuzione passa e la seconda no:

label-floor: PASS (lower_bound_meets_minimum)
label-floor: INSUFFICIENT_EVIDENCE (interval_overlaps_threshold)

La seconda risposta è quella giusta per questi dati.

L'adesione esplicita

L'intervallo per cluster è un bootstrap per cluster studentizzato. È un metodo approssimato, e una policy deve dichiarare di accettarne uno prima che una regola possa decidere su di esso. Senza questo, la stessa esecuzione raggruppata riporta:

label-floor: MANUAL_REVIEW (approximate_method_not_permitted)

ed esce con 4. Per permettere alla regola di decidere, aggiungi questo a release.yaml:

allow_approximate_methods: true

Altre due impostazioni limitano ciò per cui ci si fida del metodo.

ImpostazionePredefinitoChe cosa fa
min_clusters20Con meno cluster di questo valore una regola riporta INSUFFICIENT_EVIDENCE con insufficient_clusters. Può essere abbassato a 10 e non oltre.
max_missing_fractionnessunoSi imposta su una regola. Un intervallo per cluster non può delimitare i casi mancanti come fa uno indipendente, quindi una regola per cluster su una metrica con almeno un caso mancante riporta missingness_unbounded finché la regola non dichiara quanti dati mancanti accetta.

Una policy che imposta min_clusters: 5 viene rifiutata prima che si decida qualsiasi cosa:

Configuration error: p5.yaml: min_clusters: Input should be greater than or equal to 10

Le stesse conversazioni con una di esse in errore a ogni turno:

│ exact_label │ 82.9%    │ [64.3%, 94.5%] │ 87 / 105 observed · 3 missing · 0 excluded · 35 clusters · approximate │
label-floor: INSUFFICIENT_EVIDENCE (missingness_unbounded)

Una regola che dichiara quanti dati mancanti accetta:

rules:
  - id: label-floor
    metric: exact_label
    min: 0.60
    max_missing_fraction: 0.15
label-floor: PASS (lower_bound_meets_minimum)

Dichiarare una frazione registra un'ipotesi: che i casi mancanti manchino in modo casuale. La decisione vale quanto quell'ipotesi, ed è per questo che il motore non la adotta al posto tuo.

Che cosa una suite raggruppata non può ancora fare

Solo i tassi pass/fail hanno un intervallo per cluster. Su una suite che dichiara group_id:

  • una media, un quantile o una metrica di ranking non ha intervallo, e una regola su di essa

riporta MANUAL_REVIEW con unsupported_dependence_structure;

  • con replicates: superiore a 1, nessuna metrica ha un intervallo, tassi pass/fail compresi,

perché le due strutture di dipendenza si combinano e nulla le modella entrambe;

  • un confronto tra due esecuzioni non ha intervallo per nessuna metrica.

Un quantile di latenza sulla suite raggruppata:

│ latency_p50 │ 1.365 ms │ no interval: unsupported_dependence_structure │ p50 of 108 observed · 0 missing · 0 excluded │

L'ultima limitazione è quella che conta di più. Confrontando due esecuzioni della suite di conversazioni, con il candidato che corregge ogni conversazione alterata:

oloproof compare CANDIDATE_RUN_ID BASELINE_RUN_ID --policy compare.yaml
Comparison sha256:ed7820e6471f70ce2b5e16ba618fdd48ea92a5ed39d23cce0b719ab31fcb16af of run_01M3C43MWTH8127R7S5M4N9DQ9 against run_01M3C43J2DVM93EWWWRBMRW22E · 108 paired cases
exact_label: +16.7 points · 108 paired · 0 missing · 0 excluded
  no interval: unsupported_dependence_structure
Decisions
  no-regression  exact_label  non-inferiority, margin 5.0 points  MANUAL_REVIEW  unsupported_dependence_structure
Gate: BLOCK (exit 4)

Nessuna procedura appaiata per suite raggruppate ha superato la propria griglia di validazione, quindi il confronto riporta la differenza e chiede a una persona anziché decidere in modo approssimato. MANUAL_REVIEW anziché INSUFFICIENT_EVIDENCE, perché più casi dello stesso tipo non risolverebbero il problema.

Dove andare dopo

confronto.