France — 100 addresses from the BAN
What ran
On 2026-08-04 we drew 100 addresses from the Base Adresse Nationale release dated 2026-05-18,
rendered each one twice, and geocoded all 200 strings against a local install: the base weightsparameterA single learned number inside a model — one weight or bias. Mailwoman's encoder has roughly 30 million of them; training is the search for good values. under
the fr-FR overlay, the 1.65 GB global candidate 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., and the French BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure. rooftoprooftopGeocoding precision at the building or parcel level — coordinates within a few meters — the highest tier of the geocode cascade. Sourced from address-point and situs data. shardshardA partial output file of the corpus build, written in Parquet format. The training pipeline streams shards row by row.. The
grading target is BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure.'s own coordinate for the row the address came from. There is no second
geocoder in this measurement and no third-party reference set — this compares the 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. against
the registerinput modeThe Decision-A register switch: 'fragmented' (human-typed fragments — feeds the evidence channels) vs 'formatted' (complete records — runs the trained absence identity). Explicit on CLI/API; per-endpoint defaults (batch→formatted, autocomplete→fragmented); kind-derived otherwise. the 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. reads.
That last sentence is the whole caveat, and it has a section of its own below.
Method
The panel is a committed file rather than a fresh draw, so a re-run on your machine grades the same
100 rows. fr-ban-sample.json was produced by a seeded pass over
BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure. rowids (seed 20260804, 1200 draws, one row kept per 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.), which is why the panel 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. 100
distinct postcodespostcodeThe 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. across 58 departments including Réunion, and why it is mostly rural: BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure. rows are
distributed like French addresses are, and France is mostly not Paris. One Paris row made it in.
Each row is rendered in two surface forms:
| Arm | Form | What it tests |
|---|---|---|
clean | 28 Avenue de l'Opéra, 75002 Paris | The canonical French order |
reordered | 75002 Paris, 28 Avenue de l'Opéra | The same 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. with 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. and commune in front |
Nothing about the target changes between arms. Only the order does.
Three numbers need their definitions stated before you read them:
- Distance is the great-circle distance from the returned coordinate to BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure.'s coordinate for that
row.
exactmeans within one meter, which on this panel means the 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. found the row itself. - Routed to 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. area means the returned coordinate is within 15 km of the centroid of the BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure. points sharing that 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.. French postcodespostcodeThe 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. are not one size — a Paris arrondissement 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. about 2 km, a rural 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. can 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. 20 — so this is a check against gross misrouting and not a 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. claim. 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. claim is the distance row above it.
- Tier is which artifact answered:
address_pointis the BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure. rooftoprooftopGeocoding precision at the building or parcel level — coordinates within a few meters — the highest tier of the geocode cascade. Sourced from address-point and situs data. shardshardA partial output file of the corpus build, written in Parquet format. The training pipeline streams shards row by row.,adminis the 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. centroid the cascade falls back to when the rooftoprooftopGeocoding precision at the building or parcel level — coordinates within a few meters — the highest tier of the geocode cascade. Sourced from address-point and situs data. probe finds nothing.
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. is pinned to FR. This panel is a French dataset run through a French 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., so it
measures resolution inside France and makes no claim about 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. disambiguation. The Belgian panel
is where that question gets asked, and it answers differently.
Numbers
Both arms, 100 rows each, from fr-ban-results.json:
| Measure | clean | reordered |
|---|---|---|
| Returned a coordinate | 100 | 100 |
| Within 1 km | 96 | 97 |
| Within 5 km | 100 | 100 |
| Within 25 km | 100 | 100 |
| Exact row (within 1 m) | 94 | 96 |
| Routed to 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. area | 100 | 100 |
| Median distance | 0 km | 0 km |
| 90th percentile distance | 0 km | 0 km |
| Worst distance | 4.612 km | 4.612 km |
Answered at address_point | 96 | 98 |
Answered at admin | 4 | 2 |
The two arms took 2,615 ms together, 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.' load excluded.
The reordered arm scores higher than the clean one, which is the opposite of what a robustness arm is built to show. Two rows explain the whole gap, and the mechanism is in 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.:
clean 98 Rue Clos du Village, 38150 Agnin → street parsed as "Rue Clos du"
reordered 38150 Agnin, 98 Rue Clos du Village → street parsed as "Rue Clos du Village"
clean 33 Avenue du Centre, 91440 Bures-Sur-Yvette → street parsed as "Avenue du"
reordered 91440 Bures-Sur-Yvette, 33 Avenue du Centre → street parsed as "Avenue du Centre"
In the canonical order 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 followed by a comma and then 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., and the trailing
common noun of 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. name is dropped from the 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.. Moved to the end of the string with nothing
after it, the same streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. name survives whole, the rooftoprooftopGeocoding precision at the building or parcel level — coordinates within a few meters — the highest tier of the geocode cascade. Sourced from address-point and situs data. probe finds its row, and the tier goes from
admin to address_point. The truncationtruncationCutting an input down to the max sequence length (or an LLM response to its token limit), discarding everything past the cap. is the defect; the reordering does not fix it so much as
avoid the position where it fires.
Losses
Six rows in the clean arm did not land on their own coordinate. Four of them also miss in the
reordered arm.
| Address | Distance | Tier | What 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. produced |
|---|---|---|---|
5 Place du Calvaire à Montsaon, 52000 Semoutiers-Montsaon | 2.630 km | admin | streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. Place du Calvaire |
4 Rue de la Mairie, 70000 Andelarre | 4.612 km | address_point | streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. Rue de la Mairie |
3 Rue Jean Jaurès, 54110 Dombasle-Sur-Meurthe | 3.724 km | address_point | streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. Rue Jean Jaurès |
1 Rue du Château d'Eau, 63800 Perignat-Sur-Allier | 0.563 km | admin | streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. Rue du Château |
33 Avenue du Centre, 91440 Bures-Sur-Yvette | 1.140 km | admin | streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. Avenue du |
98 Rue Clos du Village, 38150 Agnin | 0.407 km | admin | streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. Rue Clos du |
They are two defects wearing one number.
StreetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels.-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. truncationtruncationCutting an input down to the max sequence length (or an LLM response to its token limit), discarding everything past the cap., four rows. Rue du Château d'Eau loses d'Eau, Avenue du Centre loses
Centre, Rue Clos du Village loses Village, and Place du Calvaire à Montsaon loses its hamlet
qualifier. Each truncated 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. then fails the rooftoprooftopGeocoding precision at the building or parcel level — coordinates within a few meters — the highest tier of the geocode cascade. Sourced from address-point and situs data. probe and the cascade falls back to the admin
centroid, which is why all four answer at admin. The two that recover under reordering are listed
above; the other two miss in both arms.
Same-name streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. inside one 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., two rows. Rue de la Mairie and Rue Jean Jaurès are among
the most repeated streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels. names in France. Both rows answered at address_point, so the rooftoprooftopGeocoding precision at the building or parcel level — coordinates within a few meters — the highest tier of the geocode cascade. Sourced from address-point and situs data. probe
succeeded — it succeeded on the wrong row, in a neighboring commune sharing 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.. These are
the two largest errors on the panel, 4.612 km and 3.724 km, and they are the reason the worst-case
number is what it is. A rooftoprooftopGeocoding precision at the building or parcel level — coordinates within a few meters — the highest tier of the geocode cascade. Sourced from address-point and situs data. tier that answers confidently from the wrong commune is a worse
failure than one that declines, and the tier field does not distinguish them.
Both defects were found by this panel and neither is fixed here. They are recorded as measured.
Caveats
The circularity, stated plainly. The French rooftoprooftopGeocoding precision at the building or parcel level — coordinates within a few meters — the highest tier of the geocode cascade. Sourced from address-point and situs data. tier is the BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure.. mailwoman data pull fr
downloads a shardshardA partial output file of the corpus build, written in Parquet format. The training pipeline streams shards row by row. built from the same registerinput modeThe Decision-A register switch: 'fragmented' (human-typed fragments — feeds the evidence channels) vs 'formatted' (complete records — runs the trained absence identity). Explicit on CLI/API; per-endpoint defaults (batch→formatted, autocomplete→fragmented); kind-derived otherwise. this panel grades against, so a within-one-meter hit
means the 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. found the row it was looking for in the table it was looking in. The claim this
panel supports is "a French address that exists in BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure. resolves to its BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure. rooftoprooftopGeocoding precision at the building or parcel level — coordinates within a few meters — the highest tier of the geocode cascade. Sourced from address-point and situs data." — a statement
about 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. and routing, not about coordinate accuracy. It cannot tell you whether BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure.'s coordinate
for a building is correct, because it has no independent view of that building. An address absent
from BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure. is outside the panel entirely.
A 90th-percentile distance of 0 km is not a 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. claim. It is a consequence of the same circularity: 94 of 100 rows land on the exact source coordinate, so every percentile up to the 94th is zero by construction. Read the count of exact rows and the count of misses; the percentiles carry no information this panel earned.
The commune strings are accent-stripped. BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure.'s locality_norm column is lowercased and
unaccented by the shardshardA partial output file of the corpus build, written in Parquet format. The training pipeline streams shards row by row. builder, so the panel asks for Orleans where the commune is Orléans and
45140 Ingre where it is Ingré. Every row is affected. This makes the panel slightly harder than a
correctly-accented input set and it is not corrected, because unaccented input is what a keyboard
produces.
One row per 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. is a sampling decision with a cost. It buys geographic spread — 100 postcodespostcodeThe 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., 58 departments — and it removes the dense-urban repetition that a uniform draw over 26 million rows would have produced. A panel weighted toward cities would report different numbers, and we have not measured which way.
n = 100. This is a panel. It supports statements about these hundred addresses and about the two defects they exposed. It does not support a national accuracy figure for France, and none is claimed. Reading our numbers sets out the rest of the traps.
Reproduce
The script is fr-ban-panel.mjs, the panel is
fr-ban-sample.json, and the output above is
fr-ban-results.json verbatim, including a per-row record for
every address in both arms.
That file's versions block records what this run used: Mailwoman 8.7.0,
neural-weights-fr-fr@6.5.0 resolving to model.onnx, candidate-global-1026.db, and the BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure. shardshardA partial output file of the corpus build, written in Parquet format. The training pipeline streams shards row by row..
The script writes those from the resolved artifact paths rather than from a constant, so a re-run
stamps its own — which is how 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.' filename on this page changed without 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.' changing. It
used to read model-v401-base-step-060000-int8.onnx, 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.-side name a development symlink was
pointing at; the bytes are identical (md5 c968c24ad1a3e59658ff1d92c5720575) and every number below is
unchanged.
npm install mailwoman @mailwoman/neural @mailwoman/neural-weights-fr-fr \
@mailwoman/resolver @mailwoman/resolver-wof-sqlite @mailwoman/ban \
@mailwoman/core @mailwoman/spatial
mailwoman data pull candidate fr
node fr-ban-panel.mjs --data-root <DATA_ROOT> --out fr-ban-results.json
The two bundlesevidence bundleThe pair of retrieval-augmented input channels (street-type + locality-surface) that feed lexicon membership as soft per-token evidence alongside the text. Shipped in 6.7.0; trained natively from step 0 in the from-scratch base line. are about 8.6 GB together. run-all.sh does the pull and
runs both published panels in one pass.
To redraw the panel against a newer BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure. release rather than grading the committed one:
node fr-ban-panel.mjs --resample --data-root <DATA_ROOT>
The seed is a constant in the script, not a flag, because changing it changes which addresses are being reported on. A different BANBAN (Base Adresse Nationale). France's authoritative open national address register — the highest-quality training source for French addresses, with full component structure. release renumbers the rows and will produce a different panel from the same seed, which is why the sample is committed rather than drawn at run time.
Related
- Belgium — 30 addresses, three configurations — the same machinery in 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. with no rooftoprooftopGeocoding precision at the building or parcel level — coordinates within a few meters — the highest tier of the geocode cascade. Sourced from address-point and situs data. registerinput modeThe Decision-A register switch: 'fragmented' (human-typed fragments — feeds the evidence channels) vs 'formatted' (complete records — runs the trained absence identity). Explicit on CLI/API; per-endpoint defaults (batch→formatted, autocomplete→fragmented); kind-derived otherwise. and no localelocaleThe combination of language and country an address comes from. en-US and fr-FR are the locales Mailwoman ships weights for. of its own.
- Reading our numbers — resolve rate against 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., and the rest of the traps.
- Locales and tiers — what
frcovers and what it does not. - How close is close enough? — deciding the tolerance these distances should be read against.