Skip to content
Guides6 min read

Medindo a Concordância Entre Anotadores

Calcule e interprete o Kappa de Cohen, o Kappa de Fleiss e o Alpha de Krippendorff para projetos de anotação no Potato, com exemplos de código em Python e diretrizes de interpretação.

Potato Team

A concordância entre anotadores (IAA) mede o quão consistentemente diferentes anotadores rotulam os mesmos itens. Quando a concordância é alta, você pode confiar nos rótulos. Quando ela é baixa, o culpado de costume é uma diretriz pouco clara ou uma tarefa que é, por natureza, subjetiva.

Por que medir a concordância?

Há algumas razões que justificam o esforço. Concordância baixa geralmente aponta de volta para instruções que precisam ser reescritas, então o número também serve como um teste das suas diretrizes. Ele também indica o quão difícil a tarefa realmente é, já que algumas perguntas não têm uma única resposta certa. Você consegue identificar quais anotadores precisam de mais treinamento. E, se você for publicar, os revisores vão esperar um valor de concordância. Por fim, a métrica orienta como você combina vários anotadores em um único rótulo.

Para saber como o Potato lida com isso de ponta a ponta, consulte a documentação de origem.

Métricas de concordância

Kappa de Cohen (2 anotadores)

Para comparar dois anotadores em dados categóricos:

text
κ = (Po - Pe) / (1 - Pe)

Onde:

  • Po = concordância observada
  • Pe = concordância esperada por acaso

Interpretação:

KappaInterpretação
< 0Menor que o acaso
0.01-0.20Leve
0.21-0.40Razoável
0.41-0.60Moderada
0.61-0.80Substancial
0.81-1.00Quase perfeita

Kappa de Fleiss (3+ anotadores)

Para três ou mais anotadores em dados categóricos:

yaml
quality_control:
  agreement:
    metrics:
      - fleiss_kappa

Mesma escala de interpretação do Kappa de Cohen.

Alpha de Krippendorff

Este é o mais flexível dos três. Ele lida com qualquer número de anotadores, dá conta de dados ausentes e funciona com dados nominais, ordinais, intervalares e de razão.

yaml
quality_control:
  agreement:
    metrics:
      - krippendorff_alpha
    alpha_level: nominal  # or ordinal, interval, ratio

Interpretação:

  • α ≥ 0.80: Confiável
  • 0.67 ≤ α < 0.80: Aceitável de forma provisória
  • α < 0.67: Não confiável

Configurando a Concordância no Potato

Configuração Básica

yaml
quality_control:
  agreement:
    enabled: true
    calculate_on_overlap: true
 
    metrics:
      - cohens_kappa
      - fleiss_kappa
      - krippendorff_alpha
 
    # Per annotation scheme
    per_scheme: true
 
    # Reporting
    report_interval: 100  # Every 100 annotations
    export_file: agreement_report.json

Configuração de Sobreposição

yaml
quality_control:
  redundancy:
    # How many annotators per item
    annotations_per_item: 3
 
    # Minimum overlap for calculations
    min_overlap_for_agreement: 2
 
    # Sampling for agreement
    agreement_sample_size: 100  # Calculate on 100 items
    agreement_sample_method: random  # or stratified, all

Calculando a Concordância

No Painel

O Potato exibe as métricas de concordância no painel de administração:

yaml
quality_control:
  dashboard:
    show_agreement: true
    agreement_chart: true
    update_frequency: 60  # seconds

Via API

bash
# Get current agreement metrics
curl http://localhost:8000/api/quality/agreement
 
# Response:
{
  "overall": {
    "fleiss_kappa": 0.72,
    "krippendorff_alpha": 0.75
  },
  "per_scheme": {
    "sentiment": {
      "fleiss_kappa": 0.78,
      "krippendorff_alpha": 0.80
    },
    "topic": {
      "fleiss_kappa": 0.65,
      "krippendorff_alpha": 0.68
    }
  },
  "sample_size": 150,
  "annotator_pairs": 10
}

Via CLI

bash
# Calculate agreement from output files
potato agreement --annotations annotation_output/ --output agreement_report.json
 
# With specific metric
potato agreement --annotations annotation_output/ --metric krippendorff --level ordinal

Concordância para Diferentes Tipos de Anotação

Categórica (Radio, Multiselect)

yaml
quality_control:
  agreement:
    schemes:
      sentiment:
        type: nominal
        metrics: [cohens_kappa, fleiss_kappa]
 
      urgency:
        type: ordinal  # Low < Medium < High
        metrics: [krippendorff_alpha]

Escalas Likert

yaml
quality_control:
  agreement:
    schemes:
      quality_rating:
        type: ordinal
        metrics: [krippendorff_alpha, weighted_kappa]
 
        # Weighted kappa for ordinal
        weighting: linear  # or quadratic

Anotações de Span

Spans são mais complicados que rótulos categóricos, já que dois anotadores podem concordar em um rótulo, mas discordar exatamente sobre onde ele começa e termina. NER exige um tratamento especial:

yaml
quality_control:
  agreement:
    schemes:
      entities:
        type: span
        span_matching: overlap  # or exact, token
 
        # What to compare
        compare: label_and_span  # or label_only, span_only
 
        # Overlap threshold for "match"
        overlap_threshold: 0.5
 
        metrics:
          - span_f1
          - span_precision
          - span_recall

Rankings

yaml
quality_control:
  agreement:
    schemes:
      preference_rank:
        type: ranking
        metrics:
          - kendall_tau
          - spearman_rho

Concordância Pareada vs. Geral

Pareada (Cada Par)

yaml
quality_control:
  agreement:
    pairwise: true
    output_matrix: true  # Agreement matrix
 
# Output:
# annotator1 × annotator2: κ = 0.75
# annotator1 × annotator3: κ = 0.68
# annotator2 × annotator3: κ = 0.82

Geral (Todos os Anotadores)

yaml
quality_control:
  agreement:
    overall: true
    metrics:
      - fleiss_kappa  # Designed for 3+ annotators
      - krippendorff_alpha

Lidando com Concordância Baixa

Identificar Áreas Problemáticas

yaml
quality_control:
  agreement:
    diagnostics:
      enabled: true
 
      # Items with most disagreement
      show_disagreed_items: true
      disagreement_threshold: 0.5
 
      # Labels with most confusion
      confusion_matrix: true
 
      # Annotators with low agreement
      per_annotator_agreement: true

Ações em Caso de Concordância Baixa

yaml
quality_control:
  agreement:
    alerts:
      - threshold: 0.6
        action: notify
        message: "Agreement below 0.6 - review guidelines"
 
      - threshold: 0.4
        action: pause
        message: "Agreement critically low - pausing task"
 
    # Automatic guideline reminders
    show_guidelines_on_low_agreement: true
    guideline_threshold: 0.5

Configuração Completa

yaml
annotation_task_name: "Agreement-Tracked Annotation"
 
quality_control:
  # Redundancy setup
  redundancy:
    annotations_per_item: 3
    assignment_method: random
 
  # Agreement calculation
  agreement:
    enabled: true
 
    # Metrics
    metrics:
      - fleiss_kappa
      - krippendorff_alpha
 
    # Per-scheme configuration
    schemes:
      sentiment:
        type: nominal
        metrics: [fleiss_kappa, cohens_kappa]
 
      intensity:
        type: ordinal
        metrics: [krippendorff_alpha]
        alpha_level: ordinal
 
      entities:
        type: span
        span_matching: overlap
        overlap_threshold: 0.5
        metrics: [span_f1]
 
    # Calculation settings
    calculate_on_overlap: true
    min_overlap: 2
    sample_size: all  # or number
 
    # Pairwise analysis
    pairwise: true
    pairwise_output: agreement_matrix.csv
 
    # Diagnostics
    diagnostics:
      confusion_matrix: true
      disagreed_items: true
      per_annotator: true
 
    # Alerts
    alerts:
      - metric: fleiss_kappa
        threshold: 0.6
        action: notify
 
    # Reporting
    report_file: agreement_report.json
    report_interval: 50
 
  # Dashboard
  dashboard:
    show_agreement: true
    charts:
      - agreement_over_time
      - per_scheme_agreement
      - annotator_comparison

Relatório de Saída

json
{
  "timestamp": "2024-10-25T15:30:00Z",
  "sample_size": 500,
  "annotators": ["ann1", "ann2", "ann3"],
 
  "overall_agreement": {
    "fleiss_kappa": 0.72,
    "krippendorff_alpha": 0.75
  },
 
  "per_scheme": {
    "sentiment": {
      "fleiss_kappa": 0.78,
      "confusion_matrix": {
        "Positive": {"Positive": 180, "Negative": 5, "Neutral": 15},
        "Negative": {"Positive": 8, "Negative": 165, "Neutral": 12},
        "Neutral": {"Positive": 12, "Negative": 10, "Neutral": 93}
      }
    }
  },
 
  "pairwise": {
    "ann1_ann2": 0.75,
    "ann1_ann3": 0.70,
    "ann2_ann3": 0.72
  },
 
  "per_annotator": {
    "ann1": {"avg_agreement": 0.73, "items_annotated": 500},
    "ann2": {"avg_agreement": 0.74, "items_annotated": 500},
    "ann3": {"avg_agreement": 0.71, "items_annotated": 500}
  },
 
  "most_disagreed_items": [
    {"id": "item_234", "disagreement_rate": 1.0},
    {"id": "item_567", "disagreement_rate": 0.67}
  ]
}

Boas práticas

Calcule a concordância cedo em vez de esperar até o fim do projeto, porque a essa altura já é tarde demais para corrigir as diretrizes. Escolha a métrica que combina com os seus dados: nominal, ordinal ou span. Quando a concordância volta baixa, investigue antes de culpar os anotadores, já que o problema costuma estar nas instruções. Relate o valor em qualquer publicação. E decida um limite aceitável antes de começar, não depois de ver o resultado que você obteve.

Para uma cobertura mais aprofundada da estimativa de competência quando os anotadores discordam, consulte a documentação do MACE.

Próximos passos


Documentação completa sobre concordância em /docs/core-concepts/user-management.