Skip to content

feat(variants): spec 005, ASCII transliteration and variant group_id - #38

Merged
matbrgz merged 18 commits into
masterfrom
spec-005-variantes
Oct 12, 2026
Merged

matbrgz merged 18 commits into
masterfrom
spec-005-variantes

Conversation

@matbrgz

@matbrgz matbrgz commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Spec 005 (005-variantes): escrita, forma ASCII, capitalização, forma de exibição e agrupamento de variantes (group_id). Status da spec: Em implementação.

Spec: docs/specs/005-variantes/spec.md, com plano e tarefas. ADRs novos: 0010 (regras de agrupamento), 0011 (correspondência sem acento), 0012 (transliteração para ASCII).

O que mudou

  • Escrita (R1): detect_script trata letras de largura total e meia largura, 々 como han, ignora ー/ゝ/ヽ, devolve Jpan (han com kana), Hrkt (hiragana com katakana, ISO 15924) e Kore (hangul com han) e reconhece 20 escritas que eram Zzzz.
  • ASCII (R2, ADR 0012): NFKD mais tabelas do ICAO Doc 9303 (parte 3, seção 6, 8.ª ed.): latim (Dž, fi, ə, ŋ, ɔ) e cirílico (Иванов vira ivanov, Мария vira mariia). Apóstrofos e hífens tipográficos normalizados; casefold de novo depois da NFKD (™, ℳ, ℡, 𝓜 não geram maiúscula). Se um caractere não tem transliteração, ascii fica vazio (sem forma parcial). validate passa a exigir só ASCII sem maiúsculas.
  • Capitalização (R3): nas fontes de caixa uniforme, partículas em minúsculas fora da primeira palavra (Maria del Carmen, Van der Berg, Joana d'Arc); artigos só depois de partícula (Jia Le não muda); partícula na última palavra fica capitalizada (John Van).
  • Forma de exibição (R4): por país, só pesam as observações contadas (primary, edição e tipo escolhidos); no índice, votos de países, sem somar births com population; a caixa publicada vence a capitalização gerada.
  • Agrupamento (R5, ADRs 0010 e 0011): novo variants.py. Nós (kind, name_key) com observação; junção pela chave, ligações tratadas como não dirigidas, ligações com ponta sem observação ignoradas. Fase 1 por itens: os itens se juntam só por other_gender em sobrenomes, e cada nó entra no grupo dos seus itens (por same_item, origem de transliteração ou other_gender) só se todos já são um grupo; rótulo homógrafo de itens diferentes (장 de 张 e 蒋, Герман de dois itens) fica sozinho. Fase 2: transliteração e nome sem acento, só quando inequívocos e sem concorrência (destino que já é nome de outro grupo ou rótulo de outro item com nome na escrita da origem não é anexado: 見 -> 현 de 玄; Герман -> Herman/Hermanová entra quando Герман é de um item só). Romanização de han, kana ou hangul nunca se anexa a nome de outro grupo ou item (suk/suková e 术); transliterações de um grupo que chegam a dois ou mais grupos de outros nomes não se anexam (leque: Кінаш -> Kinach e Kinasz). different_from impede a junção. P460 não junta. Prenome e sobrenome nunca se juntam. group_id é o menor name_key do grupo.
  • strips_accents (R6): campo opcional em sources.yaml, true para StatCan (nota 7), INE (nota metodológica: "eliminando los acentos") e SSA (0 de 104.819 nomes fora do ASCII).
  • Contratos (R7): notas na spec 002 R1 (links(files), da spec 004 R4.1) e R2 (strips_accents), e na spec 001 R3/R5 (variant_links.parquet, group_id, ascii). cli._build monta a lista de fontes do manifesto com a união das fontes das observações e das ligações.
  • Versão (R8): SCHEMA_VERSION 1.2.0.
  • Memória (R9, issue Margem de memória do R8 com o Wikidata (3,43 GB de 4 GB) #31): o pico vinha de write_observations, que montava todas as colunas de uma vez. Agora a escrita vai em lotes de 250.000 linhas. tools/bench_pipeline.py --wikidata DIR inclui o Wikidata na medição.
  • CI: o passo das fontes oficiais confere group_id em todas as linhas de given_names.csv e family_names.csv.

Critérios de aceite e como foram verificados

  1. Escrita: tests/test_normalize.py::test_escrita_r1 (佐々木 Hani, ユーリ Kana, Anna Latn, さくら子 Jpan, 김金 Kore, ଦାସ Orya e outros).
  2. ASCII: test_forma_ascii_r2 e test_forma_ascii_vazia_quando_algum_caractere_nao_tem_transliteracao. No lote real, só 8 nomes latinos e 332 cirílicos (letras do cazaque, tártaro e tadjique) ficam com ascii vazio.
  3. Partículas: test_particulas_em_caixa_uniforme; o ES_CSV da CI agora traz Francesc d'Assis e Joana d'Arc.
  4. Forma de exibição: test_indice_nao_soma_births_com_population, test_por_pais_edicao_antiga_nao_pesa e test_forma_publicada_vence_a_capitalizacao_gerada.
  5. Grupos: 37 testes em tests/test_variants.py (Marie-Eve, 장 sem ponte entre 张 e 蒋, 見/현/玄, Герман/Herman/Hermanová, Иванов/Иванова/Ivanov, Paulo/Paula separados, Chen ambíguo, Ines ambíguo, different_from nas duas fases, tipos diferentes, P460, ligação sem observação, junção pela chave, independência da ordem e da direção, com transliteração e sem acento embaralhados).
  6. run --offline sobre as amostras: test_build_links_preenche_group_id, test_manifesto_lista_a_fonte_das_ligacoes, schema_version 1.2.0 e o passo da CI (tests/test_ci.py).
  7. strips_accents: tests/test_sources_extensoes.py.
  8. Medição (Apple M4, 24 GB, /usr/bin/time -l, pico de memória física; master e branch medidas nas mesmas condições):
    • Lote real completo (SSA, INSEE, CSO, SSB x2, StatCan, INE, DIA e Wikidata; 4.336.051 observações): master 3,35 GB; branch 2,89 GB, 176 s.
    • Sintético (3 milhões) mais Wikidata real (3.816.771 observações): master 3,47 GB; branch 2,79 GB, 125 s.
    • tools/bench_pipeline.py --wikidata (ingest e build em etapas): 87,6 s mais 78,0 s, pico de 2.881 MB, dentro dos limites.
    • Agrupamento no lote real (depois da segunda revisão): 8.195 grupos com variantes em prenomes (17.443 nomes, o maior com 18, todos rótulos de um mesmo item) e 27.224 em sobrenomes (64.112 nomes, o maior com 9). 2.310 rótulos homógrafos sem ponte; 2.820 transliterações anexadas (1.305 ambíguas, 27 concorrentes, 9 de CJK para outro item e 2 em leque de fora); 14.136 nomes sem acento anexados (3.099 ambíguos de fora); 241 junções puladas por different_from. Grupos com rótulos de itens diferentes, contando também os QIDs das origens de transliteração e sem contar other_gender: 87 prenomes e 59 sobrenomes (eram 186 e 273 antes desta rodada), quase todos o mesmo nome em itens duplicados de línguas diferentes ligados por cirílico -> latim (Алексей/Aleksei, Омельчук/Omelczuk, Родин/Родін/Rodin); dois prenomes têm rótulo CJK no próprio item (요셉, 威廉). Marie-Eve/Marie-Ève, Jose/José e Josee/Josée ficam juntos.
  9. uv sync e uv run pytest -q (748 testes) passam localmente; a CI roda neste PR.

Decisões tomadas sozinho (custo se estiverem erradas)

  • A P460 não junta nomes (ADR 0010). O fecho transitivo forma um componente de 14.039 nomes mesmo com os cortes da P1889, e um limite de grau não estabiliza. Custo: grafias ligadas só pela P460 (Ivanov/Iwanow, cognatos) ficam em grupos separados; quem precisar delas usa variant_links (Cognatos pela P460 (said to be the same as) sem componente gigante #37).
  • other_gender só junta sobrenomes. Custo: Paulo/Paula não se agrupam; se a intenção for agrupá-los, basta mudar a tabela FASE_1 e subir a versão menor.
  • Rótulo homógrafo não faz ponte e anexação só quando inequívoca e sem concorrência (revisão do PR feat(variants): spec 005, ASCII transliteration and variant group_id #38). Custo: 2.310 rótulos homógrafos ficam sozinhos; 1.305 romanizações ambíguas, 38 transliterações concorrentes, de CJK ou em leque e 3.099 nomes sem acento ambíguos (Ines entre Inès e Inés; Ivanov do russo e do ucraniano) ficam sem grupo.
  • SSA marcada com strips_accents só pela medição, sem documento da SSA. Custo: se algum nome não tem acento por escolha da família, ele se junta à forma acentuada, o que ainda é variante do mesmo nome.
  • Transliteração do qualificador P1705 não foi restrita no adaptador. O resultado não muda, porque os rótulos do mesmo item já estão no mesmo grupo pela fase 1.
  • group_id = menor name_key do grupo. É legível e determinístico, mas muda entre releases quando entra um nome com chave menor.
  • Cirílico pelo ICAO, sem exceções por língua, e ascii vazio quando falta transliteração. Custo: ucraniano Г vira g; nomes com letras fora das tabelas ficam sem ascii.
  • Forma de exibição no índice por votos de países, e não por soma de contagens.
  • Concorrência na fase 2 pela escrita: o revisor pediu que um grupo de destino não trivial diferente do de origem conte como candidato concorrente; aplicado ao pé da letra, isso também bloquearia Герман -> Herman (grupo latino com Hermanová). A regra implementada só bloqueia quando o grupo ou item do destino tem um nome na escrita da origem. Na segunda revisão, romanização de CJK passou a nunca se anexar a nome de outro item, e cirílico -> latim continua juntando entre itens. Custo se errado: itens duplicados de línguas diferentes (russo e ucraniano) continuam juntos pela transliteração.
  • ISO 15924 seguida para kana: hiragana com katakana sem han é Hrkt, e não Jpan; 々 e 〆 contam como han pela propriedade Script do Unicode.
  • Escrita das observações em lotes (ParquetWriter): o arquivo passa a ter vários grupos de linhas, com o mesmo conteúdo.
  • Aviso para a mudança para BenchCommons/dataset-tool: esta spec acrescentou o campo opcional strips_accents em sources.py e a escrita em lotes em io.py. O conceito é de nomes, mas o registro de fontes vai mudar de repositório.

Issues

Revisão independente (rodadas de correções)

Commits 554bfc9 (agrupamento por itens e concorrência), 0aa499c (ASCII sem maiúsculas depois da NFKD, Hrkt, ー, partícula final) e 276792d (spec R1, R2, R3, R5, R8; ADR 0010; nota de group_id instável entre releases na spec 001; roadmap com 003e e 004 mescladas). Segunda rodada: c417a65 (homógrafos escondidos pela origem de transliteração, leque e romanização de CJK) e 6d5af76 (números de R5.8 e ADR 0010; R8 e o comentário de schema.py dizem que validate confere script por igualdade e ascii só como ASCII minúsculo). A spec R8 explica a 1.2.0: ascii pode ficar vazio em latim e name muda; ingest e build devem usar a mesma versão.

Closes #4
Closes #31

Criadas: #35 (transliteração de grego, hangul, kana e demais escritas), #36 (group_id em by_country e junções aplicadas), #37 (cognatos pela P460).

🤖 Generated with Claude Code

matbrgz and others added 12 commits October 12, 2026 14:44
…antes

Spec 005 e ADRs 0010 (regras de agrupamento), 0011 (correspondência sem acento) e 0012 (transliteração para ASCII); atualiza o roadmap.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…itas novas

Spec 005, R1 (issue #4).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Spec 005, R2 (issue #4; ADR 0012). Apóstrofos e hífens tipográficos normalizados; ascii vazio quando algum caractere não tem transliteração; validate passa a exigir só ASCII sem maiúsculas.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…forme

Spec 005, R3 (issue #4): Maria del Carmen, Van der Berg, Joana d'Arc; artigos só depois de partícula (Jia Le continua).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… e SSA)

Spec 005, R6 e R7.3 (ADR 0011); nota na spec 002, R2.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tadas

Spec 005, R4 (issue #4): por país pesa só o que a linha conta; no índice, votos de países; caixa publicada antes da gerada.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Spec 005, R5 (ADRs 0010 e 0011): same_item e, em sobrenomes, other_gender; depois transliteração e nome sem acento só quando inequívocos; P460 não junta; group_id é a menor chave.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Spec 005, R5 e R7.4: name_index recebe fontes e ligações; cli._build usa a união das fontes das observações e das ligações.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ratos das specs 001 e 002

Spec 005, R7.1, R7.2, R8 e R10.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Spec 005, R9.3 e R9.4 (issue #31): o pico do run vinha da conversão de todas as observações para colunas de uma vez; tools/bench_pipeline.py ganha --wikidata.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@matbrgz matbrgz changed the title Spec 005: variantes, transliteração ASCII e group_id feat(variants): spec 005, ASCII transliteration and variant group_id Oct 12, 2026
matbrgz and others added 6 commits October 12, 2026 15:20
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…rom bridging items

Phase 1 now joins nodes through their Wikidata items: a label of items in different groups (장 of 张 and 蒋) stays alone. Phase 2 skips a transliteration whose destination is ambiguous or already belongs to another name in the source script (見 -> 현 of 玄), and an unaccented name already grouped elsewhere. Adds optional rule counters for the spec measurement.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…articles capitalised

ascii_form no longer returns capitals for ™, ℳ, ℡ or math letters, which failed validate and aborted the source. Hiragana with katakana is Hrkt; half-width ー is ignored; a particle in the last word stays capitalised (John Van). Explains the 1.2.0 bump in schema.py.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…view

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…JK readings on other items

A transliteration source counts as a label of its item, so a source under items of different groups (Герман) is a homograph. A group whose transliterations reach two or more groups of other names joins none of them (Кінаш -> Kinach, Kinasz). Han, kana and hangul romanisations never join a name of another group or item (suk/suková and 术). Cyrillic to Latin joins across items stay (Омельчук -> Omelczuk).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…the 1.2.0 note

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@matbrgz
matbrgz merged commit 0153007 into master Oct 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Margem de memória do R8 com o Wikidata (3,43 GB de 4 GB) Spec 005: escrita, transliteração e forma de exibição (pendências da 001)

1 participant