Skip to content

Anotação de Spans

Destaque e rotule trechos de texto no Potato para reconhecimento de entidades nomeadas, com cores por rótulo, atalhos de teclado, dicas de ferramenta e spans descontínuos.

A anotação de spans permite que anotadores selecionem e rotulem partes do texto, e é assim que tarefas de reconhecimento de entidades nomeadas (NER), etiquetagem morfossintática e destaque de texto são construídas no Potato. Um rótulo é escrito como uma string simples ou como um objeto com seus próprios color, key_value e tooltip. O Potato lê esses três como propriedades de cada rótulo, então um mapa colors, key_values ou tooltips no nível do esquema não tem efeito em um esquema de span.

Interface de anotação de spans com destaque de entidadesAnotação de spans com rótulos de entidades codificados por cor no Potato

Configuração Básica

yaml
annotation_schemes:
  - annotation_type: span
    name: entities
    description: "Highlight named entities in the text"
    labels:
      - PERSON
      - ORGANIZATION
      - LOCATION

description é obrigatório em todo esquema e aparece acima dos botões de rótulo como a instrução que o anotador lê, por isso deve enunciar a decisão de rotulagem em vez de repetir o nome do esquema. Rótulos escritos como strings simples recebem suas cores da paleta do Potato na ordem em que são listados.

Opções de Configuração

Rótulos de Entidade

O conjunto de rótulos é a principal decisão de projeto em uma tarefa de spans, porque a revocação, a concordância e todas as medições posteriores são definidas em relação a ele. Mantenha-o pequeno o bastante para que os anotadores o guardem de memória sem consultar as diretrizes a cada span, o que na prática significa de quatro a oito tipos para a maior parte do trabalho de NER. Adicione os rótulos ao esquema acima:

yaml
labels:
  - PERSON
  - ORGANIZATION
  - LOCATION
  - DATE
  - EVENT

Cores

O Potato atribui a cada rótulo uma cor da paleta na ordem da lista, então só vale a pena escrever as cores quando uma combinação específica importa, como dois tipos que aparecem com frequência na mesma frase e não devem ser fáceis de confundir à primeira vista. A cor pertence ao rótulo:

yaml
annotation_schemes:
  - annotation_type: span
    name: entities
    description: "Highlight named entities in the text"
    labels:
      - name: PERSON
        color: "#3b82f6"
      - name: ORGANIZATION
        color: "#10b981"
      - name: LOCATION
        color: "#f59e0b"
      - DATE

Os valores são hexadecimais (#3b82f6) ou rgb(255, 0, 0). Um rótulo deixado como string simples, como DATE acima, fica com a próxima cor da paleta, então um esquema pode definir cores para os rótulos que precisam delas e deixar o restante como está.

As cores de vários esquemas também podem ser definidas em um só lugar, em ui.label_colors, indexadas pelo nome do esquema e depois pelo rótulo:

yaml
ui:
  label_colors:
    entities:
      PERSON: "#3b82f6"
      ORGANIZATION: "#10b981"

Um mapa colors: escrito no próprio esquema não é uma chave que o Potato lê. Um esquema que o contenha é renderizado com as cores da paleta, como se o bloco não existisse.

Atalhos de Teclado

Vale a pena habilitar atalhos em qualquer tarefa de spans com mais de dois rótulos, porque um anotador que leva o mouse até um botão a cada span trabalha a uma fração da velocidade de quem mantém as duas mãos no texto. Definir sequential_key_binding: true dá teclas aos rótulos na ordem em que são listados:

yaml
- annotation_type: span
  name: entities
  description: "Highlight named entities in the text"
  labels:
    - PERSON
    - ORGANIZATION
    - LOCATION
    - DATE
  sequential_key_binding: true

Quando uma tarefa tem vários esquemas na página, o Potato aloca para cada um teclas de um grupo separado, usando primeiro a fileira de números, depois a fileira superior de letras e depois a fileira central, de modo que atalhos de esquemas diferentes nunca colidem.

Para fixar um rótulo em uma tecla específica em vez de na sua posição na lista, atribua ao rótulo um key_value. O alocador respeita um key_value explícito antes de atribuir qualquer coisa automaticamente, e teclas mnemônicas sobrevivem a uma reordenação posterior da lista de rótulos, o que não acontece com as posicionais:

yaml
- annotation_type: span
  name: entities
  description: "Highlight named entities in the text"
  labels:
    - name: PERSON
      key_value: "p"
    - name: ORGANIZATION
      key_value: "o"
    - LOCATION
  sequential_key_binding: true

Um mapa key_values: no nível do esquema não é lido, nem um mapa escrito como valor de sequential_key_binding, que o Potato trata apenas como flag.

Dicas de Ferramenta

A dica de ferramenta é o lugar dos casos-limite de um rótulo, para que o anotador possa verificar o que conta como ORGANIZATION sem sair da tarefa. As dicas são propriedades de cada rótulo:

yaml
- annotation_type: span
  name: entities
  description: "Highlight named entities in the text"
  labels:
    - name: PERSON
      tooltip: "Names of people, characters, or personas"
    - name: ORGANIZATION
      tooltip: "Companies, agencies, institutions"
    - name: LOCATION
      tooltip_file: "config/tooltips/location.html"

tooltip recebe texto simples e tooltip_file recebe o caminho para um arquivo HTML, que é a melhor escolha quando a orientação precisa de exemplos, texto em negrito ou uma lista. Um mapa tooltips: no nível do esquema é lido apenas por hierarchical_multiselect e não faz nada em um esquema de span.

Spans Sobrepostos

Permitir Sobreposição

Spans podem se sobrepor, e nenhuma configuração liga esse comportamento. A sobreposição é o desejado quando um trecho de texto carrega dois rótulos ao mesmo tempo, como em "Dr. Smith", que é tanto PERSON quanto ROLE. Desde a versão 2.9.0, uma seleção que começa no fim de um span existente ou termina no início de um também é aceita, então é possível criar spans parcialmente sobrepostos. Versões anteriores recusavam essa seleção.

Desabilitar Sobreposição (Padrão)

O esquema de span não tem nenhuma chave que proíba a sobreposição, então uma tarefa em que os spans nunca devem se sobrepor precisa dizer isso nas suas diretrizes de anotação. Quando a distinção importa para a exportação e não para o anotador, dois esquemas de span mantêm os conjuntos de rótulos separados, já que cada esquema armazena seus spans sob o próprio nome:

yaml
annotation_schemes:
  - annotation_type: span
    name: entities
    description: "Label named entities"
    labels:
      - PERSON
      - ORGANIZATION
 
  - annotation_type: span
    name: roles
    description: "Label professional roles"
    labels:
      - ROLE

Modos de Seleção de Span

O Potato armazena cada span como deslocamentos de caractere no texto do item, e nenhuma chave de configuração alterna a seleção entre granularidade de palavra e de caractere. Os dois modos abaixo descrevem o que o anotador pode fazer, não configurações que você liga.

Seleção em Nível de Palavra

Arrastar sobre palavras inteiras é como a maior parte do trabalho de NER acontece na prática, e o resultado é armazenado como os deslocamentos do primeiro e do último caractere selecionados. Nada na configuração impõe limites de palavra, então, se spans de palavras inteiras importam para os seus dados, coloque o requisito nas diretrizes e verifique-o na exportação em vez de esperar que a interface recuse uma palavra parcial.

Seleção em Nível de Caractere

Selecionar parte de uma palavra está sempre disponível e não exige configuração, e é disso que dependem as tarefas morfológicas e abaixo do nível do token. O Potato reduz sequências de espaços e tabulações antes da renderização para que os deslocamentos armazenados correspondam ao que o navegador mede, e isso importa quando o seu texto tem indentação significativa. Declare instance_display quando o espaço em branco horizontal precisar ser preservado exatamente.

Spans Pré-Anotados

Iniciar uma tarefa com a saída de um modelo transforma a rotulagem em correção, que é o fluxo mais rápido sempre que um modelo já acerta a maior parte do corpus. O Potato lê as anotações iniciais de um campo de cada item, indicado por pre_annotation.field:

yaml
pre_annotation:
  enabled: true
  field: "predictions"
  allow_modification: true
  show_confidence: true
  highlight_low_confidence: 0.7

É allow_modification: true que torna a tarefa uma correção e não uma revisão, já que sem ele os anotadores não podem alterar o que o modelo propôs. highlight_low_confidence: 0.7 marca os itens sobre os quais o modelo estava menos seguro, para que a atenção vá para os spans com maior probabilidade de estarem errados.

O campo contém uma entrada por nome de esquema, e um esquema de span recebe uma lista de deslocamentos:

json
{
  "id": "item_002",
  "text": "Apple announced new iPhone in California.",
  "predictions": {
    "entities": [
      {"start": 0, "end": 5, "label": "ORG", "confidence": 0.85},
      {"start": 27, "end": 37, "label": "LOC", "confidence": 0.91}
    ]
  }
}

Pré-anotações são um ponto de partida, não uma anotação, então um item que ninguém abre é exportado vazio mesmo tendo chegado com previsões anexadas.

Configurações Comuns de NER

NER Padrão (4 Tipos)

O conjunto de quatro tipos segue a convenção do CoNLL-2003, que é a escolha certa quando seus resultados precisam ser comparáveis com números de NER publicados:

yaml
- annotation_type: span
  name: ner
  description: "Label named entities"
  labels:
    - PER    # Person
    - ORG    # Organization
    - LOC    # Location
    - MISC   # Miscellaneous
  sequential_key_binding: true

NER Estendido (Estilo OntoNotes)

Dezoito tipos trazem distinções mais finas a um custo real em concordância, já que as fronteiras entre NORP, ORG e GPE são onde os anotadores mais discordam. Use o conjunto estendido quando o trabalho posterior precisar dessas distinções, e reserve tempo para um treinamento mais longo:

yaml
- annotation_type: span
  name: ner_extended
  description: "Label named entities using the OntoNotes type set"
  labels:
    - PERSON
    - NORP        # Nationalities, religious/political groups
    - FAC         # Facilities
    - ORG
    - GPE         # Geopolitical entities
    - LOC
    - PRODUCT
    - EVENT
    - WORK_OF_ART
    - LAW
    - LANGUAGE
    - DATE
    - TIME
    - PERCENT
    - MONEY
    - QUANTITY
    - ORDINAL
    - CARDINAL

NER Biomédico

Spans biomédicos são longos e muitas vezes aninhados, então dicas de ferramenta com um exemplo resolvido para cada tipo compensam mais aqui do que em uma tarefa de domínio geral:

yaml
- annotation_type: span
  name: bio_ner
  description: "Label biomedical entities"
  labels:
    - GENE
    - PROTEIN
    - DISEASE
    - DRUG
    - SPECIES

NER de Mídias Sociais

Textos de mídias sociais trazem tipos de entidade para os quais os conjuntos de notícias jornalísticas não têm lugar, e CREATIVE_WORK e GROUP são os dois que mais acabam classificados erroneamente como ORG quando não têm rótulo próprio:

yaml
- annotation_type: span
  name: social_ner
  description: "Label named entities in social media text"
  labels:
    - PERSON
    - ORGANIZATION
    - LOCATION
    - PRODUCT
    - CREATIVE_WORK
    - GROUP

Span com Atributos

Um segundo esquema ao lado do esquema de span coleta um julgamento sobre o item como um todo. O Potato armazena os dois separadamente, então a resposta do radio se aplica ao documento, e não a um span específico:

yaml
annotation_schemes:
  - annotation_type: span
    name: entities
    description: "Highlight named entities"
    labels:
      - PERSON
      - ORGANIZATION
 
  - annotation_type: radio
    name: entity_type
    description: "What type of entity is this?"
    labels:
      - Named
      - Nominal
      - Pronominal

Múltiplos Esquemas de Span

Dois esquemas de span são a forma de anotar aspectos diferentes do mesmo texto sem obrigar os anotadores a manter em mente um único conjunto de rótulos combinado. Cada esquema tem sua própria fileira de botões, seu próprio grupo de teclas e seu próprio campo na exportação:

yaml
annotation_schemes:
  # Named entities
  - annotation_type: span
    name: entities
    description: "Label named entities"
    labels:
      - PERSON
      - ORGANIZATION
      - LOCATION
 
  # Sentiment expressions
  - annotation_type: span
    name: sentiment_spans
    description: "Highlight sentiment expressions"
    labels:
      - POSITIVE
      - NEGATIVE

Anotação de Span em Múltiplos Campos

Novo na v2.1.0

A anotação de spans pode ter como alvo um campo de texto específico em dados de múltiplos campos por meio da opção target_field, que é o necessário quando um item contém um documento de origem e um resumo e um span pertence a um deles.

Configuração

Cada esquema indica o campo que anota, de modo que os dois conjuntos de rótulos ficam ligados ao texto certo:

yaml
annotation_schemes:
  - annotation_type: span
    name: source_entities
    description: "Label entities in the source text"
    target_field: source_text
    labels:
      - PERSON
      - ORGANIZATION
 
  - annotation_type: span
    name: summary_entities
    description: "Label entities in the summary"
    target_field: summary
    labels:
      - PERSON
      - ORGANIZATION

Formato de Dados de Múltiplos Campos

Seus dados devem incluir os campos de texto separados:

json
{
  "id": "doc1",
  "source_text": "John Smith works at Microsoft in Seattle.",
  "summary": "Smith is employed by Microsoft."
}

Formato de Saída

Ao usar target_field, as anotações são indexadas por campo:

json
{
  "id": "doc1",
  "source_entities": {
    "source_text": [
      {"start": 0, "end": 10, "text": "John Smith", "label": "PERSON"},
      {"start": 20, "end": 29, "text": "Microsoft", "label": "ORGANIZATION"}
    ]
  },
  "summary_entities": {
    "summary": [
      {"start": 0, "end": 5, "text": "Smith", "label": "PERSON"},
      {"start": 22, "end": 31, "text": "Microsoft", "label": "ORGANIZATION"}
    ]
  }
}

Para um exemplo completo e funcional, veja project-hub/simple_examples/simple-multi-span/ no repositório do Potato.

Opções de Exibição

Mostrar Rótulo no Span

Por padrão, o Potato exibe o rótulo dentro de cada span destacado. Em um documento denso com muitos spans curtos, o texto dos rótulos sobrecarrega a frase, e show_span_labels: false mantém o texto legível enquanto a cor do destaque continua indicando o rótulo:

yaml
- annotation_type: span
  name: entities
  description: "Highlight named entities in the text"
  labels:
    - PERSON
    - ORGANIZATION
  show_span_labels: false

Estilo de Sublinhado

O esquema de span não tem chave para o estilo de destaque, e os spans são sempre renderizados com fundo colorido. Sublinhado e colchetes são opções do tipo de correferência, por meio de visual_display.highlight_mode, então uma tarefa que precise de um deles deve usar Cadeias de Correferência.

Formato de Saída

As anotações de span são salvas com deslocamentos de caractere:

json
{
  "id": "doc1",
  "entities": [
    {
      "start": 0,
      "end": 10,
      "text": "John Smith",
      "label": "PERSON"
    },
    {
      "start": 20,
      "end": 29,
      "text": "Microsoft",
      "label": "ORGANIZATION"
    }
  ]
}

Exemplo Completo: Tarefa de NER

item_properties indica os campos que o Potato lê para o id do item e seu texto, e uma configuração sem ele não inicia. Os cinco tipos de entidade recebem teclas da fileira de números por meio de sequential_key_binding, e o esquema radio no final registra um julgamento de dificuldade que depois ajuda a explicar onde a concordância caiu:

yaml
annotation_task_name: "Named Entity Recognition"
 
data_files:
  - data/documents.json
 
item_properties:
  id_key: id
  text_key: text
 
annotation_schemes:
  - annotation_type: span
    name: entities
    description: "Highlight and label all named entities"
    labels:
      - PERSON
      - ORGANIZATION
      - LOCATION
      - DATE
      - MONEY
    sequential_key_binding: true
    allow_discontinuous: false
 
  - annotation_type: radio
    name: difficulty
    description: "How difficult was this document to annotate?"
    labels:
      - Easy
      - Medium
      - Hard
 
output_annotation_dir: annotation_output
export_annotation_format: jsonl

Spans Descontínuos

Novo na v2.2.0

allow_discontinuous: true permite que o anotador selecione vários trechos de texto não adjacentes e os registre como um único span, que é o necessário para antecedentes divididos e constituintes descontínuos. Descontinuidade é algo diferente de sobreposição, e a chave não tem efeito sobre se dois spans podem cobrir os mesmos caracteres:

yaml
- annotation_type: span
  name: entities
  description: "Highlight named entities in the text"
  labels:
    - PERSON
    - ORGANIZATION
  allow_discontinuous: true

Com a opção ativada, o anotador mantém Ctrl pressionado no Windows e no Linux, ou Cmd no Mac, enquanto seleciona mais texto para adicioná-lo ao span atual. A saída traz um par de início e fim para cada segmento.

Integração com Vinculação de Entidades

Novo na v2.2.0

As anotações de span podem ser vinculadas a bases de conhecimento externas (Wikidata, UMLS ou APIs REST personalizadas) adicionando um bloco entity_linking ao esquema de span. A vinculação compensa o passo extra por span quando duas entidades compartilham a mesma forma de superfície e o rótulo sozinho não consegue distingui-las:

yaml
- annotation_type: span
  name: entities
  description: "Highlight and link named entities"
  labels:
    - PERSON
    - ORGANIZATION
    - LOCATION
  entity_linking:
    enabled: true
    knowledge_bases:
      - name: wikidata
        type: wikidata
        language: en
    auto_search: true
    required: false

auto_search: true executa a busca assim que um span é criado, o que economiza um clique em tarefas em que a maioria dos spans é vinculada. required: true recusa salvar um span sem vínculo, então deixe-o desligado a menos que se espere que toda entidade dos seus dados esteja na base de conhecimento. Quando a vinculação de entidades está habilitada, um ícone de link aparece na barra de controle de cada span, e clicar nele abre uma janela de busca. Veja a documentação de Vinculação de Entidades para todos os detalhes.

Boas Práticas

  1. Escreva cores nos rótulos que precisam delas e deixe a paleta cuidar do resto
  2. Coloque os casos-limite em tooltip ou tooltip_file, um por rótulo, e não na descrição do esquema
  3. Ative sequential_key_binding em qualquer esquema com mais de dois rótulos, e adicione key_value onde uma tecla mnemônica ajudar
  4. Defina a política de sobreposição nas diretrizes, já que o esquema não impõe nenhuma
  5. Inicie com pre_annotation em fluxos de correção, e mantenha allow_modification: true
  6. Mantenha o conjunto de rótulos pequeno e separe aspectos não relacionados em esquemas de span distintos

Leitura Complementar

Para detalhes de implementação, veja a documentação de origem.