Skip to content

Commit be3e06c

Browse files
MaxGhenisclaude
andauthored
Improve calibration weight initialization with country-aware divisors (#262)
* Improve calibration weight initialization for devolved nations Use country-aware initialization for calibration weights. Previously, each household's weight was divided by total area count (e.g., 650 for constituencies), causing Scottish households to start at ~9% of their target (59/650). Now weights are divided by areas in that household's country, so all countries start at ~100% of their targets. This should improve convergence speed and final accuracy for Scotland, Wales, and Northern Ireland specific targets like Scottish Child Payment. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Format with black --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 70ba4e0 commit be3e06c

3 files changed

Lines changed: 16 additions & 4 deletions

File tree

changelog_entry.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
- bump: patch
2+
changes:
3+
changed:
4+
- Improved calibration weight initialization to use country-aware divisors. Households now start with weights divided by the number of areas in their country rather than total areas, improving convergence for devolved nation targets.

policyengine_uk_data/utils/calibrate.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,18 @@ def calibrate_local_areas(
4646
m_n, y_n = m_national.copy(), y_national.copy()
4747

4848
# Weights - area_count x num_households
49+
# Use country-aware initialization: divide each household's weight by the
50+
# number of areas in its country, not the total area count. This ensures
51+
# households start at approximately correct weight for their country's targets.
52+
# The country_mask r[i,j]=1 iff household j is in same country as area i.
53+
areas_per_household = r.sum(
54+
axis=0
55+
) # number of areas each household can contribute to
56+
areas_per_household = np.maximum(
57+
areas_per_household, 1
58+
) # avoid division by zero
4959
original_weights = np.log(
50-
dataset.household.household_weight.values / area_count
60+
dataset.household.household_weight.values / areas_per_household
5161
+ np.random.random(len(dataset.household.household_weight.values))
5262
* 0.01
5363
)

uv.lock

Lines changed: 1 addition & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)