Skip to content
Guides5 min read

Midiendo el Acuerdo Entre Anotadores

Cómo calcular e interpretar el Kappa de Cohen, el Kappa de Fleiss y el Alpha de Krippendorff para tus proyectos de anotación.

Potato Team·

Midiendo el Acuerdo Entre Anotadores

El acuerdo entre anotadores (IAA) mide qué tan consistentemente diferentes anotadores etiquetan los mismos elementos. Un alto acuerdo indica anotaciones confiables; un bajo acuerdo sugiere guías poco claras o tareas subjetivas.

¿Por Qué Medir el Acuerdo?

  • Validar guías: Bajo acuerdo → instrucciones poco claras
  • Evaluar dificultad de la tarea: Algunas tareas son inherentemente subjetivas
  • Calificar anotadores: Identificar quién necesita más entrenamiento
  • Reportar confiabilidad: Requerido para publicaciones científicas
  • Agregar etiquetas: Determinar cómo combinar anotaciones

Métricas de Acuerdo

Kappa de Cohen (2 Anotadores)

Para comparar dos anotadores en datos categóricos:

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

Donde:

  • Po = acuerdo observado
  • Pe = acuerdo esperado por azar

Interpretación:

KappaInterpretación
< 0Menor que el azar
0.01-0.20Leve
0.21-0.40Aceptable
0.41-0.60Moderado
0.61-0.80Sustancial
0.81-1.00Casi perfecto

Kappa de Fleiss (3+ Anotadores)

Para múltiples anotadores en datos categóricos:

yaml
quality_control:
  agreement:
    metrics:
      - fleiss_kappa

Misma escala de interpretación que el Kappa de Cohen.

Alpha de Krippendorff

El más flexible - funciona con:

  • Cualquier número de anotadores
  • Datos faltantes
  • Varios tipos de datos (nominal, ordinal, intervalo, razón)
yaml
quality_control:
  agreement:
    metrics:
      - krippendorff_alpha
    alpha_level: nominal  # or ordinal, interval, ratio

Interpretación:

  • α ≥ 0.80: Confiable
  • 0.67 ≤ α < 0.80: Tentativamente aceptable
  • α < 0.67: No confiable

Configurando el Acuerdo en Potato

Configuración 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

Configuración de Superposición

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 el Acuerdo

En el Panel de Control

Potato muestra métricas de acuerdo en el panel de administración:

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

Vía 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
}

Vía 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

Acuerdo para Diferentes Tipos de Anotación

Categórico (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

Anotaciones de Span

Para NER, los spans requieren manejo 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

Acuerdo por Pares vs General

Por Pares (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

General (Todos los Anotadores)

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

Manejando Bajo Acuerdo

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

Acciones ante Bajo Acuerdo

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

Configuración 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

Reporte de Salida

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}
  ]
}

Mejores Prácticas

  1. Calcular temprano: No esperar hasta el final
  2. Usar métricas apropiadas: Nominal vs ordinal vs span
  3. Investigar bajo acuerdo: Frecuentemente revela problemas en las guías
  4. Reportar en publicaciones: Requerido para trabajo científico
  5. Establecer umbrales: Definir niveles aceptables de antemano

Próximos Pasos


Documentación completa de acuerdo en /docs/core-concepts/user-management.