Skip to main content

Synonymy and homonymy — canonicalize, disambiguate, never drop a span

An address parser has to hold two facts at once that feel contradictory until you name them:

  1. The same place can be written many ways. "123 N Main St", "123 North Main Street", and "123 Main St N" are one location wearing three outfits.
  2. The same surface can mean different things. "Georgia" is a US stateregionThe first-level administrative subdivision of a country — a US state, a French region, a province. The component between country and locality. in Atlanta, Georgia and a countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. in Tbilisi, Georgia.

These are the two oldest axes of lexical semantics, and once you separate them the contradiction dissolves — they are orthogonal, and each has its own operation.

AxisPhenomenonOperationLives in
many surfaces → one referentsynonymysynonymyMany surfaces, one referent: '123 N Main St' and '123 North Main Street' are the same place. Handled by canonicalization, never by guessing which spelling is right. The dual of homonymy.canonicalizationcanonicalizationMapping a span to its canonical value: 'St' and 'Street' both become the USPS suffix ST; 'USA' and 'United States' both become ISO US. The operation that handles synonymy. Canonical values come from @mailwoman/codex, not a hand-grown alias list.parser + codex
one surface → many referentshomonymyhomonymyOne surface, many referents: 'Georgia' is a US state in 'Atlanta, Georgia' and a country in 'Tbilisi, Georgia.' Handled by disambiguation, split across two stages — the parser resolves the tag from in-string context; the resolver late-binds the referent with geographic context. (homographhomonymyOne surface, many referents: 'Georgia' is a US state in 'Atlanta, Georgia' and a country in 'Tbilisi, Georgia.' Handled by disambiguation, split across two stages — the parser resolves the tag from in-string context; the resolver late-binds the referent with geographic context.)disambiguationparser and resolverresolverThe component that converts parsed address components (locality, region, postcode) into coordinates by looking them up in the gazetteer. The resolver ranks candidates by name match, population, and proximity, and returns the best-matching place with its centroid or polygon.

Synonymy → canonicalization

SynonymysynonymyMany surfaces, one referent: '123 N Main St' and '123 North Main Street' are the same place. Handled by canonicalization, never by guessing which spelling is right. The dual of homonymy. is handled by mapping every spanspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree. to a canonical value, not by trying to guess which spelling is "right". "St" and "StreetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels." both canonicalize to the USPS suffix ST; "USA", "U.S.A.", and "United States" all canonicalize to the ISO-3166 code US. The canonical value comes from @mailwoman/codex (the provenance-tracked reference data), not from a hand-grown alias list that grows forever (see corpus poisoning for why the ever-growing exception list is a smell).

The payoff is that two records match when their spansspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree. canonicalize to the same values, regardless of surface. That gives the parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. a second use beyond geocodinggeocodingThe process of converting an address into geographic coordinates (latitude and longitude). Mailwoman geocodes in a multi-tier cascade: exact address-point match → street interpolation → locality centroid. Each tier is progressively coarser but more widely available.: it's a record-linkage primitive too — see "Never drop a spanspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree." below.

Homonymy → disambiguation, split across two stages

HomonymyhomonymyOne surface, many referents: 'Georgia' is a US state in 'Atlanta, Georgia' and a country in 'Tbilisi, Georgia.' Handled by disambiguation, split across two stages — the parser resolves the tag from in-string context; the resolver late-binds the referent with geographic context. is harder, because the right answer depends on context — and there are two kinds of context, which want two different homes.

  • Tag disambiguation — what kind of thing is this spanspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree.? ("Georgia" → country or region?) This is decidable from in-string context: "Atlanta" next to it tells you it is the stateregionThe first-level administrative subdivision of a country — a US state, a French region, a province. The component between country and locality.. So it belongs in the parser, and it is exactly what a context-sensitive neural tagger is for. The modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' resolves it; a lexicon can only inform the decision (a soft featurefeatureAn input signal a model conditions on. Beyond the raw tokens, Mailwoman feeds soft features — gazetteer-membership channels and the postcode anchor — that inform predictions without overriding them.), never make it — see closed-vocab fields are model-first.
  • Referent disambiguation — which specific entity? ("Springfield" → which of the 30-some?) This needs context that is not in the address string — a coordinate, a focus point, the administrative hierarchy. So it belongs in the resolverresolverThe component that converts parsed address components (locality, region, postcode) into coordinates by looking them up in the gazetteer. The resolver ranks candidates by name match, population, and proximity, and returns the best-matching place with its centroid or polygon., and it is exactly what concordance does: it brings gazetteergazetteerA geographical index that maps place names and postcodes to real-world coordinates. Mailwoman uses a custom-built Who's On First (WOF) SQLite database as its gazetteer — the 'atlas' half of the grammar/atlas architecture. knowledge into the decision after the parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates..

The clean rule: the parser disambiguates the tag using in-string context; the resolverresolverThe component that converts parsed address components (locality, region, postcode) into coordinates by looking them up in the gazetteer. The resolver ranks candidates by name match, population, and proximity, and returns the best-matching place with its centroid or polygon. disambiguates the referent using geographic context. Conflating them is how parsers end up either over-committing (guessing which Springfield from text alone) or under-committing (refusing to tag "Georgia" at all).

A note on scale, because it surprises people: there are ~195 countries, and the countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. tag still felt hard. The size is not the problem. ~180 countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. names collide with nothing and are trivial; the difficulty is the ~12 surfaces that overlap the other closed sets (Georgia/Jordan/Lebanon/Mexico/Peru/Turkey ↔ US places; CA/GA/IN ↔ stateregionThe first-level administrative subdivision of a country — a US state, a French region, a province. The component between country and locality. codes; Jordan/Chad ↔ given names). So "differentiate 195 countries" is "make ~12 binary sense calls against the other vocabularies", every one decidable from in-string context.

Never drop a span

Many geocoders' parsers are lossy by design: a spanspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree. that does not fit the winning interpretation is demoted to "accessory" information and folded into the resolverresolverThe component that converts parsed address components (locality, region, postcode) into coordinates by looking them up in the gazetteer. The resolver ranks candidates by name match, population, and proximity, and returns the best-matching place with its centroid or polygon.. That is fine if your only goal is "resolve to a point", and fatal the moment you want to do anything adjacent to geocodinggeocodingThe process of converting an address into geographic coordinates (latitude and longitude). Mailwoman geocodes in a multi-tier cascade: exact address-point match → street interpolation → locality centroid. Each tier is progressively coarser but more widely available. — chiefly record linkagerecord matchingThe process of determining whether two database records refer to the same real-world entity. Mailwoman's matcher uses a geocode-first approach (match the resolved place, not the address string) with Fellegi-Sunter probabilistic scoring.: deciding whether two rows from two datasets are the same entity.

Mailwoman's parser emits a labelcomponent tagOne of the 33 labels in Mailwoman's address schema — street, locality, region, postcode, house_number, unit, po_box, country, venue, intersection, and others. Each parsed span carries exactly one component tag. for every tokentokenOne word or subword in the tokenized input. For the neural classifier, tokens come from SentencePiece (subword units); for the rule classifiers, tokens are whitespace- and punctuation-separated words. — the BIO sequence covers the whole string, so nothing is silently eaten. The one trap is cosmetic: the JSON projection currently drops O runs (see eval discipline, "JSON hides gaps"), so unclassified material looks gone even though the parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. kept it. The fix is a typed unknown/other spanspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree. that survives projection. Then a parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. is a lossless, typed decomposition: every character accounted for — classified or explicitly-unclassified — each carrying a canonical value.

That decomposition is the record-linkage fingerprint. Two records are the same entity when their canonicalized spanspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree.-sets agree, surface variation and all. A geocoder front-end cannot give you that; a structured, lossless parser can. This is why the parser does address-understanding work of its own, rather than only feeding the resolverresolverThe component that converts parsed address components (locality, region, postcode) into coordinates by looking them up in the gazetteer. The resolver ranks candidates by name match, population, and proximity, and returns the best-matching place with its centroid or polygon..

Soft priors, not hard masks

Traditional parsers lean on positional masks (a field may only appear in slot N) and user hints (the query's origin countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head.) as hard filters. They have to — a rules enginerule-based classifierMailwoman's legacy v0 parser — a library of deterministic token classifiers (house number, street suffix, postcode, place name, etc.) composed by priority. Now primarily used for corpus labeling, fallback classification, and arbitration diagnostics. cannot read context, so it constrains the search space instead.

A modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' that reads context does not need the crutch, but the same signals are still useful — as soft priorssoft priorOutside knowledge fed to the model or resolver as overridable evidence (a feature, a score term) rather than a hard filter. A focus-country hint becomes an anchor feature; a focus-point becomes a ranking term., fed in as featuresfeatureAn input signal a model conditions on. Beyond the raw tokens, Mailwoman feeds soft features — gazetteer-membership channels and the postcode anchor — that inform predictions without overriding them. the modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' or resolverresolverThe component that converts parsed address components (locality, region, postcode) into coordinates by looking them up in the gazetteer. The resolver ranks candidates by name match, population, and proximity, and returns the best-matching place with its centroid or polygon. can overrule when the string says otherwise. A focus-countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. becomes a featurefeatureAn input signal a model conditions on. Beyond the raw tokens, Mailwoman feeds soft features — gazetteer-membership channels and the postcode anchor — that inform predictions without overriding them. for the parser's gazetteer anchor; a focus-point becomes a term in the resolverresolverThe component that converts parsed address components (locality, region, postcode) into coordinates by looking them up in the gazetteer. The resolver ranks candidates by name match, population, and proximity, and returns the best-matching place with its centroid or polygon.'s ranking. Same information as the mask, but as a preference the modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' can override, not a constraint it can't.

Two paradigms: parse-time vs index-time

Worth contrasting two whole philosophies, because each is internally coherent:

  • Parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates.-time structured tagging (Mailwoman, PeliasPeliasAn open-source geocoder, Mailwoman's spiritual predecessor., libpostallibpostalAn open-source C address parser used by Pelias. Mailwoman's rule-based v0 and neural classifier supersede it.) — commit a typed decomposition up front. Tag disambiguation happens now; referent disambiguation is deferred to the resolverresolverThe component that converts parsed address components (locality, region, postcode) into coordinates by looking them up in the gazetteer. The resolver ranks candidates by name match, population, and proximity, and returns the best-matching place with its centroid or polygon.. You get a lossless structure suitable for record linkagerecord matchingThe process of determining whether two database records refer to the same real-world entity. Mailwoman's matcher uses a geocode-first approach (match the resolved place, not the address string) with Fellegi-Sunter probabilistic scoring..
  • Index-time disambiguation (Airmail) — do not parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates.; index every tokentokenOne word or subword in the tokenized input. For the neural classifier, tokens come from SentencePiece (subword units); for the rule classifiers, tokens are whitespace- and punctuation-separated words. and let retrieval + geographic proximity (S2 cells) decide at query time. Elegant for "give me a point", and it also never drops a tokentokenOne word or subword in the tokenized input. For the neural classifier, tokens come from SentencePiece (subword units); for the rule classifiers, tokens are whitespace- and punctuation-separated words. — but it never hands you the clean typed decomposition, so record linkagerecord matchingThe process of determining whether two database records refer to the same real-world entity. Mailwoman's matcher uses a geocode-first approach (match the resolved place, not the address string) with Fellegi-Sunter probabilistic scoring. is off the table.

The index-time camp gets two things right: information-preservation (never drop a tokentokenOne word or subword in the tokenized input. For the neural classifier, tokens come from SentencePiece (subword units); for the rule classifiers, tokens are whitespace- and punctuation-separated words.) and a geographic prior as evidence (proximity as a soft signal). We keep both — preservation via the lossless parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates., the geographic prior via the resolverresolverThe component that converts parsed address components (locality, region, postcode) into coordinates by looking them up in the gazetteer. The resolver ranks candidates by name match, population, and proximity, and returns the best-matching place with its centroid or polygon.'s concordanceconcordanceA joint-decode signal that rewards a parse whose spans form a consistent Who's On First parent-child chain and vetoes contradictory ones — a hard veto for conflicts, a log-space bonus for full agreement. — while keeping the structured parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. the index-time approach gives up. The trade is deliberate: we disambiguate the tag early (where in-string context is enough) and bind the referent late (where geographic context is needed), rather than collapsing both into the index.

The one-liner

Canonicalize for synonymysynonymyMany surfaces, one referent: '123 N Main St' and '123 North Main Street' are the same place. Handled by canonicalization, never by guessing which spelling is right. The dual of homonymy.; context-disambiguate the tag at parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. time; late-bind the referent at resolve time; and never drop a spanspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree. on the floor.