Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions changelog.d/297-cps-educational-attainment.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
The US fiscal-refresh build can carry educational attainment as an auxiliary person column, `cps_educational_attainment`, beside the raw Census `A_HGA` it is classified from (microcosm#297; the student debt pilot, Project 2). `--cps-educational-attainment` joins each person to the pinned official CPS ASEC person member on (income year, `PERIDNUM`), checks the Census household, person and age identity, and never predicts or defaults a value; a support clone takes its source person's code. `--asec-attainment-source INCOME_YEAR=PATH` supplies local archives, and unmapped years are fetched and verified against the same pins.

The classes are the seven ACS S1501 population-25-and-over categories (less than 9th grade; 9th to 12th grade, no diploma; high school graduate or equivalency; some college, no degree; associate's, occupational and academic together; bachelor's; graduate or professional), plus `not_in_universe` under 15. The ACS PUMS `SCHL` map is defined and tested; the ACS-local lane does not read `SCHL` yet, and the stage refuses ACS-spine rows. The degree-ROI classes are `associates_degree` (two-year) and `bachelors_degree` (four-year) against the high-school baseline.

Provenance. `microcosm.data.stored_inputs.US_AUXILIARY_STORED_COLUMNS` flags the column as auxiliary (carried for conditioning and calibration, not consumed by rules) and joins the stored-input register.

Targets. The US target compiler binds ACS 1-year S1501 state cells for the population 25 and over (one per state and class) as person counts of the column (family `census_educational_attainment`, materializer `population_attainment`), and leaves the universe totals, the 18-to-24 universe and Puerto Rico unbound. The fiscal-refresh materializer counts them, and a frame without the column refuses rather than binding zeros. The pinned Chronicle feed carries no S1501 facts, so no release binds them until PolicyEngine/chronicle#347 merges and the US feed is re-pinned.

The receipt is `experiments/297-cps-educational-attainment-receipt.md`, run on Modal with `experiments/modal_297.py`.
46 changes: 46 additions & 0 deletions docs/us-fact-to-target.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,52 @@ binds them:
band. `experiments/940-state-agi-bands/` measures pre-calibration support
per state and band on the #982 fix's offline outputs.

### ACS S1501 state attainment cells bind on an auxiliary column (microcosm#297)

ACS population margins are raw survey quantities, so the doctrine above
admits them. The compiler still admits `census_acs` only at
congressional-district geography, with one exception:
`_acs_attainment_reference_from_fact` binds the ACS 1-year S1501 state
attainment record sets
(`census_acs.acs1_<year>.s1501.state_attainment_25_plus.<st>`, Chronicle
package `census/acs_s1501_state_2024`).

- **Which rows.** The population-25-and-over detail rows, one per state and
class, for the 50 states and DC. The universe totals stay unbound, because
Census PEP binds population by state and age. The 18-to-24 universe stays
unbound too: the ACS counts dormitory residents in the state of their
college, and the CPS counts them in their parents' household. Puerto Rico
is outside the model. A detail row whose category, age band or measure is
not the reviewed one raises.
- **The column.** Each row counts persons in its age band whose auxiliary
`cps_educational_attainment` class is the row's
(`microcosm.build.us_runtime.educational_attainment`; family
`census_educational_attainment`, materializer `population_attainment`).
The fiscal-refresh build writes the column with
`--cps-educational-attainment`. A frame without it refuses to materialize
the rows. The rows of one state differ only in their class, so the
congressional-district reconciliation rule in `fiscal_target_references.json`
matches on `educational_attainment_category` too.
- **Levels.** The rows bind as levels. ACS 1-year weights are controlled to
the Census population estimates, so their 25-and-over totals sit close to
the PEP totals the release already binds. The receipt measures the gap per
state (`experiments/297-cps-educational-attainment-receipt.md`). If it
grows, rebase the rows onto the bound state population, as the AGI bands
are.
- **Before they bind.** The CPS and the ACS split some college from
associate's degrees differently: on the published default the release
has fewer people with some college and more with an associate's degree
than S1501 in almost every state, and their sum is off by less than the
some-college cell alone. Binding the two cells separately would move weight
to settle a definition. The
`less_than_9th_grade` cells are also thin in small states. The receipt
measures both; the re-pin review decides whether to bind the seven cells
or merged ones.
- **Feed.** The pinned feed carries no S1501 facts. When the re-pinned feed
adds them, regenerate the parity manifest, which then declares
`census_acs.acs1_2024` compiled. A release that compiles them must also
run with `--cps-educational-attainment`.

## 4. Keep the exclusion register honest

`US_FISCAL_TARGET_SUPPORT_EXCLUSIONS` is keyed by `source_record_id` and its
Expand Down
103 changes: 103 additions & 0 deletions experiments/297-cps-educational-attainment-receipt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# microcosm#297 receipt: CPS educational attainment against ACS S1501

Generated 2026-10-22 by `experiments/build_297_attainment_receipt.py` at commit `e2621e231c6cbc62939711e7c967be314624f65c`, Modal run `20261022T171517Z-e2621e231` (`experiments/modal_297.py`). Machine-readable copy: `experiments/receipts/297-cps-educational-attainment-s1501.json`.

The build stage ran on the published release `populace-us-2024-spm-20260915` (166,321 persons, 57,240 households) at its calibrated weights. Every person joined its own Census member row; the signal gate passed. The S1501 facts are a **temporary draft input** (PolicyEngine/chronicle#347, unmerged): 676 facts, 357 compiled targets (51 states and DC x 7 classes, population 25 and over), 0 mismatches against the raw Census response, largest gap between a state's categories and its total 0.

## Classes

| Class | CPS ASEC `A_HGA` | ACS PUMS `SCHL` | Six-class view |
|---|---|---|---|
| `less_than_9th_grade` | 31-34 | 01-11 | less than high school |
| `9th_to_12th_grade_no_diploma` | 35-38 | 12-15 | less than high school |
| `high_school_graduate_includes_equivalency` | 39 | 16, 17 | high school or GED |
| `some_college_no_degree` | 40 | 18, 19 | some college, no degree |
| `associates_degree` | 41, 42 | 20 | associate's |
| `bachelors_degree` | 43 | 21 | bachelor's |
| `graduate_or_professional_degree` | 44, 45, 46 | 22, 23, 24 | graduate or professional |
| `not_in_universe` | 0 (Children) | blank, or under 15 | |

## National, population 25 and over (sum of the 51 state cells)

| Class | S1501 | Release | S1501 share | Release share |
|---|---:|---:|---:|---:|
| < 9th grade | 10.91M | 7.82M | 4.6% | 3.3% |
| 9th-12th, no diploma | 12.87M | 11.70M | 5.5% | 5.0% |
| High school or GED | 60.70M | 65.69M | 25.7% | 27.9% |
| Some college, no degree | 43.65M | 33.29M | 18.5% | 14.1% |
| Associate's | 20.85M | 26.24M | 8.8% | 11.1% |
| Bachelor's | 52.23M | 57.04M | 22.1% | 24.2% |
| Graduate or professional | 34.70M | 33.79M | 14.7% | 14.3% |

## State cells (357)

| Measure | Value |
|---|---:|
| Mean abs share error | 2.29 pp |
| 90th percentile abs share error | 5.21 pp |
| Max abs share error | 10.84 pp |
| Median abs level error | 15.3% |
| 90th percentile abs level error | 46.3% |
| Max abs level error | 83.3% |
| Fewest records in a cell | 4 |
| Fewest households in a cell | 3 |
| S1501 25+ total vs release 25+ population, median abs | 0.14% |
| S1501 25+ total vs release 25+ population, max abs | 3.94% |

Share error is the release's share of a state's population 25 and over in a class minus S1501's; level error compares counts.

### Classes the degree-ROI analysis uses

Two-year degree = `associates_degree`, four-year degree = `bachelors_degree`, each against the `high_school_graduate_includes_equivalency` baseline.

| Role | Class | Mean abs share error | Max abs share error | Median abs level error | Fewest records |
|---|---|---:|---:|---:|---:|
| baseline | `high_school_graduate_includes_equivalency` | 2.87 pp | 10.84 pp | 8.5% | 95 |
| two_year_degree | `associates_degree` | 2.45 pp | 7.29 pp | 19.2% | 21 |
| four_year_degree | `bachelors_degree` | 2.32 pp | 8.11 pp | 8.7% | 221 |

### Largest share errors

| State | Class | S1501 share | Release share | Error | Records |
|---|---|---:|---:|---:|---:|
| MS | High school or GED | 29.4% | 40.2% | +10.84 pp | 527 |
| MN | Some college, no degree | 19.2% | 9.3% | -9.88 pp | 230 |
| HI | Some college, no degree | 18.6% | 8.8% | -9.82 pp | 240 |
| MT | Some college, no degree | 22.7% | 13.3% | -9.41 pp | 218 |
| AK | High school or GED | 28.5% | 36.8% | +8.32 pp | 464 |
| ND | Some college, no degree | 21.7% | 13.4% | -8.31 pp | 178 |
| VA | Bachelor's | 24.1% | 32.2% | +8.11 pp | 718 |
| MD | Bachelor's | 23.2% | 31.0% | +7.86 pp | 545 |
| GA | Some college, no degree | 18.8% | 11.0% | -7.86 pp | 276 |
| ME | High school or GED | 29.5% | 37.0% | +7.50 pp | 471 |

### Reading the comparison

- **Some college against associate's is an instrument difference.** Nationally the release has 14.1% some college, no degree against S1501's 18.5%, and 11.1% associate's against 8.8%. The release is below S1501 on some college in 49 of 51 states and above it on associate's in 44. The gap has one sign almost everywhere, so it reads as a difference between the instruments rather than sampling: the CPS interviews by telephone or visit and offers occupational and academic associate's answers, the ACS is mostly self-response and includes group quarters (Census, "Educational Attainment Fact Sheet", https://www.census.gov/topics/education/educational-attainment/guidance/factsheet-acs-cps.html). Binding the two cells separately would move weight to settle a definition. Their sum is -2.1 pp off nationally (25.3% against 27.3%), less than the some-college cell alone; the merged rows below give the state spread.
- **Thin cells.** 13 cells have fewer than 30 records; 10 of them are `less_than_9th_grade`. The standalone calibration's largest weight ratio (131) is in LA. Merging the two classes below a diploma (the six-class view) thickens those cells.

| Merged row | Mean abs share error | Max abs share error |
|---|---:|---:|
| less_than_high_school | 1.73 pp | 6.44 pp |
| some_college_or_associates | 2.93 pp | 7.45 pp |

## Held out: population 18 to 24

Not compiled: the ACS counts college students in dormitories (group quarters) in the state of their college, the CPS in their parents' household.
Mean abs share error 6.81 pp, max 34.03 pp; mean signed error by category: less_than_high_school_graduate +2.43 pp, high_school_graduate_includes_equivalency -3.96 pp, some_college_or_associates_degree +2.82 pp, bachelors_degree_or_higher -1.28 pp.

## Standalone calibration to the cells

Per-state minimum-KL reweighting of the release's household weights to the seven 25+ cells, holding the state's population under 25 fixed. Not the release solve, which fits every target jointly; it shows what binding these cells alone asks of the weights.

| Measure | Value |
|---|---:|
| Max abs level error after | 0.0000% |
| Weight ratio, lowest state 1st percentile | 0.380 |
| Weight ratio, highest state 99th percentile | 5.944 |
| Weight ratio, min / max | 0.176 / 130.971 |
| Kish effective sample size kept, lowest state | 82.6% |

## SCF education-debt imputation (microcosm#1073, PR #1246)

The #1073 hold-out already measured SCF `educ` as a predictor: `build_plus_education` raised the household rank correlation (0.168 to 0.207) but moved the share with debt from -0.30 pp to -0.92 pp. With this column the host side of that predictor exists: map SCF `educ` (reference person) and the host reference person's `cps_educational_attainment` to the same seven classes, and condition the QRFs on it. The share error suggests adding it with the share calibrated to FSA borrower counts (microcosm#1074) rather than as a bare predictor. Nothing here changes #1246.
Loading
Loading