Accordo su span e output strutturati
Perché il kappa di Cohen e di Fleiss non regge per span, NER e annotazione strutturata, e cosa usare al suo posto: F1 come accordo, match esatto o parziale e l'alpha unitizzato di Krippendorff.
Le misure di accordo corrette per il caso, come il kappa di Cohen, presuppongono che ogni annotatore etichetti lo stesso insieme fisso di elementi con lo stesso insieme fisso di categorie. L'annotazione a span rompe questa assunzione: gli annotatori possono divergere su dove uno span inizia, dove finisce e se esiste affatto. Per gli span la misura di affidabilità standard è l'F1 a coppie, non il kappa, e devi decidere fin dall'inizio se una sovrapposizione parziale dei confini conta come accordo. Questa guida spiega perché qui le metriche abituali falliscono e cosa riportare invece.
Perché il kappa non si adatta agli span
Un coefficiente corretto per il caso richiede tre cose: una lista fissa di elementi, una lista fissa di etichette e la possibilità di calcolare quanto spesso gli annotatori concorderebbero per caso. I task a span non ne forniscono nessuna in modo pulito. Non c'è una lista predeterminata di «elementi» da etichettare, l'annotatore inventa gli span mentre legge, quindi due persone possono produrre un numero diverso di span sullo stesso documento. E non c'è una classe negativa sensata: gli «elementi che nessuno ha marcato» sono tutte le possibili sottostringhe, un insieme enorme e mal definito.
È l'ultimo punto quello decisivo. Hripcsak e Rothschild (2005) hanno mostrato che quando la classe negativa è molto grande o indefinita, come nell'information retrieval e nell'estrazione di span, la probabilità che due annotatori concordino sullo stesso span arbitrario è di fatto nulla, quindi la correzione per il caso non cambia quasi niente e le assunzioni dietro il kappa non valgono più. Il loro risultato è la giustificazione standard per un'alternativa più pulita: la F-measure è essa stessa la statistica di accordo appropriata. Tratta gli span di un annotatore come riferimento e quelli dell'altro come previsioni, calcola l'F1 e fai la media su tutte le coppie di annotatori. Dato che l'F1 è simmetrico, l'ordine della coppia non conta.
Match esatto o match parziale: decidi prima di misurare
Il numero che riporti dipende interamente da cosa consideri un successo, e non esiste una risposta universale, quindi dichiara la tua scelta.
- Match esatto: due span concordano solo se entrambi i confini coincidono. È rigido, ed è la scelta giusta quando i confini portano significato (citazioni giuridiche, nomi di composti chimici).
- Match parziale / per sovrapposizione: due span concordano se si sovrappongono, anche solo un po' o oltre una certa soglia. È più permissivo, e ha senso quando conta la presenza di un'entità più della sua estensione precisa.
- Confini vs. etichetta: per gli span tipizzati (NER), separa due domande, gli annotatori hanno marcato la stessa estensione, e le hanno dato lo stesso tipo? Riportarle insieme nasconde quale delle due stia davvero generando il disaccordo.
Artstein e Poesio (2008) è la rassegna di riferimento sull'accordo in linguistica computazionale e affronta in dettaglio questo problema di «unitizing», il disaccordo su come segmentare il testo in unità. È il lavoro da citare quando devi difendere una scelta metodologica.
Quando invece vuoi un numero corretto per il caso
Se riesci a ridurre il task a un insieme fisso di unità, la correzione per il caso torna valida. Due riduzioni comuni:
- Etichettatura a livello di token: riformula il task a span come un'etichetta per token (lo schema BIO). Ora ogni token è un elemento fisso con un piccolo insieme di etichette, e il kappa di Fleiss o l'alpha di Krippendorff si applicano direttamente. Il problema è che l'accordo a livello di token risulta gonfiato, la maggior parte dei token appartiene alla classe facile «outside», quindi un numero alto può nascondere un vero disaccordo sui confini.
- Alpha unitizzato: Krippendorff (2004) ha sviluppato una variante dell'alpha proprio per il caso in cui sono gli annotatori a segmentare un continuum. È l'opzione rigorosa quando vuoi una singola cifra di affidabilità corretta per il caso sulla segmentazione, al prezzo di una preparazione più laboriosa.
Una via di mezzo pratica: riporta insieme il kappa a livello di token e l'F1 a livello di span. Il primo ti dice qualcosa sulla coerenza delle etichette, il secondo sulla coerenza dei confini, e la distanza tra i due ti dice quale problema risolvere.
Farlo in Potato
Potato calcola in automatico l'alpha di Krippendorff per gli schemi categoriali, ma per uno schema span il numero a livello di documento nasconde il disaccordo sui confini, quindi misura al livello che ti interessa davvero. La ricetta affidabile è far lavorare gli annotatori in sovrapposizione su un sottoinsieme condiviso, esportare i loro span e calcolare da te l'F1 a coppie secondo la regola di match che hai scelto.
annotation_schemes:
- name: pii_spans
annotation_type: span
description: "Highlight every span that reveals personal information."
labels:
- name: person
- name: location
- name: org
# Overlap a subset so agreement is measurable
automatic_assignment:
on: true
instance_per_annotator: 100
labels_per_instance: 3L'export conserva gli span di ciascun annotatore con i loro offset di carattere e le etichette, cioè tutto quello che serve per calcolare offline l'F1 a match esatto o per sovrapposizione, e per separare l'accordo sui confini da quello sui tipi. Se i tuoi span sono tipizzati, calcola l'F1 due volte, una ignorando il tipo (accordo sui confini) e una richiedendo che il tipo coincida (accordo pieno).
Approfondimenti
- L'accordo tra annotatori spiegato, per le metriche corrette per il caso che si applicano ai task categoriali.
- Annotazione a span e Riconoscimento di entità nominate, per progettare il task in sé.
- Risoluzione della coreferenza, dove l'accordo ha metriche specializzate proprie (MUC, B³, CEAF).
- Esportare le annotazioni per il machine learning, per tirare fuori gli span e calcolare l'F1.