Postcodes and ZIP Codes
The question
The postcodepostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. looks like the easiest part of an address to work with. It is short, machine-readable and fixed in shape, and nearly every web form asks for it. Yet 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. by postcodepostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. produces some of the least accurate coordinates. This page explains why.
The analog
A postcodepostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. is a sorting instruction. It encodes a path through a postal network: the regional facility, the delivery office, the carrier routecarrier routeThe delivery path one postal carrier covers on a shift. A ZIP code is fundamentally a set of carrier routes, not a geographic polygon, which is why ZIP boundaries are fuzzy and shift over time.. It is written for the sorting machine and the carrier, and it encodes what they need in the order they need it.
The US structure runs from east to west. The first digit is "a general geographic area of the
nation, '0' in the east, moving to '9' in the west". The next two digits are regional areas, and the
final two are specific post offices (USPS). The five
digits therefore end at a post office instead of at a building. The +4 extension identifies something
smaller, and the Postal Service's own list of what it can identify is informative: "a side of a
streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. between 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., both sides of a streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. between 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., a building, a floor or
group of floors in a building, a firm within a building, 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. of boxes on a rural route, or a group
of Post Office boxesPO boxA numbered mailbox at a post office used as a delivery address instead of a physical street location. Mailwoman tags it as the po_box component; structurally the same family as a subpremise. to which a single USPS employee makes delivery"
(Domestic Mail Manual 602). Two further digits, added in
1991, extend the code to the individual delivery point.
Every item on that list is a unitunitA subdivision of a building — apartment, suite, floor — that refines a street address. Mailwoman's unit component; a designator plus identifier forms a subpremise. of delivery. None of them is a geographic shape.
The same idea, five ways
Other postal services solve the same problem with different alphabets and different levels of detail.
The UK splits the code into an outward half and an inward half, and the hierarchy has countable levels:
124 postcodepostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. areas, 3,118 districts, 12,463 sectors, and roughly 1.79 million live unitunitA subdivision of a building — apartment, suite, floor — that refines a street address. Mailwoman's unit component; a designator plus identifier forms a subpremise. postcodespostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one.. A
small-user unitunitA subdivision of a building — apartment, suite, floor — that refines a street address. Mailwoman's unit component; a designator plus identifier forms a subpremise. postcodepostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. covers about fifteen addresses and never more than a hundred
(ONS). At that level of
detail a UK postcodepostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. is close to a point. That is why SW1A 1AA behaves like an address in a geocoder
and 90210 does not.
Ireland went further. An Eircode has seven characters: a three-character routing key that identifies the post town, then a four-character unique identifier that "is unique to an address and its geographic location" (Eircode). Each code identifies one delivery point without interpolationinterpolationA geocoding technique that estimates a coordinate along a street segment based on the house number range. Used as the middle tier of Mailwoman's geocode cascade when exact address-point data is unavailable.. Before the system launched in 2015, Irish addresses had no postcodepostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. at all.
Canada alternates letters and digits (K1A 0B1): a forward sortation area, then a local delivery
unitunitA subdivision of a building — apartment, suite, floor — that refines a street address. Mailwoman's unit component; a designator plus identifier forms a subpremise.. The Netherlands uses four digits and two letters. France uses five digits whose first two are the
département. As a result, 06130 and 6130 are different places, and a system that stores postcodespostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one.
as integers loses the difference.
Why the polygon is somebody's approximation
Some data sources represent postcodespostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. as shapes, and each source defines its own limits. The US Census Bureau created ZIP Code Tabulation Areas because "ZIP Codes are stored as one component of discrete addresses tied to delivery points, including specific housing unitunitA subdivision of a building — apartment, suite, floor — that refines a street address. Mailwoman's unit component; a designator plus identifier forms a subpremise. locations. The result is a point-based dataset unsuitable for mapping …" (Census). The Bureau generalized census blocks into areas so that statistics keyed by ZIP Code could be mapped at all. The Bureau constructed these areas, and they are not Postal Service boundaries. The same page states that the Postal Service assigns ZIP Code ranges to regional post offices. Those offices then assign ZIP Codes to delivery routes.
The UK states the same limitation from the other direction: "postcodepostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. boundaries mostly do not align with other geographic boundaries," and they move as addresses are built and mail volumes change (ONS).
The errors therefore come from how postcodespostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. are defined, even when the data is correct. A rural code covers a route, and its centroid falls wherever the route's addresses average out. A box-only code centers on the post office instead of on the homes of the people who rent the boxes. A code that crosses a town line belongs to two municipalities and fits neither of their outlines.
What this costs a parser
This has two consequences for a parser, and they pull in opposite directions.
First, a postcodepostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. is strong evidence about a regionregionThe first-level administrative subdivision of a country — a US state, a French region, a province. The component between country and locality. and weak evidence about a point. Used as a constraint on where to look, it is valuable. Used as the answer, it produces coordinates whose error does not show in the output.
Second, a postcodepostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. shape does not identify a single 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.. Five digits match the US pattern, the
French pattern and part of the German one, so 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. of a bare 75001 is ambiguous.
Mailwoman's kind classifierkind classifierStage 2.5 of the runtime pipeline: categorizes the input into one of eight query kinds (structured_address, postcode_only, locality_only, intersection, po_box, landmark, poi_query, vague) so the coordinator can route to the right parsing strategy. reports that it received only a postcodepostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one..
Handle PO boxes and other edge kinds has a measured
table of where five bare postcodespostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. resolved without 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. scope. Four of them are US codes, and
none of those four resolved to the US. That page also shows the fix: scope the query by
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.. It also shows the remaining problem: scoping turns some wrong answers into no answer.
Related
- What an address is — the delivery point the code routes to.
- How mail gets delivered — the machines the code was designed for.
- Falsehoods about addresses — the postcodepostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. section, in one line each.
- Handle PO boxes and other edge kinds — what a bare postcodepostcodeThe country-specific postcode (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. does in the pipelinestaged pipelineMailwoman's runtime architecture: a sequence of pure-function stages (normalize → query-shape → locale-hint → kind-classifier → phrase-grouper → classifier → decoder) connected by typed handoffs. Each stage is published as its own npm package. today.