Quant Memo
Core

Entity Resolution When Identifiers Do Not Match

Joining two datasets is easy when they share a clean identifier and genuinely hard when they do not, because tickers get reused and company names drift.

Prerequisites: Profiling a Raw Feed: Rows, Keys and Nulls

Two datasets both describe "Meta Platforms." One tags it FB, the other META, and a third, older file still calls it "Facebook Inc." A ticker can also point at two entirely different companies a decade apart, once the original filer delists and a new one recycles the symbol. Entity resolution is the work of deciding, row by row, which real-world company each record actually refers to, so two datasets can be joined without silently merging the wrong things or dropping the right ones.

The safest join key is one that is both unique and stable through time — a permanent security identifier, not a ticker or a name — and even those need care, because vendors do not all define "the same company" identically around spin-offs and mergers.

Why the obvious key breaks

Tickers are reused after delisting. Company names get abbreviated, punctuated, or translated differently across vendors ("J.P. Morgan" vs "JPMorgan Chase & Co"). CUSIPs and ISINs change on corporate actions. None of this is malicious — each vendor built their identifier scheme for their own purposes — but it means a naive join on ticker or name will silently produce two failure modes: false matches, where unrelated rows get merged because a symbol coincided, and false non-matches, where the same company fails to link because the strings differ by a comma.

Vendor A ticker: META Vendor B name: "Facebook Inc" resolution layer permanent entity ID
A resolution layer sits between raw vendor identifiers and one internal, permanent entity ID that both datasets get mapped onto.

Worked example

A research desk joins a sentiment dataset (keyed by company name, scraped from news headlines) against a pricing database (keyed by a permanent security ID) for a universe of 2,000 names. A naive exact-string join on name matches only 1,140 rows — 57% — because the sentiment vendor writes "Alphabet Inc Class A" where the pricing database has just "Alphabet Inc." Adding a name-normalization step (stripping share-class suffixes, legal-entity abbreviations, and punctuation) before matching lifts the match rate to 1,860 rows, 93%. The remaining 140 unmatched names are checked manually and turn out to be a mix of genuinely absent coverage and three cases where the same ticker had been reused by a different company after a 2019 delisting — those three are excluded rather than force-matched.

What this means in practice

Build the mapping table once, review it, and reuse it — do not re-resolve entities inside every research script, because each ad hoc join makes a slightly different set of matching decisions and no two studies end up comparable.

A high match rate is not the same as a high match accuracy. Fuzzy string matching will happily produce a 99% match rate by pairing unrelated companies with similar names; always spot-check a random sample of matches by hand, not just the unmatched leftovers.

Related concepts

Practice in interviews

Further reading

  • Christen, Data Matching: Concepts and Techniques for Record Linkage, Entity Resolution, and Duplicate Detection
ShareTwitterLinkedIn