Ability — Resolução de Entidades
Ability transforma registros confusos e sobrepostos em um conjunto limpo e rastreável de entidades. Ele funciona em cinco estágios e nunca destrói dados originais: cada registro mesclado mantém vínculos com os originais de onde veio.
Correspondência de registros é a matemática de comparação (o registro A corresponde ao registro B?). Resolução de entidades é o trabalho completo: correspondência, agrupamento de correspondências em entidades, pontuação de confiança e manutenção de proveniência. Faça o trabalho completo.
Antes de começar: a verificação de alinhamento
Solicitações confusas são normais. Leia erros de digitação e abreviações como intenção e nunca comente sobre ortografia. Antes do trabalho real, declare três linhas curtas para que o usuário possa corrigir o curso com baixo custo:
SAID: <o que o usuário literalmente pediu>
INFERRED: <o problema real a resolver>
ASSUMED: <a principal suposição que você está fazendo — faça no máximo uma pergunta se estiver realmente bloqueado>
Pule isso para perguntas rápidas; use quando você estiver prestes a processar dados ou projetar um pipeline.
O pipeline de 5 estágios
1. Perfil
Examine cada campo antes de fazer qualquer correspondência. Relate por campo: taxa de nulos, contagem de valores distintos, valores mais frequentes, padrões de formato e problemas de codificação (UTF-8 vs Latin-1). A criação de perfil mostra quais campos são confiáveis o suficiente para corresponder e quais valores são tão comuns (por exemplo, "Silva", "Rua Principal, 123") que a concordância significa pouco.
2. Padronizar
Normalize antes de comparar, ou as pontuações estarão erradas: minúsculas, remover pontuação, expandir abreviações (R. → Rua), analisar nomes em partes, normalizar números de telefone para dígitos, normalizar sufixos de empresas (S.A., Ltda., ME), e padronizar endereços (verificação postal quando disponível).
Dados reais desorganizados quase sempre também precisam de:
- Tabela de apelidos (Bob/Roberto, Magali/Margarida, Sasha/Alexandre, Patrícia/Patrícia) e iniciais ("J.") tratadas como compatíveis com qualquer nome começando com essa letra.
- Campos de nome trocados — compare também primeiro↔último invertido.
- Datas ambíguas — "04/05/1990" pode ser 4 de abril ou 5 de maio. Mantenha ambas as leituras e trate uma troca de dia/mês como uma correspondência parcial, não um conflito.
3. Bloquear
Comparar cada registro com todos os outros é N² — 1 milhão de registros significa ~500 bilhões de pares. O bloqueio compara apenas registros que compartilham uma chave. Use várias passagens com chaves diferentes para que um erro de digitação em um campo não esconda uma correspondência real:
- Sobrenome fonético (Soundex / NYSIIS) + ano de nascimento
- Prefixo do CEP + número da casa
- Últimos 4 de um ID + CEP
- Telefone ou e-mail
- Para dados com muito texto: MinHash LSH em conjuntos de tokens, ou embeddings + busca de vizinhos mais próximos (FAISS/HNSW)
Meça:
- Taxa de redução = 1 − (pares comparados ÷ todos os pares possíveis) — almeje > 99%
- Completude de pares = correspondências verdadeiras que caem em algum bloco ÷ todas as correspondências verdadeiras — almeje ≥ 95%
4. Pontuar — a cascata de 3 etapas
Execute as verificações baratas e certas primeiro e as caras apenas onde necessário.
- Determinístico: um ID único confiável concorda (ID nacional, CPF, número de conta, e-mail verificado) → correspondência.
- Fuzzy: sem correspondência de ID → compare campos com o algoritmo certo por campo (veja a tabela) e combine-os com pesos Fellegi-Sunter.
- Aprendizado de máquina / revisão humana: ainda ambíguo → um classificador (ex.: regressão logística nas características de similaridade dos campos) se houver dados rotulados, caso contrário, encaminhe para uma fila de revisão humana.
| Tipo de campo | Use |
|---|---|
| Nomes de pessoas | Jaro-Winkler (recompensa prefixos correspondentes), além de listas de apelidos |
| Nomes de empresas | Token sort ratio (ordem das palavras não importa) após limpeza de sufixos |
| Endereços | Levenshtein após padronização; número da casa e unidade devem concordar exatamente |
| IDs, telefone, e-mail | Exato após normalização |
| Texto longo | Jaccard / cosseno em tokens |
Fellegi-Sunter em resumo — para cada campo k:
- m = P(campo concorda | registros realmente correspondem) — quão confiável o campo é
- u = P(campo concorda | registros não correspondem) — com que frequência concorda por acaso
- peso de concordância = log2(m/u); peso de discordância = log2((1−m)/(1−u))
- pontuação total = soma dos pesos para o resultado de cada campo
Valores raros carregam mais evidência: concordar em "Lebowski" (u minúsculo) é muito mais forte do que concordar em "Silva". Use u específico do valor quando possível. Na prática: um nome completo raro mais uma data de nascimento exata é uma evidência forte mesmo quando endereço, telefone e e-mail mudaram (a pessoa se mudou); um nome comum mais data de nascimento não é.
Para pontuar pares, execute scripts/fs_score.py em vez de calcular manualmente — ele aplica
os pesos, converte a pontuação em uma probabilidade de correspondência dadas as probabilidades a priori, e atribui
a faixa de decisão. Execute python scripts/fs_score.py --help para uso.
Fórmulas completas, o exemplo resolvido e a estimativa de m/u (incluindo EM) estão em
references/methods.md; leia-o quando o usuário quiser a matemática ou precisar ajustar os pesos.
Duas armadilhas que a pontuação sozinha não pegará:
- Famílias. Gêmeos, cônjuges e colegas de quarto compartilham sobrenome, endereço e às vezes data de nascimento, então sua pontuação pode parecer uma correspondência quase certa. Se os primeiros nomes diferem (e não são apelidos um do outro) e contatos pessoais (e-mail, telefone) conflitam, mantenha-os separados ou envie para revisão — independentemente do que a pontuação diga.
- Valores placeholders. Datas como 2000-01-01 ou 1900-01-01, telefones como 555-0000 e e-mails como [email protected] são preenchimento, não evidência. A criação de perfil (estágio 1) deve sinalizar valores que se repetem suspeitamente; não dê peso a eles.
Faixas de decisão (ajuste em dados rotulados; estes são pontos de partida):
| Probabilidade de correspondência | Ação |
|---|---|
| ≥ 0.95 | Correspondência automática |
| 0.80 – 0.94 | Fila de revisão humana |
| < 0.80 | Não corresponde |
5. Mesclar — sobrevivência e registros dourados
Agrupe pares correspondidos em entidades (componentes conectados / agrupamento de grafo — cuidado
com cadeias onde AB e BC mas A≁C; divida esses para revisão). Para cada entidade, construa
um registro dourado escolhendo cada campo com uma regra declarada:
- Mais recente (timestamp mais recente) — para endereços, telefone
- Mais completo (não nulo, mais longo) — para nomes, descrições
- Fonte confiável (classificação do sistema) — para IDs, nomes legais
Nunca sobrescreva ou exclua originais. Armazene: ID do registro dourado → lista de IDs dos registros fonte, a regra que escolheu cada campo e a pontuação de correspondência que os uniu.
Validando resultados
Peça, ou ajude a construir, um pequeno conjunto rotulado (alguns centenas de pares marcados como correspondência/não correspondência). Relate precisão, recall e F1 nele, além da taxa de redução e completude de pares para o bloqueio. Limiares sem validação são palpites — diga isso quando não houver conjunto rotulado.
Marcas de evidência
Ao reivindicar um resultado, diga como você sabe:
- [DOC] — de uma especificação ou documentação, não executado
- [RAN] — executado nesta sessão
- [PASS] — verificado contra dados rotulados/teste
Revisão de checkpoint
Em trabalhos longos (aproximadamente a cada cinco turnos de trabalho, quando o usuário relata um erro, ou quando eles digitam "checkpoint" ou "dream"): pause o trabalho do projeto e revise brevemente seus próprios turnos recentes. Liste cada erro ou desvio das restrições declaradas pelo usuário, sua causa e a correção que você aplicará daqui em diante. Em seguida, retome. Mantenha a revisão fora dos entregáveis — é para a conversa, não para os dados ou documentos do usuário.
Saída para um trabalho de correspondência
Termine um trabalho concluído com:
ENTITIES: <registros de entrada> → <entidades resolvidas> (<duplicatas encontradas>)
BANDS: auto <n> | revisão <n> | não correspondem <n>
QUALITY: precisão <x> | recall <x> | F1 <x> (ou "não validado — nenhum conjunto rotulado")
FILES: <onde os registros dourados, crosswalk e fila de revisão foram salvos>
Privacidade
A correspondência frequentemente envolve dados pessoais. Processe localmente, não cole identificadores
em URLs ou serviços externos, e ao vincular entre organizações, sugira
vinculação com preservação de privacidade (codificação Bloom-filter de nomes, comparada com
similaridade Dice) — detalhes em references/methods.md.