euromod_linking.methods.lma_labour_alignment.weights¶
Weight-split exact alignment: select individuals (ranked by a score) until a weighted target is hit exactly, splitting the boundary household’s sample weight between a transitioning branch and a staying copy.
Economic intuition¶
Each survey row represents dwt real-world people (the grossing weight).
Macro targets are continuous, so after selecting whole persons the residual
gap is almost always a fraction of the next candidate’s weight — say 40% of
the 5,000 people a boundary person represents should enter employment. Rather
than over- or under-shooting the target, the split represents exactly that:
one branch of the household (40% of its weight) where the person transitions,
one copy (60%) where they don’t. The population total is unchanged — weight is
partitioned, never created.
Whole households are split, not individuals, because EUROMOD assesses taxes and benefits on complete household contexts (couple assessments, child benefits, household-level means tests). Splitting a person out of their household would simulate them against a truncated family and mis-price their taxes and benefits; copying the household keeps every branch fiscally coherent, at the cost of a few duplicated rows with rescaled weights.
Two properties the split must preserve, both easy to get wrong:
A household copy does not inherit the boundary person’s transition flag. The transitioning branch carries it, the staying copy does not — otherwise the boundary person transitions with their full weight and the target is overshot by exactly the fraction the split was meant to avoid.
When several boundary persons share one household, its weight is partitioned over all 2^k transition combinations (a product measure), so each boundary person’s transitioning weight is exactly
orig_weight * ratioand the total is conserved. Compounding the ratios onto a single copy conserves the total but gets the individual masses wrong.
Determinism: mergesort + idperson tie-break everywhere; new ids allocated in sorted split order.
Attributes¶
Functions¶
|
Apply all boundary splits. Each info must carry 'flag_col' — the |
|
Select candidates (sorted by prob_col, idperson tie-break) whose weights |
Module Contents¶
- euromod_linking.methods.lma_labour_alignment.weights.apply_boundary_splits(df: pandas.DataFrame, boundary_infos: list[dict]) pandas.DataFrame[source]¶
Apply all boundary splits. Each info must carry ‘flag_col’ — the transition-flag column its selection set (already 1 on the original row).
For a household with k boundary splits, the original rows become the all-transition stratum (
weight *= prod(ratios)) and 2^k - 1 copies cover the remaining combinations, with the flag zeroed for each staying boundary person. Total dwt is conserved to float precision.The 2^k enumeration is a product measure: with two boundary members whose transition shares are r1 and r2, the households this row represents divide into four subpopulations (both move, only one, only the other, neither) with weights
r1*r2,r1*(1-r2),(1-r1)*r2,(1-r1)*(1-r2)— treating the two members’ transitions as independent events. This is what makes each member’s transitioning mass exactlyw*r_iwhile household weight is only partitioned; compounding the ratios onto a single copy satisfies neither.
- euromod_linking.methods.lma_labour_alignment.weights.select_for_target(df: pandas.DataFrame, candidates_idx: pandas.Index, target_gap: float, ascending: bool, prob_col: str) tuple[pandas.Index, dict | None][source]¶
Select candidates (sorted by prob_col, idperson tie-break) whose weights cumulate to target_gap. Returns (selected row index, boundary_info | None); boundary_info marks the last person, whose weight must be split.
Walking the propensity ranking and taking cumulative weighted mass is the micro analogue of “the N most likely people transition”: the weighted count of movers — not the row count — is what must match the macro target, since each row stands for dwt real people.
- euromod_linking.methods.lma_labour_alignment.weights.RELATION_COLS = ('idfather', 'idmother', 'idpartner')¶