Skip to content

Add Scotland and Wales private-rent calibration targets#331

Open
MaxGhenis wants to merge 4 commits intomainfrom
codex/fix-316-country-rent-targets
Open

Add Scotland and Wales private-rent calibration targets#331
MaxGhenis wants to merge 4 commits intomainfrom
codex/fix-316-country-rent-targets

Conversation

@MaxGhenis
Copy link
Copy Markdown
Contributor

@MaxGhenis MaxGhenis commented Apr 12, 2026

Summary

This addresses #316 with a bounded target-side fix.

The root problem is not just sample size. Constituency calibration currently has no rent or tenure anchors at all, so Scotland and Wales can drift to implausibly low private-rent levels while still matching income, age, and UC targets.

This PR adds country-level Scotland and Wales anchors to the national objective used during constituency calibration:

  • private-rented stock targets for Wales and Scotland
  • linearised average private-rent constraints for Wales and Scotland
  • tenure compute support for Wales/Scotland private-renter targets

Target values

2025 private-rented stock targets:

  • Wales: 200,700
  • Scotland: 357,706

2025 average private rent anchors:

  • Wales: £795/month
  • Scotland: £999/month

Why this shape

This does not claim to solve within-country differentiation like Edinburgh versus rural Scotland. We still do not have constituency-level rent targets.

It also deliberately avoids country rent-spend targets, because those would conflict with the current rough UK-wide rent total target. Instead, the PR uses a linear average-rent constraint:

  • weighted private rent total
  • minus target average rent × weighted private-renter count
  • equals zero

That gives the optimizer the right signal without introducing a contradictory aggregate objective.

Sources

  • Wales dwelling stock estimates at 31 March 2024
  • Scotland stock by tenure 2023 workbook
  • ONS private rents bulletin, May 2025

Testing

Passed locally:

  • uvx ruff check policyengine_uk_data/targets/sources/devolved_housing.py policyengine_uk_data/targets/compute/households.py policyengine_uk_data/targets/compute/other.py policyengine_uk_data/targets/build_loss_matrix.py policyengine_uk_data/tests/test_devolved_housing_targets.py policyengine_uk_data/tests/test_target_registry.py
  • uv run pytest -q policyengine_uk_data/tests/test_devolved_housing_targets.py policyengine_uk_data/tests/test_target_registry.py policyengine_uk_data/tests/test_housing_targets.py

@MaxGhenis MaxGhenis requested a review from vahid-ahmadi April 13, 2026 03:25
Copy link
Copy Markdown
Collaborator

@vahid-ahmadi vahid-ahmadi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two items worth addressing:

  1. households.py refactor is a no-op — should be removed or completed

    The compute_tenure refactor changes _TENURE_MAP values to (string, country) tuples and generalises the lookup, but the map still only contains tenure_england_* keys. No Wales/Scotland entries are added, and no source module provides Wales/Scotland tenure targets. This function is used by the general target registry, not the constituency calibration path — so it's not exercised by anything new in this PR. Should either be removed from the PR or completed with actual new entries.

  2. Minor inconsistency: rent vs benunit_rent

    The existing local_authorities/loss.py:227-228 uses benunit_rent mapped to household level for its private rent targets. This PR uses rent (the household-level hhrent from FRS) directly. These could diverge for multi-benefit-unit households. Probably fine since the constituency path builds its own matrix, but worth a quick check that the same rent concept is intended.

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.

2 participants