Phase 05 - Lesson 25

Vinculação e Desambiguação de Entidades

O NER encontrou "Paris". A vinculação de entidades decide: Paris, França? Paris Hilton? Paris, Texas? Paris (o príncipe troiano)? Sem a vinculação, seu grafo de conhecimento permanece ambíguo.

Tipo: Build Linguagens: Python Pré-requisitos: Fase 5 · 06 (NER), Fase 5 · 24 (Resolução de Correferência) Tempo: ~60 minutos

O Problema

Uma frase diz: "Jordan beat the press." Seu NER marca "Jordan" como PERSON. Ótimo. Mas qual Jordan?

  • Michael Jordan (basquete)?
  • Michael B. Jordan (ator)?
  • Michael I. Jordan (professor de ML em Berkeley — sim, essa confusão é real em artigos de ML)?
  • Jordan (o país)?
  • Jordan (nome próprio hebraico)?

A vinculação de entidades (EL) resolve cada menção para uma entrada única em uma base de conhecimento: Wikidata, Wikipedia, DBpedia ou sua KB de domínio. Duas subtarefas:

  1. Geração de candidatos. Dado "Jordan", quais entradas da KB são plausíveis?
  2. Desambiguação. Dado o contexto, qual candidato é o correto?

Ambas as etapas são aprendíveis. Ambas têm benchmarks. O pipeline combinado tem se mantido estável por uma década — o que muda é a qualidade do desambiguador.

O Conceito

Pipeline de vinculação de entidades: menção → candidatos → entidade desambiguada

Geração de candidatos. Dada a forma de superfície da menção ("Jordan"), busque candidatos em um índice de aliases. Os dicionários de aliases da Wikipedia cobrem a maioria das entidades nomeadas: "JFK" → John F. Kennedy, Jacqueline Kennedy, aeroporto JFK, JFK (filme). Um índice típico retorna de 10 a 30 candidatos por menção.

Desambiguação: três abordagens.

  1. Prior + contexto (Milne & Witten, 2008). P(entity | mention) × context-similarity(entity, text). Funciona bem, é rápido, não exige treinamento.
  2. Baseada em embeddings (ESS / REL / Blink). Codifique a menção + contexto. Codifique a descrição de cada candidato. Escolha o cosseno máximo. O padrão de 2020 a 2024.
  3. Generativa (GENRE, 2021; baseada em LLM, 2023+). Decodifica o nome canônico da entidade token a token. Restrita a uma trie de nomes de entidade válidos, de modo que a saída tem garantia de ser um id de KB válido.

Ponta a ponta vs pipeline. Modelos modernos (ELQ, BLINK, ExtEnD, GENRE) executam NER + geração de candidatos + desambiguação em uma única passagem. Sistemas em pipeline ainda dominam em produção porque você pode trocar componentes.

As duas medições

  • Recall de menção (geração de candidatos). Fração de menções de referência em que a entrada correta da KB aparece na lista de candidatos. É o piso de todo o pipeline.
  • Acurácia de desambiguação / F1. Dados os candidatos corretos, com que frequência o top-1 está certo.

Sempre relate ambas. Um sistema com 99% de desambiguação sobre 80% de recall de candidatos é um pipeline de 80%.

Construa

Passo 1: construa um índice de aliases a partir dos redirecionamentos da Wikipedia

alias_to_entities = {
    "jordan": ["Q41421 (Michael Jordan)", "Q810 (Jordan, country)", "Q254110 (Michael B. Jordan)"],
    "paris":  ["Q90 (Paris, France)", "Q663094 (Paris, Texas)", "Q55411 (Paris Hilton)"],
    "apple":  ["Q312 (Apple Inc.)", "Q89 (apple, fruit)"],
}

Dados de aliases da Wikipedia: ~18M de pares (alias, entidade). Baixe dos dumps do Wikidata. Armazene como índice invertido.

Passo 2: desambiguação baseada em contexto

def disambiguate(mention, context, alias_index, entity_desc):
    candidates = alias_index.get(mention.lower(), [])
    if not candidates:
        return None, 0.0
    context_words = set(tokenize(context))
    best, best_score = None, -1
    for entity_id in candidates:
        desc_words = set(tokenize(entity_desc[entity_id]))
        union = len(context_words | desc_words)
        score = len(context_words & desc_words) / union if union else 0.0
        if score > best_score:
            best, best_score = entity_id, score
    return best, best_score

A sobreposição de Jaccard é um brinquedo. Substitua por similaridade de cosseno sobre embeddings (veja o passo 2 em code/main.py para a versão com transformer).

Passo 3: baseado em embeddings (estilo BLINK)

from sentence_transformers import SentenceTransformer
encoder = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")

def embed_mention(text, mention_span):
    start, end = mention_span
    marked = f"{text[:start]} [MENTION] {text[start:end]} [/MENTION] {text[end:]}"
    return encoder.encode([marked], normalize_embeddings=True)[0]

def embed_entity(entity_id, description):
    return encoder.encode([f"{entity_id}: {description}"], normalize_embeddings=True)[0]

No momento de indexação, codifique cada entidade da KB uma vez. No momento da consulta, codifique a menção + contexto uma vez, faça o produto escalar contra o pool de candidatos e escolha o máximo.

Passo 4: vinculação generativa de entidades (conceito)

O GENRE decodifica o título da Wikipedia da entidade caractere a caractere. A decodificação restrita (veja a lição 20) garante que apenas títulos válidos possam ser gerados. Integração estreita com uma trie respaldada pela KB. O descendente moderno é o REL-GEN e a EL via prompt de LLM com saída estruturada.

prompt = f"""Text: {text}
Mention: {mention}
List the best Wikipedia title for this mention.
Respond with JSON: {{"title": "..."}}"""

Combinado com uma whitelist (o choice do Outlines), este é o pipeline de EL mais simples de colocar em produção em 2026.

Passo 5: avalie no AIDA-CoNLL

O AIDA-CoNLL é o benchmark padrão de EL: 1.393 artigos da Reuters, 34 mil menções, entidades da Wikipedia. Relate a acurácia in-KB (P@1) e a taxa de detecção de NIL out-of-KB.

Armadilhas

  • Tratamento de NIL. Algumas menções não estão na KB (entidades emergentes, pessoas obscuras). Os sistemas precisam prever NIL em vez de chutar a entidade errada. Medido separadamente.
  • Erros de fronteira de menção. O NER a montante perde spans parciais ("Bank of America" marcado apenas como "Bank"). O recall da EL cai.
  • Viés de popularidade. Sistemas treinados superestimam entidades frequentes. Uma menção a "Michael I. Jordan" em um artigo de ML muitas vezes é vinculada ao Jordan do basquete.
  • EL multilíngue. Mapear menções em texto chinês para entidades da Wikipedia em inglês. Requer um codificador multilíngue ou uma etapa de tradução.
  • Desatualização da KB. Novas empresas, eventos e pessoas não estão no dump da Wikipedia do ano passado. Pipelines de produção precisam de um ciclo de atualização.

Use

A pilha de 2026:

Situação Escolha
Inglês de propósito geral + Wikipedia BLINK ou REL
Multilíngue, KB = Wikipedia mGENRE
Amigável a LLM, poucas menções/dia Faça prompt no Claude/GPT-4 com lista de candidatos + JSON restrito
KB específica de domínio (médica, jurídica) BERT customizado com recuperação ciente da KB + fine-tune em conjunto de domínio no estilo AIDA
Latência extremamente baixa Apenas prior de correspondência exata (baseline Milne-Witten)
SOTA de pesquisa GENRE / ExtEnD / EL generativa por LLM

Padrão de produção que entra em produção em 2026: NER → correferência → EL em cada menção → colapsar clusters para uma entidade canônica por cluster. Saída: um id de KB por entidade no documento, não um por menção.

Entregue

Salve como outputs/skill-entity-linker.md:

---
name: entity-linker
description: Design an entity linking pipeline — KB, candidate generator, disambiguator, evaluation.
version: 1.0.0
phase: 5
lesson: 25
tags: [nlp, entity-linking, knowledge-graph]
---

Given a use case (domain KB, language, volume, latency budget), output:

1. Knowledge base. Wikidata / Wikipedia / custom KB. Version date. Refresh cadence.
2. Candidate generator. Alias-index, embedding, or hybrid. Target mention recall @ K.
3. Disambiguator. Prior + context, embedding-based, generative, or LLM-prompted.
4. NIL strategy. Threshold on top score, classifier, or explicit NIL candidate.
5. Evaluation. Mention recall @ 30, top-1 accuracy, NIL-detection F1 on held-out set.

Refuse any EL pipeline without a mention-recall baseline (you cannot evaluate a disambiguator without knowing candidate gen surfaced the right entity). Refuse any pipeline using LLM-prompted EL without constrained output to valid KB ids. Flag systems where popularity bias affects minority entities (e.g. name-clashes) without domain fine-tuning.

Exercícios

  1. Fácil. Implemente o desambiguador prior+contexto em code/main.py sobre 10 menções ambíguas (Paris, Jordan, Apple). Rotule manualmente a entidade correta. Meça a acurácia.
  2. Médio. Codifique 50 menções ambíguas com um sentence transformer. Faça o embedding da descrição de cada candidato. Compare a desambiguação baseada em embeddings com a sobreposição de contexto via Jaccard.
  3. Difícil. Construa uma KB de domínio com 1k entidades (por exemplo, funcionários + produtos da sua empresa). Implemente NER + EL ponta a ponta. Meça precisão e recall sobre 100 frases reservadas.

Termos-Chave

Termo O que as pessoas dizem O que realmente significa
Vinculação de entidades (EL) Vincular à Wikipedia Mapear uma menção para uma entrada única da KB.
Geração de candidatos Quem poderia ser? Retornar uma lista curta de entradas plausíveis da KB para uma menção.
Desambiguação Escolher a correta Pontuar candidatos usando o contexto e escolher o vencedor.
Índice de aliases A tabela de consulta Mapear da forma de superfície → entidades candidatas.
NIL Não está na KB Previsão explícita de que nenhuma entrada da KB corresponde.
KB Base de conhecimento Wikidata, Wikipedia, DBpedia ou sua KB de domínio.
AIDA-CoNLL O benchmark 1.393 artigos da Reuters com vínculos de entidade de referência.

Leituras Adicionais

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).