Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save MaxGhenis/1d4f3b573d0ffbede880b05be1281b6a to your computer and use it in GitHub Desktop.

Select an option

Save MaxGhenis/1d4f3b573d0ffbede880b05be1281b6a to your computer and use it in GitHub Desktop.
Impact of unemployment insurance on child poverty: repeal vs. doubling (PolicyEngine-US 2026)
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "80dbc76f",
"metadata": {},
"source": [
"# Impact of unemployment insurance on child poverty: repeal vs. doubling\n",
"\n",
"This notebook analyzes how repealing and doubling UI benefits would each affect child poverty in 2026 using PolicyEngine-US microsimulation.\n",
"\n",
"**Methodology:**\n",
"- Compare baseline (with UI) to two counterfactuals: UI zeroed out (repeal) and UI doubled\n",
"- Changes cascade through tax calculations and other benefits\n",
"- Uses SPM (Supplemental Poverty Measure) for poverty measurement"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "436044c2",
"metadata": {
"execution": {
"iopub.execute_input": "2026-01-31T20:31:47.251532Z",
"iopub.status.busy": "2026-01-31T20:31:47.251447Z",
"iopub.status.idle": "2026-01-31T20:31:51.550637Z",
"shell.execute_reply": "2026-01-31T20:31:51.550081Z"
}
},
"outputs": [],
"source": [
"from policyengine_us import Microsimulation\n",
"import numpy as np\n",
"import pandas as pd\n",
"\n",
"year = 2026"
]
},
{
"cell_type": "markdown",
"id": "a2fb0b4b",
"metadata": {},
"source": [
"## Setup simulations"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "548e8501",
"metadata": {
"execution": {
"iopub.execute_input": "2026-01-31T20:31:51.555630Z",
"iopub.status.busy": "2026-01-31T20:31:51.555332Z",
"iopub.status.idle": "2026-01-31T20:31:52.441895Z",
"shell.execute_reply": "2026-01-31T20:31:52.441394Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Simulations initialized for 2026\n"
]
}
],
"source": [
"# Baseline simulation (current law with UI)\n",
"baseline = Microsimulation()\n",
"\n",
"# Counterfactual 1: zero out unemployment compensation (repeal)\n",
"repeal = Microsimulation()\n",
"repeal.set_input(\n",
" \"unemployment_compensation\",\n",
" year,\n",
" repeal.calc(\"unemployment_compensation\", period=year).values * 0,\n",
")\n",
"\n",
"# Counterfactual 2: double unemployment compensation\n",
"doubled = Microsimulation()\n",
"doubled.set_input(\n",
" \"unemployment_compensation\",\n",
" year,\n",
" doubled.calc(\"unemployment_compensation\", period=year).values * 2,\n",
")\n",
"\n",
"print(f\"Simulations initialized for {year}\")"
]
},
{
"cell_type": "markdown",
"id": "f1f30b45",
"metadata": {},
"source": [
"## Child poverty impact"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "d682a8ad",
"metadata": {
"execution": {
"iopub.execute_input": "2026-01-31T20:31:52.443442Z",
"iopub.status.busy": "2026-01-31T20:31:52.443346Z",
"iopub.status.idle": "2026-01-31T20:32:39.530885Z",
"shell.execute_reply": "2026-01-31T20:32:39.530206Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"=== CHILD POVERTY IMPACT ===\n",
"Baseline child poverty rate (current UI): 22.20%\n",
"\n",
"Repealing UI:\n",
" Child poverty rate: 22.42%\n",
" Increase: +0.22% (1.0% increase)\n",
" Children pushed into poverty: 159,849\n",
"\n",
"Doubling UI:\n",
" Child poverty rate: 22.14%\n",
" Reduction: -0.06% (0.3% reduction)\n",
" Children lifted from poverty: 41,023\n"
]
}
],
"source": [
"# Get child indicator\n",
"is_child = baseline.calc(\"is_child\", period=year)\n",
"total_children = float(is_child.sum())\n",
"\n",
"# Calculate SPM poverty status for each person\n",
"baseline_in_poverty = baseline.calc(\"person_in_poverty\", period=year)\n",
"repeal_in_poverty = repeal.calc(\"person_in_poverty\", period=year)\n",
"doubled_in_poverty = doubled.calc(\"person_in_poverty\", period=year)\n",
"\n",
"# Filter to children only\n",
"baseline_child_poverty = baseline_in_poverty[is_child.values == 1]\n",
"repeal_child_poverty = repeal_in_poverty[is_child.values == 1]\n",
"doubled_child_poverty = doubled_in_poverty[is_child.values == 1]\n",
"\n",
"# Calculate rates (MicroSeries .mean() is weighted automatically)\n",
"baseline_rate = float(baseline_child_poverty.mean())\n",
"repeal_rate = float(repeal_child_poverty.mean())\n",
"doubled_rate = float(doubled_child_poverty.mean())\n",
"\n",
"# Repeal metrics\n",
"repeal_increase_pp = repeal_rate - baseline_rate\n",
"repeal_increase_pct = repeal_increase_pp / baseline_rate if baseline_rate > 0 else 0\n",
"repeal_children_into_poverty = total_children * repeal_increase_pp\n",
"\n",
"# Doubling metrics\n",
"doubled_reduction_pp = baseline_rate - doubled_rate\n",
"doubled_reduction_pct = doubled_reduction_pp / baseline_rate if baseline_rate > 0 else 0\n",
"doubled_children_lifted = total_children * doubled_reduction_pp\n",
"\n",
"print(\"=== CHILD POVERTY IMPACT ===\")\n",
"print(f\"Baseline child poverty rate (current UI): {baseline_rate:.2%}\")\n",
"print()\n",
"print(f\"Repealing UI:\")\n",
"print(f\" Child poverty rate: {repeal_rate:.2%}\")\n",
"print(f\" Increase: +{repeal_increase_pp:.2%} ({repeal_increase_pct:.1%} increase)\")\n",
"print(f\" Children pushed into poverty: {repeal_children_into_poverty:,.0f}\")\n",
"print()\n",
"print(f\"Doubling UI:\")\n",
"print(f\" Child poverty rate: {doubled_rate:.2%}\")\n",
"print(f\" Reduction: -{doubled_reduction_pp:.2%} ({doubled_reduction_pct:.1%} reduction)\")\n",
"print(f\" Children lifted from poverty: {doubled_children_lifted:,.0f}\")"
]
},
{
"cell_type": "markdown",
"id": "f22bc6c4",
"metadata": {},
"source": [
"## Fiscal impacts"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "90f63ec0",
"metadata": {
"execution": {
"iopub.execute_input": "2026-01-31T20:32:39.536289Z",
"iopub.status.busy": "2026-01-31T20:32:39.536145Z",
"iopub.status.idle": "2026-01-31T20:32:39.545106Z",
"shell.execute_reply": "2026-01-31T20:32:39.544372Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"=== FISCAL IMPACTS: Repeal UI ===\n",
"UI outlays change: $-41.57B\n",
"Federal tax revenue change: $-5.90B\n",
"State/local tax revenue change: $-1.05B\n",
"Other benefits change (SNAP, etc.): $0.74B\n",
"Net income change: $-33.88B\n",
"\n",
"=== FISCAL IMPACTS: Double UI ===\n",
"UI outlays change: $41.57B\n",
"Federal tax revenue change: $7.09B\n",
"State/local tax revenue change: $1.06B\n",
"Other benefits change (SNAP, etc.): $-0.48B\n",
"Net income change: $32.93B\n",
"\n"
]
}
],
"source": [
"def calc_fiscal(sim, label):\n",
" ui = float((sim.calc(\"unemployment_compensation\", period=year) - baseline.calc(\"unemployment_compensation\", period=year)).sum())\n",
" fed_tax = float((sim.calc(\"spm_unit_federal_tax\", period=year) - baseline.calc(\"spm_unit_federal_tax\", period=year)).sum())\n",
" state_tax = float((sim.calc(\"spm_unit_state_tax\", period=year) - baseline.calc(\"spm_unit_state_tax\", period=year)).sum())\n",
" benefits = float((sim.calc(\"spm_unit_benefits\", period=year) - baseline.calc(\"spm_unit_benefits\", period=year)).sum())\n",
" net_income = float((sim.calc(\"spm_unit_net_income\", period=year) - baseline.calc(\"spm_unit_net_income\", period=year)).sum())\n",
" other_benefits = benefits - ui\n",
" return {\n",
" \"label\": label,\n",
" \"ui_change\": ui,\n",
" \"fed_tax_change\": fed_tax,\n",
" \"state_tax_change\": state_tax,\n",
" \"other_benefits_change\": other_benefits,\n",
" \"net_income_change\": net_income,\n",
" }\n",
"\n",
"repeal_fiscal = calc_fiscal(repeal, \"Repeal UI\")\n",
"doubled_fiscal = calc_fiscal(doubled, \"Double UI\")\n",
"\n",
"for f in [repeal_fiscal, doubled_fiscal]:\n",
" print(f\"=== FISCAL IMPACTS: {f['label']} ===\")\n",
" print(f\"UI outlays change: ${f['ui_change']/1e9:.2f}B\")\n",
" print(f\"Federal tax revenue change: ${f['fed_tax_change']/1e9:.2f}B\")\n",
" print(f\"State/local tax revenue change: ${f['state_tax_change']/1e9:.2f}B\")\n",
" print(f\"Other benefits change (SNAP, etc.): ${f['other_benefits_change']/1e9:.2f}B\")\n",
" print(f\"Net income change: ${f['net_income_change']/1e9:.2f}B\")\n",
" print()"
]
},
{
"cell_type": "markdown",
"id": "2aa6031b",
"metadata": {},
"source": [
"## Summary table"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "5db7cae4",
"metadata": {
"execution": {
"iopub.execute_input": "2026-01-31T20:32:39.547771Z",
"iopub.status.busy": "2026-01-31T20:32:39.547627Z",
"iopub.status.idle": "2026-01-31T20:32:39.553932Z",
"shell.execute_reply": "2026-01-31T20:32:39.553647Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Metric</th>\n",
" <th>Baseline</th>\n",
" <th>Repeal UI</th>\n",
" <th>Double UI</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Child poverty rate</td>\n",
" <td>22.20%</td>\n",
" <td>22.42%</td>\n",
" <td>22.14%</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Change vs baseline (pp)</td>\n",
" <td>-</td>\n",
" <td>+0.22%</td>\n",
" <td>-0.06%</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Change vs baseline (%)</td>\n",
" <td>-</td>\n",
" <td>+1.0%</td>\n",
" <td>-0.3%</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Children affected</td>\n",
" <td>-</td>\n",
" <td>+159,849 into poverty</td>\n",
" <td>41,023 lifted from poverty</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>UI outlays change ($B)</td>\n",
" <td>-</td>\n",
" <td>$-41.6B</td>\n",
" <td>$41.6B</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>Federal tax change ($B)</td>\n",
" <td>-</td>\n",
" <td>$-5.9B</td>\n",
" <td>$7.1B</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>State/local tax change ($B)</td>\n",
" <td>-</td>\n",
" <td>$-1.1B</td>\n",
" <td>$1.1B</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>Other benefits change ($B)</td>\n",
" <td>-</td>\n",
" <td>$0.7B</td>\n",
" <td>$-0.5B</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>Net income change ($B)</td>\n",
" <td>-</td>\n",
" <td>$-33.9B</td>\n",
" <td>$32.9B</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Metric Baseline Repeal UI \\\n",
"0 Child poverty rate 22.20% 22.42% \n",
"1 Change vs baseline (pp) - +0.22% \n",
"2 Change vs baseline (%) - +1.0% \n",
"3 Children affected - +159,849 into poverty \n",
"4 UI outlays change ($B) - $-41.6B \n",
"5 Federal tax change ($B) - $-5.9B \n",
"6 State/local tax change ($B) - $-1.1B \n",
"7 Other benefits change ($B) - $0.7B \n",
"8 Net income change ($B) - $-33.9B \n",
"\n",
" Double UI \n",
"0 22.14% \n",
"1 -0.06% \n",
"2 -0.3% \n",
"3 41,023 lifted from poverty \n",
"4 $41.6B \n",
"5 $7.1B \n",
"6 $1.1B \n",
"7 $-0.5B \n",
"8 $32.9B "
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"summary = pd.DataFrame({\n",
" \"Metric\": [\n",
" \"Child poverty rate\",\n",
" \"Change vs baseline (pp)\",\n",
" \"Change vs baseline (%)\",\n",
" \"Children affected\",\n",
" \"UI outlays change ($B)\",\n",
" \"Federal tax change ($B)\",\n",
" \"State/local tax change ($B)\",\n",
" \"Other benefits change ($B)\",\n",
" \"Net income change ($B)\",\n",
" ],\n",
" \"Baseline\": [\n",
" f\"{baseline_rate:.2%}\",\n",
" \"-\",\n",
" \"-\",\n",
" \"-\",\n",
" \"-\",\n",
" \"-\",\n",
" \"-\",\n",
" \"-\",\n",
" \"-\",\n",
" ],\n",
" \"Repeal UI\": [\n",
" f\"{repeal_rate:.2%}\",\n",
" f\"+{repeal_increase_pp:.2%}\",\n",
" f\"+{repeal_increase_pct:.1%}\",\n",
" f\"+{repeal_children_into_poverty:,.0f} into poverty\",\n",
" f\"${repeal_fiscal['ui_change']/1e9:.1f}B\",\n",
" f\"${repeal_fiscal['fed_tax_change']/1e9:.1f}B\",\n",
" f\"${repeal_fiscal['state_tax_change']/1e9:.1f}B\",\n",
" f\"${repeal_fiscal['other_benefits_change']/1e9:.1f}B\",\n",
" f\"${repeal_fiscal['net_income_change']/1e9:.1f}B\",\n",
" ],\n",
" \"Double UI\": [\n",
" f\"{doubled_rate:.2%}\",\n",
" f\"-{doubled_reduction_pp:.2%}\",\n",
" f\"-{doubled_reduction_pct:.1%}\",\n",
" f\"{doubled_children_lifted:,.0f} lifted from poverty\",\n",
" f\"${doubled_fiscal['ui_change']/1e9:.1f}B\",\n",
" f\"${doubled_fiscal['fed_tax_change']/1e9:.1f}B\",\n",
" f\"${doubled_fiscal['state_tax_change']/1e9:.1f}B\",\n",
" f\"${doubled_fiscal['other_benefits_change']/1e9:.1f}B\",\n",
" f\"${doubled_fiscal['net_income_change']/1e9:.1f}B\",\n",
" ],\n",
"})\n",
"\n",
"summary"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "5dfe4060",
"metadata": {
"execution": {
"iopub.execute_input": "2026-01-31T20:32:39.555272Z",
"iopub.status.busy": "2026-01-31T20:32:39.555192Z",
"iopub.status.idle": "2026-01-31T20:32:39.557852Z",
"shell.execute_reply": "2026-01-31T20:32:39.557392Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"PolicyEngine-US version: 1.525.0\n"
]
}
],
"source": [
"from importlib.metadata import version\n",
"print(f\"PolicyEngine-US version: {version('policyengine-us')}\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.14.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment