Close-enough geocoding
Not every application needs sub-meter accuracy. For most applications, "in the right citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy." is close enough. A geocode that places a customer in the correct metropolitan area is sufficient for market analysis, sales territory assignment, and regional logistics. The coordinate needs to be useful for the task, not necessarily correct.
The approach
- Define your precisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1. requirement. Not "as accurate as possible." A specific distance that is sufficient for your use case. Market analysis: within the correct citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy.. Sales territory: within the correct ZIP code. Regional logistics: within the correct metro area. Last-mile delivery: within the correct block.
- Choose the cheapest geocoder that meets the requirement. CitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy.-level accuracy → localitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy.-only 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. (free, a few hundred lines of code). ZIP-level accuracy → 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.-only 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. plus a ZIP-to-centroid table (free, trivially updateable). Block-level accuracy → a 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. API (Google, geocode.earth — costs money but requires zero infrastructure).
- Stop. Don't optimize past your requirement. A geocode that is accurate to 5 meters when your application needs 5 kilometers is wasted engineering effort. The last 10% of accuracy costs 90% of the infrastructure.
This is the economic argument for "close enough" — the cost of higher precisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1. is not linear, and the value of higher precisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1. drops off sharply after you meet your application's requirement.
When it works
- Statistical aggregation. You're counting customers by citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy., not delivering packages to them. A geocode that places 1,000 customers in the Los Angeles metro area is statistically useful even if every individual coordinate is off by miles. The aggregate is correct even if the individuals are not.
- Market analysis. You're deciding where to open a new store. You need to know which ZIP codes have high customer density, not which buildings they're in. ZIP-level 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. answers this.
- Regional routing. A package bound for "Springfield" goes to the Springfield distribution center. The streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. address is for the last-mile carrier, not the regional sort. The regional sort only needs citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy.-level accuracy.
- You have a known address universe. A utility company with 500,000 service addresses. The addresses are already in a database. You don't need to geocode them — you need to verify that an input address matches one in the database. NormalizenormalizeStage 1 of the runtime pipeline: deterministic input preprocessing (Unicode NFC, punctuation normalization, whitespace collapse). Returns a NormalizedInput with an offsetMap that maps normalized positions back to the raw input.-to-match handles this.
- You can't get finer data anyway. WOFWOF (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.'s coordinate for a rural localitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. may be the best data available. The building doesn't exist in any 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.. The streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. is not mapped. The locality centroidlocality centroidThe representative centre point of a city or locality, used as a coarse coordinate when no exact address point is available — the coarsest tier of the geocode cascade. is the closest approximation that exists. Spending engineering effort on higher precisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1. would require new data collection, not better algorithms.
What you lose
- The last mile. A package placed at the ZIP centroid in rural Montana is 15 miles from the actual delivery point. The regional sort correctly routes it to the right post office, and the carrier who delivers it knows the route. The geocode was wrong, but the package arrived anyway, because the postal system's last mile is human, not algorithmic.
- The false confidence of high precisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1.. A coordinate with 8 decimal places looks authoritative and implies sub-millimeter accuracy, so the consumer trusts it. A coordinate with 1 decimal place (10-kilometer precisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1.) looks approximate, so the consumer treats it accordingly. The high-precisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1. coordinate may in fact be less accurate: the extra digits can be noise rather than signal, yet the consumer still trusts the precise-looking one more.
- The misuse case. You built a geocoder for market analysis. Someone uses it for delivery routing. The geocoder was "close enough" for its intended use case. It is catastrophically wrong for the unintended one. The geocoder has no way to signal its intended precisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1. level. The consumer has no way to know.
- The concentrated tail. 90% of your addresses geocode to within acceptable precisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1.. The 10% that don't are concentrated in rural areas, new construction, and informal settlements — the populations where precisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1. matters most and is hardest to get.
- The changing requirement. You built a geocoder for statistical aggregation. Two years later, the business wants delivery routing. The geocoder that was "close enough" is now wrong by an order of magnitude. Retooling to higher precisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1. requires rebuilding the 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. infrastructure.
Precision spectrum
Your application lives somewhere on this spectrum. Know where.
| PrecisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1. | Use case | Cheapest approach |
|---|---|---|
| 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.-level | Global market sizing | IP geolocation (free, built into every web framework) |
| StateregionThe first-level administrative subdivision of a country — a US state, a French region, a province. The component between country and locality./provinceregionThe first-level administrative subdivision of a country — a US state, a French region, a province. The component between country and locality.-level | Regional sales territories | StateregionThe first-level administrative subdivision of a country — a US state, a French region, a province. The component between country and locality. name → centroid lookup (a 50-row CSV) |
| County-level | US county-level statistics | ZIP → county crosswalk (free from Census) |
| CitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy.-level | Metro-area market analysis | LocalitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy.-only 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. (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. lookup, ~200K rows) |
| ZIP-level | Delivery zone assignment | 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.-only 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. (regex + centroid table) |
| Block-level | Last-mile delivery routing | Geocoding API (Google, geocode.earth) |
| Building-level | Address verification | Commercial service (SmartyStreets, Melissa Data) |
| Entrance-level | Emergency dispatch | Proprietary, expensive, jurisdiction-specific |
Each step down the spectrum costs roughly 10× more in infrastructure and engineering than the step above it. CitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy.-level 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. is a few hundred lines of code. Building-level 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. requires a commercial API or a neural parser plus a 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.. Entrance-level 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. requires proprietary data that doesn't exist for most of the world.
Pick the cheapest level that meets your requirement. Don't spend entrance-level money on a citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy.-level problem.
Where Mailwoman fits
Mailwoman targets the block-to-building level of the spectrum. The parser extracts streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. and building number components. 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. matches them against WOFWOF (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. and OSMOpenStreetMap (OSM). A community-curated global map database (ODbL-licensed) with addr:* tagged features and place hierarchies. A secondary corpus source and a source of street names. data to return building-level coordinates where available, 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.-segmentsegmentA punctuation-bounded chunk of the normalized input — the comma-separated parts of 'Portland, OR' — used to give downstream stages structural context. coordinates where not.
Mailwoman is not the right choice for citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy.-level or ZIP-level 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.. Those 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. are solved by simpler, cheaper approaches. Mailwoman is the right choice when you need finer precisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1. than a locality centroidlocality centroidThe representative centre point of a city or locality, used as a coarse coordinate when no exact address point is available — the coarsest tier of the geocode cascade. and can't or won't pay for a commercial API.
Mailwoman is also the right choice when you need to improve your precisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1. over time. The 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. pipelinestaged pipelineMailwoman's runtime architecture: a sequence of pure-function stages (normalize → query-shape → locale-gate → kind-classifier → phrase-grouper → classifier → decoder) connected by typed handoffs. Each stage is published as its own npm package. accepts new 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. data. 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. can be swapped for a better 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.. The parser improves with more data without changes to the downstream system. "Close enough" today at the block level can become building-level tomorrow with the same infrastructure.
See also
- The case for simple geocoders — the series overview
- Locality-only geocoding — the citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy.-level approach
- Postcode-only geocoding — the ZIP-level approach
- Falsehoods about geocoded precision and frontages — the precisionprecisionOf the spans the model labeled as a given tag, the fraction it got right. High precision means few false positives. Paired with recall to compute F1. assumptions that break geocoders
- The 90% trap — why the 10% tail costs more than the 90%