Skip to content

Supply is_hbai_dependent_child from the FRS and move targets and imputations off the deprecated is_child/is_adult #486

Description

@MaxGhenis

Why

PolicyEngine/policyengine-uk#1896 replaces the generic is_child (age < 18) and is_adult (age >= 18) flags inside the UK model with each programme's legal definition and adds HBAI variables (is_hbai_dependent_child, is_hbai_adult, hbai_person_type). The generic variables stay as deprecated shims with their old formulas, so nothing in uk-data breaks. But each uk-data use should read the definition of the statistic it targets; age < 18 matches none of them. Separately, uk-data can now supply the exact HBAI dependent-child flag.

1. Supply is_hbai_dependent_child from the FRS

The FRS child table is exactly the HBAI dependent-child population. frs.py already separates adult and child records to derive is_parent (derive_is_parent_from_frs_microdata). Add pe_person["is_hbai_dependent_child"] = ~np.isin(person_id, frs["adult"].person_id). Once the dataset carries it, the model's claimant/partner and couple classification use the survey's own benefit-unit roles instead of the calculator fallback (which, for example, cannot tell a 16- or 17-year-old partner from a dependant). Add a test that every benefit unit has one or two non-dependants.

2. Calibration targets (currently computed with age < 18)

  • calibration/matrix_builder.py:127-136, datasets/local_areas/constituencies/loss.py:107-118, targets/compute/benefits.py:33-51 (UC households by number of children): Stat-Xplore counts children and young people under 20 declared in the UC household. Use is_child_or_qualifying_young_person_for_universal_credit (or an explicit (age < 20) & ~is_uc_claimant predicate named for the statistic).
  • targets/compute/benefits.py:54-99 (UC by family type and payment band): children as above; "couple" is a UC joint claim (is_couple, now the claimant-has-a-partner test), not "two people aged 18+" (family_type, deprecated).
  • targets/compute/benefits.py:114-163, targets/dwp.py:200-305 (two-child limit): use is_child_or_qualifying_young_person_for_universal_credit; change the Target metadata from is_child.
  • targets/compute/benefits.py:24-30 (Scotland UC with a child under 1): age < 1 alone.
  • targets/compute/demographics.py:71-76 and targets/compute/households.py:6-51 (census and ONS household types): the ONS/census dependent child is under 16, or 16-18 in full-time education with no partner or child in the household. Use a predicate named for that source, and build household types from it, not from family_type.
  • create_target_matrix catches exceptions and logs "Skipping target": add a test that fails if any registered target is skipped, so a broken predicate cannot silently drop targets.

3. Imputation predictors

  • ETB public services (imputations/services/etb.py) and VAT (imputations/vat.py): ETB's own child definition is the HBAI dependent child, so predict from household counts of is_hbai_dependent_child and is_hbai_adult, and use household_count_people as the per-person divisor. Retrain the cached models.
  • LCFS consumption (imputations/consumption.py) and WAS wealth (imputations/wealth.py): keep results with explicit age counts computed in uk-data (the LCF and WAS definitions differ; flag the gap) instead of the deprecated is_child/is_adult/num_children/num_adults.
  • Capital gains (imputations/capital_gains.py): adult_index (now explicitly "rank among household members aged 18 or over") is unchanged; switch to is_household_head if the reference person is intended.

🤖 Generated with Claude Code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions