Skip to content

Score a sized UK local release's per-area representativeness (#1124 item G) - #1304

Draft
juaristi22 wants to merge 1 commit into
mainfrom
uk-local-representativeness-1124
Draft

juaristi22 wants to merge 1 commit into
mainfrom
uk-local-representativeness-1124

Conversation

@juaristi22

Copy link
Copy Markdown
Collaborator

Adds the per-area representativeness scorecard that #1124 item G asks for, as a tool that reads any finished sized UK local run. A sized release ships S, a selection of the pool's households with refitted weights, while the dense solution D weights every pool household. Calibration checks only the rows we bind. This asks whether, inside each constituency and local authority, S still looks like D on household characteristics no target binds.

Part of #1124 (item G). The pool profile and variables come from #1163's size-experiment scorecard, unchanged, so that harness can import them from here. Planned under #1278.

What it compares

  • Variables. Household size (capped at 6), tenure, the head's age band, the ONS household type and the income decile (cut at D's weighted income distribution), alone and in six joints: size × tenure, tenure × head age, size × decile, head age × decile, type × tenure and type × decile.
  • Distance. The total variation distance (TVD) of S's distribution from D's, per area. Beside it sits the noise null, the TVD a draw of S's effective sample size from D would show by chance, and their ratio. A ratio near one means S is as close to D as its own size allows.

How it reads a run

uk_runtime.representativeness.read_uk_local_run(run_dir) reads:

  • the problem and D (uk.full.dense/solution);
  • S (uk.full.size_refit/solution), on the pool rows the size receipt names;
  • the pool frame from the run's graph store.

Every artifact is checked against the run's evidence index, and the receipt's rows must be the refit solution's own households. A run without a size refit ships D itself, so it is reported as not applicable.

What it writes

tools/score_uk_local_representativeness.py --run-dir <run> --out <dir> writes two files. The tool refuses an --out inside the repository.

  • representativeness_by_area.csv: per grain, area and variable. It names areas and carries their support, so it stays private.

  • representativeness_summary.json: cross-area statistics only, beside the digests of the artifacts read:

    • the median and 90th-percentile TVD;
    • the median TVD-to-noise ratio;
    • the number of areas above a ratio of 2.

    Only areas where S rests on at least ten distinct source households are scored, and quantiles over fewer than ten scored areas are withheld. No area code, maximum or minimum appears (UKDS disclosure control).

Nothing in the build, its gates or the release changes. The first run is meant for the frozen pre-Budget build's run directory.

Not in this PR

Tests

packages/microcosm-build/tests/engine_free/uk/test_uk_local_representativeness.py has 9 tests, using a synthetic pool and a synthetic finished run written by test_support/microcosm_build/uk_local_representativeness.py. They check that:

  • D scored against itself gives zero distance in every area;
  • a tenure shift in one area shows there and nowhere else;
  • the noise null shrinks as the effective sample grows, and an empty S is not valid;
  • the summary scores only areas resting on ten or more sources, withholds its quantiles below the area minimum, and carries no area code or extreme;
  • the run reader returns D and S, returns nothing for a dense-only run and refuses a changed artifact;
  • the tool writes both files, refuses an --out inside the repository and reports a dense-only run as not applicable.

Locally: the new test file passes, tools/ci_test_plan.py verify is ok and ruff is clean on the edited files.

🤖 Generated with Claude Code

#1124 item G asks for a per-area representativeness scorecard, so that a
selection is judged on what it does to the joint distribution of each
area, not only on the rows it binds. #1163 built one inside the
size-experiment harness. This puts it on main as an after-the-fact tool
that reads any finished sized run, beginning with the frozen pre-Budget
build.

uk_runtime.representativeness reads D (uk.full.dense/solution) and S
(uk.full.size_refit/solution on the size receipt's pool rows, which must
be the solution's own households). Every artifact is checked against the
run's evidence index. In each constituency and local authority it
compares S with D on household size, tenure, the head's age band, the ONS
household type and the income decile, alone and in six joints. Each
comparison is a total variation distance beside its noise null, the
distance an ESS-sized draw from D would show by chance. The pool profile
and the variables are #1163's, unchanged, so that harness can import
them from here.

tools/score_uk_local_representativeness.py writes the per-area table to a
directory outside the repository; it refuses one inside. The summary
JSON keeps cross-area statistics only: median and 90th-percentile
distances, the median ratio and the count of areas above it. Only areas
where S rests on ten or more distinct source households count; quantiles
over fewer than ten such areas are withheld. No area code, maximum or
minimum appears. A dense-only run is not applicable. Energy distance is
left for later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant