Skip to main content

What is an address?

Addresses look obvious — you see one every day — but parsingaddress 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. them turns out to be one of the harder problemsexpectation-maximizationAn iterative algorithm that estimates model parameters when some variables are unobserved. In Mailwoman's matcher, EM learns the Fellegi-Sunter m and u parameters from unlabeled data — no training labels needed. in natural language processing, because a single string can mean many places, and a single place can be written many ways.

This article defines what Mailwoman means by "address" and what data shape comes out of the parser.

The data model

Mailwoman modelsneural 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.' an address as a bag of typed components. Each component is a (tag, value) pair where the tag comes from a fixed vocabularyvocabularyThe fixed set of tokens a tokenizer can produce. Mailwoman's SentencePiece vocabulary is tens of thousands of subword pieces, with byte fallback for anything outside it.:

tagexample valuealways present?
country"United States", "USA", "FR"no
region"NY", "Île-de-France"no
subregion"Brooklyn", "Manhattan"no
locality"New York", "Paris"usually
dependent_locality"Greenpoint" (neighbourhood)no
postcode"10118", "75008"no
cedex"CEDEX 08" (FR-specific)no
street"5th Ave", "Rue Lafayette"when streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels.-level
house_number"350", "10 bis"when streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels.-level
venue"Wrigley Field", "Empire State Building"sometimes
unit"Apt 4B", "Suite 200"sometimes
po_box"PO Box 1234"sometimes
intersection_a, intersection_b"5th Ave", "42nd St"for intersectionsintersectionAn address that names a location by two crossing streets ('5th & Main') rather than a number and street. Mailwoman tags the two streets as intersection_a and intersection_b — a negative-space format that starved the early model.
attention"c/o Jane Smith"for postal mail

The full canonical vocabularyvocabularyThe fixed set of tokens a tokenizer can produce. Mailwoman's SentencePiece vocabulary is tens of thousands of subword pieces, with byte fallback for anything outside it. lives in core/types/component.ts. Adding a tag requires a written rationale because everything downstream is keyed off this list.

A parsed result is therefore a flat dictionary with optional repeated tags (rare; usually each tag appears at most once), not a tree. The exact shape:

interface ParsedAddress {
raw: string // the original input
components: {
[tag: ComponentTag]: string // the surface text from raw, not normalized
}
confidence: number // overall confidence, 0..1
source: "rule" | "neural" | "merged"
}

Why this is hard

A few properties of real-world addresses make parsingaddress 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. harder than it looks:

1. Components are optional and order varies.

350 5th Ave, New York, NY 10118
Pier 39, San Francisco, CA 94133
90210
"Wrigley Field, 1060 W Addison St, Chicago, IL 60613"
4 Rue Lafayette, 75008 Paris

All five are valid addresses. The first has six components, the third has one, the fifth puts the postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. before the localitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy.. A parser that demands a fixed structure misses most of the real input distribution.

2. The same string can be multiple components.

Buffalo, NY
Buffalo Wild Wings, Buffalo, NY 14201
Buffalo Buffalo (the famous Cornell sentence)

"Buffalo" can be a localitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. (Buffalo, NY), a venuevenueA named, non-address place — a business, building, park, or stadium. Mailwoman's free-text point-of-interest component, added as a Tier 2 fine label. (Buffalo Wild Wings has it in the name), an animal name, or even a verb. Context decides which. A rule that hardcodes "Buffalo = localitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy." is wrong in two of the three cases.

3. Multi-word components are common.

Saint Petersburg, FL
North Hollywood, CA
San Francisco, CA
New York, NY

A parser that labelscomponent 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. one 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. at a time has to decide that "Saint" and "Petersburg" go together. The first version of Mailwoman's neural classifierneural 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.' (v0.2.0) got "Saint Petersburg" wrong because the second 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.'s 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. was independent of the first — see BIO labels for the fix.

4. Spelling, capitalization, and punctuation vary.

1600 Pennsylvania Ave NW, Washington, DC 20500
1600 Pennsylvania Avenue Northwest, Washington, District of Columbia 20500
1600 pennsylvania ave nw washington dc 20500
1600 PENNSYLVANIA AVENUE NW, WASHINGTON DC 20500

Four ways to write the same address. The parser has to handle all of them, and 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. has to map all four to the same Who's On FirstWOF (Who's On First). An open-source gazetteer of places maintained by Mapzen/whosonfirst. Mailwoman builds a custom SQLite database from WOF GeoJSON repos, extended with postcode data, importance scores, and coincident-role relations. place ID.

5. Different localeslocaleThe combination of language and country an address comes from. en-US and fr-FR are the locales Mailwoman ships weights for. have different rules.

US addresses put the postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. after the regionregionThe first-level administrative subdivision of a country — a US state, a French region, a province. The component between country and locality.. French addresses put it before the localitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy.. Japanese addresses are essentially the reverse of European ones — 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. first, then prefecture, then municipalitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy., then a building number. Mailwoman's 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.' is trained on a combined multi-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. corpuscorpusThe BIO-labeled training data used to train Mailwoman's neural classifier. Assembled from real sources (OpenAddresses, National Address Database) and synthetic shards (boundary stress, order variants, negative space). Managed by @mailwoman/corpus. rather than a universal template, precisely because there is no universal address grammar; Japan today is 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.-route only, with no parser trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input. claim (see the scope declaration for the current localelocaleThe combination of language and country an address comes from. en-US and fr-FR are the locales Mailwoman ships weights for. tierstierInternal versioning of which label classes the model emits. Tier 1 is the coarse components (country, region, locality, postcode); Tier 2 adds venue, street, house_number; Tier 3 (future) would add attention, po_box, and POI venue subtyping. Historically called 'Stage 1/2/3' before the runtime-pipeline naming made that ambiguous.).

The adversarial cases

The Mailwoman team keeps a hand-labelled adversarial corpus of 54 entries that target known failure modes. A few examples:

categoryexamplethe trap
place-name-venuevenueA named, non-address place — a business, building, park, or stadium. Mailwoman's free-text point-of-interest component, added as a Tier 2 fine label.Buffalo Wild Wings, Buffalo, NY"Buffalo" appears twice with different roles
place-shaped-venuevenueA named, non-address place — a business, building, park, or stadium. Mailwoman's free-text point-of-interest component, added as a Tier 2 fine label.Empire State Building, 350 5th Avethe venuevenueA named, non-address place — a business, building, park, or stadium. Mailwoman's free-text point-of-interest component, added as a Tier 2 fine label. name has place-like words
disambiguationPortland, ME or Portland, OR?multi-stateregionThe first-level administrative subdivision of a country — a US state, a French region, a province. The component between country and locality. citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. names
typoPennsylvana Avemisspelled streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels.
no-commas1600 pennsylvania ave nw washington dc 20500no separators
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.-prefixAddress: 350 5th Aveleading metadata
trailing-junk350 5th Ave, NY (across from Macy's)trailing parenthetical

The neural classifierneural 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.' is trained against these cases (synthesized variations end up in the trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input. corpuscorpusThe BIO-labeled training data used to train Mailwoman's neural classifier. Assembled from real sources (OpenAddresses, National Address Database) and synthetic shards (boundary stress, order variants, negative space). Managed by @mailwoman/corpus. too), and each iteration's evalevalRunning the model against a held-out golden dataset and computing per-component F1, exact-match, calibration, and resolved-coordinate error. reports them separately so we can see if a regression specifically broke an adversarial category.

Where this lives in the code

  • core/types/component.ts — the canonical ComponentTag union
  • data/eval/golden/v0.1.2/ — the golden evaluationevalRunning the model against a held-out golden dataset and computing per-component F1, exact-match, calibration, and resolved-coordinate error. set, by file: us.jsonl, fr.jsonl, adversarial.jsonl
  • corpus/src/types.ts — the CanonicalRow shape that adapters produce

See also

  • Tokenization — how strings become tokenstokenOne 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. before parsingaddress 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.
  • BIO labels — how the neural classifierneural 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.' marks component boundaries
  • Resolver and Who's On First — turning parsed components into coordinates