Skip to content

feat(crossref): strip company legal forms and honorifics in entity dedup (#116) - #122

Merged
JordanCoin merged 2 commits into
mainfrom
feat/crossref-rigour
Oct 23, 2026
Merged

JordanCoin merged 2 commits into
mainfrom
feat/crossref-rigour

Conversation

@JordanCoin

@JordanCoin JordanCoin commented Oct 21, 2026 •

Copy link
Copy Markdown
Owner

Closes #116.

Crossref entity dedup now collapses company legal forms and person honorifics with a vendored, stdlib-only normalizer in openfoia/matching.py. No new dependency (rigour was dropped: it needs pyicu, which has no wheels and requires a system ICU library, breaking low-end and Windows installs).

dedup_key(name, entity_type):

  • NFKC normalize, casefold, punctuation to spaces, collapse whitespace
  • Organizations: strip one trailing legal form from a 63-entry list, multi-token forms first
    • US/UK: inc, incorporated, llc, l l c, ltd, limited, plc, corp, corporation, co, company, lp, llp, public limited company, limited liability company
    • Europe: gmbh, gmbh co kg, ag, kg, se, sa, s a, sas, sarl, srl, s r l, spa, s p a, bv, b v, nv, n v, oy, oyj, ab, as, a s, asa, aps, kft, sp z o o, sro, s r o, spol s r o, doo, d o o, ooo, jsc, pjsc
    • Latin America: ltda, s a de c v, sa de cv, s de r l, cia
    • Asia: pte ltd, pty ltd, pvt ltd, kk, sdn bhd, bhd, co ltd
  • Persons: strip leading mr, mrs, ms, dr, prof, sir, hon
  • A name that is only a legal form ("Inc.") keeps its key, never empty

Known limits: no transliteration (Cyrillic and Latin spellings do not merge) and no expansion ("Siemens AG" does not match "Siemens Aktiengesellschaft"). Fuzzy matching via nomenklatura stays phase 2.

Tests: tests/test_matching.py covers the Clearview acceptance case, Petrobras S.A./SA, Siemens AG vs Aktiengesellschaft (not merged), Dr. Jane Doe, bare "Inc.", same text across person/org (still merges, unchanged), and list ordering.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Wdqj51cPquyTRKmoJLQV6y

@JordanCoin
JordanCoin marked this pull request as draft October 21, 2026 15:43
@JordanCoin

Copy link
Copy Markdown
Owner Author

Held as draft for Jordan's decision: rigour pulls in pyicu, which has no wheels and needs system ICU + pkg-config (build failed here until PKG_CONFIG_PATH pointed at Homebrew icu4c). That is a rough install on Windows and on the $300 laptop the mission targets. Options: (a) merge as an opt-in extra with the ICU caveat documented, (b) drop rigour and vendor a short company-form list (the useful part is data, about 40 suffixes), (c) check whether an older rigour pinned to normality 2.x avoids pyicu. Fallback path is unchanged either way.

JordanCoin and others added 2 commits October 23, 2026 19:56
New openfoia/matching.py dedup_key(name, entity_type). With the optional
`match` extra (rigour>=2.5.0, also in `all`), organizations go through
rigour.names.normalize_name + remove_org_types and persons through
remove_person_prefixes + normalize_name, so "Clearview AI Inc.",
"Clearview AI, Ltd" and "CLEARVIEW AI LIMITED" collapse to one crossref
lookup. The legacy six-suffix strip still runs on rigour's output
because rigour keeps "co"; a name that is only a legal form keeps the
legacy key. Without rigour the key is byte-identical to the old inline
logic in _deduplicate_entities.

rigour depends on normality, which requires pyicu (sdist only, builds
against system ICU), so the install-extras hint names libicu-dev /
icu4c + pkg-config.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wdqj51cPquyTRKmoJLQV6y
…igour (#116)

rigour pulls in pyicu, which has no wheels and needs a system ICU library,
breaking the $300-laptop and Windows installs. dedup_key is now stdlib only:
NFKC + casefold, punctuation to spaces, then strip one trailing legal form
(63 entries, multi-token first) for organizations or leading honorifics for
persons. A name that is only a legal form keeps its key. No transliteration
and no expansion (AG does not match Aktiengesellschaft); nomenklatura is
phase 2. Removes the match extra and its install-extras entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wdqj51cPquyTRKmoJLQV6y
@JordanCoin
JordanCoin force-pushed the feat/crossref-rigour branch from 14795e4 to 207e26a Compare October 23, 2026 17:57
@JordanCoin JordanCoin changed the title feat(crossref): rigour name normalization for entity dedup (#116) feat(crossref): strip company legal forms and honorifics in entity dedup (#116) Oct 23, 2026
@JordanCoin
JordanCoin marked this pull request as ready for review October 23, 2026 17:57
@JordanCoin
JordanCoin merged commit 6917af3 into main Oct 23, 2026
7 checks passed
@JordanCoin
JordanCoin deleted the feat/crossref-rigour branch October 23, 2026 17:59
@JordanCoin JordanCoin mentioned this pull request Oct 23, 2026
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.

crossref: entity dedup and name matching via rigour (optional extra), nomenklatura xref later

1 participant