Construyendo Tu Primera Tarea de Anotación NER
Guía paso a paso para crear una tarea de reconocimiento de entidades nombradas en Potato, con la configuración de spans, colores de etiquetas, spans superpuestos, atajos de teclado y exportación a CoNLL.
Este tutorial construye en Potato una tarea de reconocimiento de entidades nombradas (NER) con cinco tipos de entidad, atajos con las teclas numéricas, instrucciones para los anotadores y una exportación a CoNLL-2003 para entrenar modelos. Para las opciones de configuración de spans que hay detrás, consulta la documentación de anotación de spans.
Lo que recibe el anotador
La tarea terminada presenta al anotador una oración con una fila de botones etiquetados encima. El anotador arrastra sobre una frase para seleccionarla, pulsa una tecla numérica o hace clic en un botón para etiquetarla, y vuelve a hacer clic en un span etiquetado para cambiarlo o eliminarlo. Cada span se guarda con sus desplazamientos de caracteres, de modo que el mismo archivo de anotaciones sirve tanto para una exportación a CoNLL-2003 como para un cálculo de acuerdo a nivel de span.
Requisitos Previos
Necesitas Potato instalado, un archivo de datos de texto y el YAML suficiente para editar una configuración:
pip install potato-annotationPaso 1: El esquema de spans
La anotación de spans es el tipo span de Potato. Cada etiqueta necesita un nombre, y los campos opcionales útiles son color, que distingue visualmente los tipos de entidad en un texto denso, key_value, que asocia un atajo de teclado a la etiqueta, y tooltip, que muestra la definición de la etiqueta al pasar el cursor para que los anotadores no tengan que salir de la página para consultar el libro de códigos.
Con cinco tipos la tarea se puede aprender en una sola sesión. A partir de unos ocho, los anotadores empiezan a consultar las guías en cada elemento, y ahí es donde cae el rendimiento. sequential_key_binding activa las teclas numéricas, y key_value fija qué número corresponde a cada etiqueta en lugar de dejarlo al orden de la lista. Crea config.yaml:
annotation_task_name: "Named Entity Recognition"
task_dir: "."
data_files:
- data/sentences.json
item_properties:
id_key: id
text_key: text
output_annotation_dir: "annotation_output/"
export_annotation_format: "jsonl"
annotation_schemes:
- annotation_type: span
name: entities
description: "Highlight and label named entities in the text"
sequential_key_binding: true
labels:
- name: PER
tooltip: "Person names, including fictional characters"
color: "#FF6B6B"
key_value: "1"
- name: ORG
tooltip: "Companies, institutions, agencies"
color: "#4ECDC4"
key_value: "2"
- name: LOC
tooltip: "Places, including countries, cities, landmarks"
color: "#45B7D1"
key_value: "3"
- name: DATE
tooltip: "Dates, times, and temporal expressions"
color: "#96CEB4"
key_value: "4"
- name: MISC
tooltip: "Named entities that fit none of the above"
color: "#FFEAA7"
key_value: "5"
user_config:
allow_all_users: truePaso 2: El archivo de datos
Potato lee un objeto JSON por línea y toma los campos indicados en item_properties. Crea data/sentences.json:
{"id": "1", "text": "Apple Inc. announced that CEO Tim Cook will visit Paris next Tuesday."}
{"id": "2", "text": "The United Nations headquarters in New York hosted delegates from Japan."}
{"id": "3", "text": "Dr. Sarah Johnson published her research at Stanford University in March 2024."}Tres oraciones bastan para comprobar que la interfaz funciona. Carga el corpus real cuando el conjunto de etiquetas haya superado una prueba piloto.
Paso 3: Instrucciones al alcance del anotador
La mayor parte del desacuerdo en NER proviene de las reglas de límites y no de los tipos de entidad en sí, así que las reglas que deciden más elementos deben estar en la pantalla de anotación. annotation_instructions se muestra como un panel plegable en la parte superior de cada elemento, abierto por defecto, que los anotadores pliegan cuando ya conocen la tarea. Añade este bloque a la configuración anterior:
annotation_instructions: |
## Entity types
- **PER** covers people, including fictional characters ("John Smith", "Dr. Johnson", "Batman")
- **ORG** covers companies, institutions, and agencies ("Apple Inc.", "United Nations", "Stanford University")
- **LOC** covers places, including countries, cities, and landmarks ("Paris", "New York", "Mount Everest")
- **DATE** covers dates, times, and temporal expressions ("Tuesday", "March 2024", "next week")
- **MISC** covers named entities that fit none of the above ("Nobel Prize", "iPhone", "COVID-19")
## Boundary rules
1. Include titles (Dr., Mr.) with person names.
2. For nested entities, annotate the largest meaningful span.
3. Leave articles (the, a) outside the span.Aquí se renderiza Markdown, así que puedes copiar el mismo texto de tu libro de códigos sin reescribirlo como HTML. Limita este panel a las reglas que resuelven la mayoría de los elementos y deja el libro de códigos completo detrás de annotation_codebook_url, que se abre en su propia pestaña.
La interfaz de spans muestra entonces las etiquetas como botones sobre el texto:
Los anotadores resaltan spans de texto y asignan etiquetas de entidad como PER, ORG, LOC y DATE
Paso 4: Ejecutar la tarea
Inicia el servidor con la configuración del Paso 1:
potato start config.yamlAbre la dirección que imprime e inicia sesión. A partir de ahí, el anotador realiza cuatro acciones por entidad:
- Seleccionar el texto. Haz clic y arrastra sobre la frase.
- Asignar el tipo. Pulsa la tecla numérica o haz clic en el botón de la etiqueta.
- Corregir un error. Haz clic en un span existente para cambiar su etiqueta o eliminarlo.
- Enviar. Pasa al siguiente elemento cuando termines la oración.
Paso 5: Qué contiene el archivo de salida
Cada elemento anotado se escribe en annotation_output/ como un objeto JSON, con el nombre del esquema como clave y una entrada por span:
{
"id": "1",
"text": "Apple Inc. announced that CEO Tim Cook will visit Paris next Tuesday.",
"entities": [
{"start": 0, "end": 10, "label": "ORG", "text": "Apple Inc."},
{"start": 30, "end": 38, "label": "PER", "text": "Tim Cook"},
{"start": 50, "end": 55, "label": "LOC", "text": "Paris"},
{"start": 61, "end": 73, "label": "DATE", "text": "next Tuesday"}
]
}Los desplazamientos de caracteres son lo que hace útil el archivo en etapas posteriores. Sobreviven a los cambios de tokenización, así que las mismas anotaciones pueden realinearse con el tokenizador que use tu modelo.
Paso 6: Exportar a CoNLL-2003
Los modelos de etiquetado de secuencias leen tokens etiquetados y no desplazamientos de caracteres, así que Potato convierte los spans al exportar:
python -m potato.export -c config.yaml -f conll_2003 -o ./conll_export/El resultado es un token por línea con su etiqueta, con líneas en blanco entre oraciones. La opción tag_scheme escribe BIO, BIOES o IOB, con BIO como valor por defecto, así que ajústala a lo que espere tu código de entrenamiento antes de ejecutar la exportación.
Afinar las guías
Las reglas imprecisas producen decisiones divididas sobre el mismo span, así que vale la pena revisarlas mientras la prueba piloto todavía es pequeña. Repasa los casos difíciles con los anotadores antes de que empiecen y no después, y mantén una lista compartida de casos límite resueltos a medida que aparezcan. Una caída del acuerdo entre anotadores es la señal de que una regla necesita ajustarse, y detectarla en 50 elementos cuesta menos que en 5000.
Próximos Pasos
- Agrega una fase de entrenamiento para preparar a los anotadores antes de que toquen elementos reales
- Configura múltiples anotadores para poder comparar los spans
- Exporta al formato de Hugging Face para entrenar modelos
- Lee la documentación de anotación de spans para ver la lista completa de opciones