Created
July 23, 2025 13:39
-
-
Save nikhilwoodruff/5be11f58f8e772c47ea5559378d60741 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "code", | |
| "execution_count": 54, | |
| "id": "671ecba2", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Final shapes - X: (2939, 22), y: (2939, 3)\n", | |
| "Positive class rate: 0.084\n" | |
| ] | |
| }, | |
| { | |
| "data": { | |
| "application/vnd.plotly.v1+json": { | |
| "config": { | |
| "plotlyServerURL": "https://plot.ly" | |
| }, | |
| "data": [ | |
| { | |
| "alignmentgroup": "True", | |
| "hovertemplate": "variable=0<br>age=%{x}<br>value=%{y}<extra></extra>", | |
| "legendgroup": "0", | |
| "marker": { | |
| "color": "#2C6496", | |
| "pattern": { | |
| "shape": "" | |
| } | |
| }, | |
| "name": "0", | |
| "offsetgroup": "0", | |
| "orientation": "v", | |
| "showlegend": true, | |
| "textposition": "auto", | |
| "type": "bar", | |
| "x": [ | |
| 16, | |
| 17, | |
| 18, | |
| 19, | |
| 20, | |
| 21, | |
| 22, | |
| 23, | |
| 24, | |
| 25, | |
| 26, | |
| 27, | |
| 28, | |
| 29, | |
| 30, | |
| 31, | |
| 32, | |
| 33, | |
| 34, | |
| 35, | |
| 36, | |
| 37, | |
| 38, | |
| 39, | |
| 40, | |
| 41, | |
| 42, | |
| 43, | |
| 44, | |
| 45, | |
| 46, | |
| 47, | |
| 48, | |
| 49, | |
| 50, | |
| 51, | |
| 52, | |
| 53, | |
| 54, | |
| 55, | |
| 56, | |
| 57, | |
| 58, | |
| 59, | |
| 60, | |
| 61, | |
| 62, | |
| 63, | |
| 64, | |
| 65, | |
| 66, | |
| 67, | |
| 68, | |
| 69, | |
| 70 | |
| ], | |
| "xaxis": "x", | |
| "y": [ | |
| 0.12272046230208689, | |
| 0.33081985439156475, | |
| 0.1516752367078785, | |
| 0.3772873272728147, | |
| 0.16468009103932427, | |
| 0.08591656144753525, | |
| 0.07466549719671173, | |
| 0.15777115746405443, | |
| 0.055721381709675555, | |
| 0.10131817932298616, | |
| 0, | |
| 0, | |
| 0.04002040916023905, | |
| 0.016137188104571, | |
| 0, | |
| 0.1402600892175181, | |
| 0.04525813220638878, | |
| 0.1608129708654496, | |
| 0.04511183714501131, | |
| 0.05939275941906967, | |
| 0.03490604810205659, | |
| 0.1154995717236862, | |
| 0.13998911133370662, | |
| 0, | |
| 0, | |
| 0.06665570148965451, | |
| 0, | |
| 0.060169527622779745, | |
| 0.003022383156419279, | |
| 0, | |
| 0, | |
| 0, | |
| 0.013285449449810686, | |
| 0.046059949355663106, | |
| 0.02664482966877916, | |
| 0.06620395237455799, | |
| 0.04795735554207538, | |
| 0.034506853345332454, | |
| 0.04882587428663965, | |
| 0.05067503043217135, | |
| 0.025179332381747226, | |
| 0.05983957519211712, | |
| 0.06623991331869636, | |
| 0.0540075081766612, | |
| 0.17547062106758676, | |
| 0.034005776823203, | |
| 0.05179676172627123, | |
| 0.07260665569881053, | |
| 0.11661015350268067, | |
| 0.09148520299870647, | |
| 0.20846794479364292, | |
| 0.021167258221747823, | |
| 0.05639080905955598, | |
| 0.030691090201591165, | |
| 0.04208955308177593 | |
| ], | |
| "yaxis": "y" | |
| } | |
| ], | |
| "layout": { | |
| "annotations": [ | |
| { | |
| "showarrow": false, | |
| "text": "Source: PolicyEngine UK tax-benefit microsimulation model (version 2.40.2)", | |
| "x": 0, | |
| "xanchor": "left", | |
| "xref": "paper", | |
| "y": -0.2, | |
| "yanchor": "bottom", | |
| "yref": "paper" | |
| } | |
| ], | |
| "barmode": "relative", | |
| "font": { | |
| "color": "black", | |
| "family": "Roboto Serif" | |
| }, | |
| "height": 600, | |
| "images": [ | |
| { | |
| "sizex": 0.15, | |
| "sizey": 0.15, | |
| "source": "https://raw.githubusercontent.com/PolicyEngine/policyengine-app/master/src/images/logos/policyengine/blue.png", | |
| "x": 1.1, | |
| "xanchor": "right", | |
| "xref": "paper", | |
| "y": -0.2, | |
| "yanchor": "bottom", | |
| "yref": "paper" | |
| } | |
| ], | |
| "legend": { | |
| "title": { | |
| "text": "variable" | |
| }, | |
| "tracegroupgap": 0 | |
| }, | |
| "margin": { | |
| "b": 120, | |
| "l": 120, | |
| "r": 120, | |
| "t": 120 | |
| }, | |
| "modebar": { | |
| "activecolor": "#F4F4F4", | |
| "bgcolor": "#F4F4F4", | |
| "color": "#F4F4F4" | |
| }, | |
| "paper_bgcolor": "#F4F4F4", | |
| "plot_bgcolor": "#F4F4F4", | |
| "showlegend": false, | |
| "template": { | |
| "data": { | |
| "bar": [ | |
| { | |
| "error_x": { | |
| "color": "#2a3f5f" | |
| }, | |
| "error_y": { | |
| "color": "#2a3f5f" | |
| }, | |
| "marker": { | |
| "line": { | |
| "color": "white", | |
| "width": 0.5 | |
| }, | |
| "pattern": { | |
| "fillmode": "overlay", | |
| "size": 10, | |
| "solidity": 0.2 | |
| } | |
| }, | |
| "type": "bar" | |
| } | |
| ], | |
| "barpolar": [ | |
| { | |
| "marker": { | |
| "line": { | |
| "color": "white", | |
| "width": 0.5 | |
| }, | |
| "pattern": { | |
| "fillmode": "overlay", | |
| "size": 10, | |
| "solidity": 0.2 | |
| } | |
| }, | |
| "type": "barpolar" | |
| } | |
| ], | |
| "carpet": [ | |
| { | |
| "aaxis": { | |
| "endlinecolor": "#2a3f5f", | |
| "gridcolor": "#C8D4E3", | |
| "linecolor": "#C8D4E3", | |
| "minorgridcolor": "#C8D4E3", | |
| "startlinecolor": "#2a3f5f" | |
| }, | |
| "baxis": { | |
| "endlinecolor": "#2a3f5f", | |
| "gridcolor": "#C8D4E3", | |
| "linecolor": "#C8D4E3", | |
| "minorgridcolor": "#C8D4E3", | |
| "startlinecolor": "#2a3f5f" | |
| }, | |
| "type": "carpet" | |
| } | |
| ], | |
| "choropleth": [ | |
| { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| }, | |
| "type": "choropleth" | |
| } | |
| ], | |
| "contour": [ | |
| { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| }, | |
| "colorscale": [ | |
| [ | |
| 0, | |
| "#0d0887" | |
| ], | |
| [ | |
| 0.1111111111111111, | |
| "#46039f" | |
| ], | |
| [ | |
| 0.2222222222222222, | |
| "#7201a8" | |
| ], | |
| [ | |
| 0.3333333333333333, | |
| "#9c179e" | |
| ], | |
| [ | |
| 0.4444444444444444, | |
| "#bd3786" | |
| ], | |
| [ | |
| 0.5555555555555556, | |
| "#d8576b" | |
| ], | |
| [ | |
| 0.6666666666666666, | |
| "#ed7953" | |
| ], | |
| [ | |
| 0.7777777777777778, | |
| "#fb9f3a" | |
| ], | |
| [ | |
| 0.8888888888888888, | |
| "#fdca26" | |
| ], | |
| [ | |
| 1, | |
| "#f0f921" | |
| ] | |
| ], | |
| "type": "contour" | |
| } | |
| ], | |
| "contourcarpet": [ | |
| { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| }, | |
| "type": "contourcarpet" | |
| } | |
| ], | |
| "heatmap": [ | |
| { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| }, | |
| "colorscale": [ | |
| [ | |
| 0, | |
| "#0d0887" | |
| ], | |
| [ | |
| 0.1111111111111111, | |
| "#46039f" | |
| ], | |
| [ | |
| 0.2222222222222222, | |
| "#7201a8" | |
| ], | |
| [ | |
| 0.3333333333333333, | |
| "#9c179e" | |
| ], | |
| [ | |
| 0.4444444444444444, | |
| "#bd3786" | |
| ], | |
| [ | |
| 0.5555555555555556, | |
| "#d8576b" | |
| ], | |
| [ | |
| 0.6666666666666666, | |
| "#ed7953" | |
| ], | |
| [ | |
| 0.7777777777777778, | |
| "#fb9f3a" | |
| ], | |
| [ | |
| 0.8888888888888888, | |
| "#fdca26" | |
| ], | |
| [ | |
| 1, | |
| "#f0f921" | |
| ] | |
| ], | |
| "type": "heatmap" | |
| } | |
| ], | |
| "heatmapgl": [ | |
| { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| }, | |
| "colorscale": [ | |
| [ | |
| 0, | |
| "#0d0887" | |
| ], | |
| [ | |
| 0.1111111111111111, | |
| "#46039f" | |
| ], | |
| [ | |
| 0.2222222222222222, | |
| "#7201a8" | |
| ], | |
| [ | |
| 0.3333333333333333, | |
| "#9c179e" | |
| ], | |
| [ | |
| 0.4444444444444444, | |
| "#bd3786" | |
| ], | |
| [ | |
| 0.5555555555555556, | |
| "#d8576b" | |
| ], | |
| [ | |
| 0.6666666666666666, | |
| "#ed7953" | |
| ], | |
| [ | |
| 0.7777777777777778, | |
| "#fb9f3a" | |
| ], | |
| [ | |
| 0.8888888888888888, | |
| "#fdca26" | |
| ], | |
| [ | |
| 1, | |
| "#f0f921" | |
| ] | |
| ], | |
| "type": "heatmapgl" | |
| } | |
| ], | |
| "histogram": [ | |
| { | |
| "marker": { | |
| "pattern": { | |
| "fillmode": "overlay", | |
| "size": 10, | |
| "solidity": 0.2 | |
| } | |
| }, | |
| "type": "histogram" | |
| } | |
| ], | |
| "histogram2d": [ | |
| { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| }, | |
| "colorscale": [ | |
| [ | |
| 0, | |
| "#0d0887" | |
| ], | |
| [ | |
| 0.1111111111111111, | |
| "#46039f" | |
| ], | |
| [ | |
| 0.2222222222222222, | |
| "#7201a8" | |
| ], | |
| [ | |
| 0.3333333333333333, | |
| "#9c179e" | |
| ], | |
| [ | |
| 0.4444444444444444, | |
| "#bd3786" | |
| ], | |
| [ | |
| 0.5555555555555556, | |
| "#d8576b" | |
| ], | |
| [ | |
| 0.6666666666666666, | |
| "#ed7953" | |
| ], | |
| [ | |
| 0.7777777777777778, | |
| "#fb9f3a" | |
| ], | |
| [ | |
| 0.8888888888888888, | |
| "#fdca26" | |
| ], | |
| [ | |
| 1, | |
| "#f0f921" | |
| ] | |
| ], | |
| "type": "histogram2d" | |
| } | |
| ], | |
| "histogram2dcontour": [ | |
| { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| }, | |
| "colorscale": [ | |
| [ | |
| 0, | |
| "#0d0887" | |
| ], | |
| [ | |
| 0.1111111111111111, | |
| "#46039f" | |
| ], | |
| [ | |
| 0.2222222222222222, | |
| "#7201a8" | |
| ], | |
| [ | |
| 0.3333333333333333, | |
| "#9c179e" | |
| ], | |
| [ | |
| 0.4444444444444444, | |
| "#bd3786" | |
| ], | |
| [ | |
| 0.5555555555555556, | |
| "#d8576b" | |
| ], | |
| [ | |
| 0.6666666666666666, | |
| "#ed7953" | |
| ], | |
| [ | |
| 0.7777777777777778, | |
| "#fb9f3a" | |
| ], | |
| [ | |
| 0.8888888888888888, | |
| "#fdca26" | |
| ], | |
| [ | |
| 1, | |
| "#f0f921" | |
| ] | |
| ], | |
| "type": "histogram2dcontour" | |
| } | |
| ], | |
| "mesh3d": [ | |
| { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| }, | |
| "type": "mesh3d" | |
| } | |
| ], | |
| "parcoords": [ | |
| { | |
| "line": { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| } | |
| }, | |
| "type": "parcoords" | |
| } | |
| ], | |
| "pie": [ | |
| { | |
| "automargin": true, | |
| "type": "pie" | |
| } | |
| ], | |
| "scatter": [ | |
| { | |
| "fillpattern": { | |
| "fillmode": "overlay", | |
| "size": 10, | |
| "solidity": 0.2 | |
| }, | |
| "type": "scatter" | |
| } | |
| ], | |
| "scatter3d": [ | |
| { | |
| "line": { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| } | |
| }, | |
| "marker": { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| } | |
| }, | |
| "type": "scatter3d" | |
| } | |
| ], | |
| "scattercarpet": [ | |
| { | |
| "marker": { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| } | |
| }, | |
| "type": "scattercarpet" | |
| } | |
| ], | |
| "scattergeo": [ | |
| { | |
| "marker": { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| } | |
| }, | |
| "type": "scattergeo" | |
| } | |
| ], | |
| "scattergl": [ | |
| { | |
| "marker": { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| } | |
| }, | |
| "type": "scattergl" | |
| } | |
| ], | |
| "scattermapbox": [ | |
| { | |
| "marker": { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| } | |
| }, | |
| "type": "scattermapbox" | |
| } | |
| ], | |
| "scatterpolar": [ | |
| { | |
| "marker": { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| } | |
| }, | |
| "type": "scatterpolar" | |
| } | |
| ], | |
| "scatterpolargl": [ | |
| { | |
| "marker": { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| } | |
| }, | |
| "type": "scatterpolargl" | |
| } | |
| ], | |
| "scatterternary": [ | |
| { | |
| "marker": { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| } | |
| }, | |
| "type": "scatterternary" | |
| } | |
| ], | |
| "surface": [ | |
| { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| }, | |
| "colorscale": [ | |
| [ | |
| 0, | |
| "#0d0887" | |
| ], | |
| [ | |
| 0.1111111111111111, | |
| "#46039f" | |
| ], | |
| [ | |
| 0.2222222222222222, | |
| "#7201a8" | |
| ], | |
| [ | |
| 0.3333333333333333, | |
| "#9c179e" | |
| ], | |
| [ | |
| 0.4444444444444444, | |
| "#bd3786" | |
| ], | |
| [ | |
| 0.5555555555555556, | |
| "#d8576b" | |
| ], | |
| [ | |
| 0.6666666666666666, | |
| "#ed7953" | |
| ], | |
| [ | |
| 0.7777777777777778, | |
| "#fb9f3a" | |
| ], | |
| [ | |
| 0.8888888888888888, | |
| "#fdca26" | |
| ], | |
| [ | |
| 1, | |
| "#f0f921" | |
| ] | |
| ], | |
| "type": "surface" | |
| } | |
| ], | |
| "table": [ | |
| { | |
| "cells": { | |
| "fill": { | |
| "color": "#EBF0F8" | |
| }, | |
| "line": { | |
| "color": "white" | |
| } | |
| }, | |
| "header": { | |
| "fill": { | |
| "color": "#C8D4E3" | |
| }, | |
| "line": { | |
| "color": "white" | |
| } | |
| }, | |
| "type": "table" | |
| } | |
| ] | |
| }, | |
| "layout": { | |
| "annotationdefaults": { | |
| "arrowcolor": "#2a3f5f", | |
| "arrowhead": 0, | |
| "arrowwidth": 1 | |
| }, | |
| "autotypenumbers": "strict", | |
| "coloraxis": { | |
| "colorbar": { | |
| "outlinewidth": 0, | |
| "ticks": "" | |
| } | |
| }, | |
| "colorscale": { | |
| "diverging": [ | |
| [ | |
| 0, | |
| "#8e0152" | |
| ], | |
| [ | |
| 0.1, | |
| "#c51b7d" | |
| ], | |
| [ | |
| 0.2, | |
| "#de77ae" | |
| ], | |
| [ | |
| 0.3, | |
| "#f1b6da" | |
| ], | |
| [ | |
| 0.4, | |
| "#fde0ef" | |
| ], | |
| [ | |
| 0.5, | |
| "#f7f7f7" | |
| ], | |
| [ | |
| 0.6, | |
| "#e6f5d0" | |
| ], | |
| [ | |
| 0.7, | |
| "#b8e186" | |
| ], | |
| [ | |
| 0.8, | |
| "#7fbc41" | |
| ], | |
| [ | |
| 0.9, | |
| "#4d9221" | |
| ], | |
| [ | |
| 1, | |
| "#276419" | |
| ] | |
| ], | |
| "sequential": [ | |
| [ | |
| 0, | |
| "#0d0887" | |
| ], | |
| [ | |
| 0.1111111111111111, | |
| "#46039f" | |
| ], | |
| [ | |
| 0.2222222222222222, | |
| "#7201a8" | |
| ], | |
| [ | |
| 0.3333333333333333, | |
| "#9c179e" | |
| ], | |
| [ | |
| 0.4444444444444444, | |
| "#bd3786" | |
| ], | |
| [ | |
| 0.5555555555555556, | |
| "#d8576b" | |
| ], | |
| [ | |
| 0.6666666666666666, | |
| "#ed7953" | |
| ], | |
| [ | |
| 0.7777777777777778, | |
| "#fb9f3a" | |
| ], | |
| [ | |
| 0.8888888888888888, | |
| "#fdca26" | |
| ], | |
| [ | |
| 1, | |
| "#f0f921" | |
| ] | |
| ], | |
| "sequentialminus": [ | |
| [ | |
| 0, | |
| "#0d0887" | |
| ], | |
| [ | |
| 0.1111111111111111, | |
| "#46039f" | |
| ], | |
| [ | |
| 0.2222222222222222, | |
| "#7201a8" | |
| ], | |
| [ | |
| 0.3333333333333333, | |
| "#9c179e" | |
| ], | |
| [ | |
| 0.4444444444444444, | |
| "#bd3786" | |
| ], | |
| [ | |
| 0.5555555555555556, | |
| "#d8576b" | |
| ], | |
| [ | |
| 0.6666666666666666, | |
| "#ed7953" | |
| ], | |
| [ | |
| 0.7777777777777778, | |
| "#fb9f3a" | |
| ], | |
| [ | |
| 0.8888888888888888, | |
| "#fdca26" | |
| ], | |
| [ | |
| 1, | |
| "#f0f921" | |
| ] | |
| ] | |
| }, | |
| "colorway": [ | |
| "#636efa", | |
| "#EF553B", | |
| "#00cc96", | |
| "#ab63fa", | |
| "#FFA15A", | |
| "#19d3f3", | |
| "#FF6692", | |
| "#B6E880", | |
| "#FF97FF", | |
| "#FECB52" | |
| ], | |
| "font": { | |
| "color": "#2a3f5f" | |
| }, | |
| "geo": { | |
| "bgcolor": "white", | |
| "lakecolor": "white", | |
| "landcolor": "white", | |
| "showlakes": true, | |
| "showland": true, | |
| "subunitcolor": "#C8D4E3" | |
| }, | |
| "hoverlabel": { | |
| "align": "left" | |
| }, | |
| "hovermode": "closest", | |
| "mapbox": { | |
| "style": "light" | |
| }, | |
| "paper_bgcolor": "white", | |
| "plot_bgcolor": "white", | |
| "polar": { | |
| "angularaxis": { | |
| "gridcolor": "#EBF0F8", | |
| "linecolor": "#EBF0F8", | |
| "ticks": "" | |
| }, | |
| "bgcolor": "white", | |
| "radialaxis": { | |
| "gridcolor": "#EBF0F8", | |
| "linecolor": "#EBF0F8", | |
| "ticks": "" | |
| } | |
| }, | |
| "scene": { | |
| "xaxis": { | |
| "backgroundcolor": "white", | |
| "gridcolor": "#DFE8F3", | |
| "gridwidth": 2, | |
| "linecolor": "#EBF0F8", | |
| "showbackground": true, | |
| "ticks": "", | |
| "zerolinecolor": "#EBF0F8" | |
| }, | |
| "yaxis": { | |
| "backgroundcolor": "white", | |
| "gridcolor": "#DFE8F3", | |
| "gridwidth": 2, | |
| "linecolor": "#EBF0F8", | |
| "showbackground": true, | |
| "ticks": "", | |
| "zerolinecolor": "#EBF0F8" | |
| }, | |
| "zaxis": { | |
| "backgroundcolor": "white", | |
| "gridcolor": "#DFE8F3", | |
| "gridwidth": 2, | |
| "linecolor": "#EBF0F8", | |
| "showbackground": true, | |
| "ticks": "", | |
| "zerolinecolor": "#EBF0F8" | |
| } | |
| }, | |
| "shapedefaults": { | |
| "line": { | |
| "color": "#2a3f5f" | |
| } | |
| }, | |
| "ternary": { | |
| "aaxis": { | |
| "gridcolor": "#DFE8F3", | |
| "linecolor": "#A2B1C6", | |
| "ticks": "" | |
| }, | |
| "baxis": { | |
| "gridcolor": "#DFE8F3", | |
| "linecolor": "#A2B1C6", | |
| "ticks": "" | |
| }, | |
| "bgcolor": "white", | |
| "caxis": { | |
| "gridcolor": "#DFE8F3", | |
| "linecolor": "#A2B1C6", | |
| "ticks": "" | |
| } | |
| }, | |
| "title": { | |
| "x": 0.05 | |
| }, | |
| "xaxis": { | |
| "automargin": true, | |
| "gridcolor": "#EBF0F8", | |
| "linecolor": "#EBF0F8", | |
| "ticks": "", | |
| "title": { | |
| "standoff": 15 | |
| }, | |
| "zerolinecolor": "#EBF0F8", | |
| "zerolinewidth": 2 | |
| }, | |
| "yaxis": { | |
| "automargin": true, | |
| "gridcolor": "#EBF0F8", | |
| "linecolor": "#EBF0F8", | |
| "ticks": "", | |
| "title": { | |
| "standoff": 15 | |
| }, | |
| "zerolinecolor": "#EBF0F8", | |
| "zerolinewidth": 2 | |
| } | |
| } | |
| }, | |
| "title": { | |
| "text": "Percentage of people who became economically active in the last 5 quarters, by <br>age (LFS) " | |
| }, | |
| "uniformtext": { | |
| "minsize": 12, | |
| "mode": "hide" | |
| }, | |
| "width": 800, | |
| "xaxis": { | |
| "anchor": "y", | |
| "domain": [ | |
| 0, | |
| 1 | |
| ], | |
| "gridcolor": "#F4F4F4", | |
| "ticksuffix": "", | |
| "title": { | |
| "text": "age" | |
| }, | |
| "zerolinecolor": "#F4F4F4" | |
| }, | |
| "yaxis": { | |
| "anchor": "x", | |
| "domain": [ | |
| 0, | |
| 1 | |
| ], | |
| "gridcolor": "#F4F4F4", | |
| "tickformat": ".0%", | |
| "ticksuffix": "", | |
| "title": { | |
| "text": "value" | |
| }, | |
| "zerolinecolor": "#F4F4F4" | |
| } | |
| } | |
| } | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "from microimpute.comparisons import autoimpute\n", | |
| "from policyengine_uk import Microsimulation\n", | |
| "\n", | |
| "baseline = Microsimulation()\n", | |
| "baseline.subsample(20_000)\n", | |
| "\n", | |
| "df = baseline.calculate_dataframe([\n", | |
| " \"age\",\n", | |
| " \"gender\",\n", | |
| " \"employment_status\",\n", | |
| " \"pip_dl\",\n", | |
| " \"pip_m\",\n", | |
| "], 2025)\n", | |
| "\n", | |
| "# Rough naive approach: impute 'became newly economically active' from the LFS?\n", | |
| "\n", | |
| "import pandas as pd\n", | |
| "import numpy as np\n", | |
| "\n", | |
| "# Load the data\n", | |
| "lfs = pd.read_csv(\"~/Downloads/UKDA-9133-tab/tab/lgwt22_5q_aj22_aj23_eul.tab\", sep=\"\\t\")\n", | |
| "\n", | |
| "# Create target variable as DataFrame\n", | |
| "inactivity_variables = [\n", | |
| " \"INCAC051\",\n", | |
| " \"INCAC052\",\n", | |
| " \"INCAC053\",\n", | |
| " \"INCAC054\",\n", | |
| " \"INCAC055\",\n", | |
| "]\n", | |
| "was_inactive_at_some_point = np.any(\n", | |
| " [lfs[col] >= 6 for col in inactivity_variables],\n", | |
| " axis=0\n", | |
| ")\n", | |
| "became_active = np.any(\n", | |
| " [lfs[col] == 1 for col in inactivity_variables],\n", | |
| " axis=0\n", | |
| ")\n", | |
| "quarter_of_last_inactivity = np.argmax(\n", | |
| " [lfs[col] >= 6 for col in inactivity_variables],\n", | |
| ")\n", | |
| "quarter_of_first_activity = quarter_of_last_inactivity\n", | |
| "length_activity_after_inactivity = (4 - quarter_of_first_activity + 1) / 4\n", | |
| "y_train = pd.DataFrame(dict(\n", | |
| " was_inactive_at_some_point=was_inactive_at_some_point,\n", | |
| " became_active_afterwards=became_active,\n", | |
| " activity_length_after_inactivity=length_activity_after_inactivity * was_inactive_at_some_point * became_active\n", | |
| "))\n", | |
| "\n", | |
| "# Select predictor variables with clear names\n", | |
| "predictor_mapping = {\n", | |
| " # Demographics\n", | |
| " 'AGE5': 'age',\n", | |
| " 'SEX': 'sex', \n", | |
| " 'MARSTA5': 'marital_status',\n", | |
| " 'ETUKEUL5': 'ethnicity',\n", | |
| " 'HIQUAL155': 'highest_qualification',\n", | |
| " 'GOVTOR5': 'region',\n", | |
| " \n", | |
| " # Employment characteristics\n", | |
| " 'FTPTWK5': 'full_or_part_time',\n", | |
| " 'SOC20M5': 'occupation_code',\n", | |
| " 'Inds07m5': 'industry_code',\n", | |
| " 'PUBLICR5': 'public_or_private_sector',\n", | |
| " \n", | |
| " # Income\n", | |
| " 'GRSSWK5': 'gross_weekly_pay',\n", | |
| " 'HRRATE5': 'hourly_pay_rate',\n", | |
| " \n", | |
| " # Household\n", | |
| " 'TEN15': 'housing_tenure',\n", | |
| " 'HDPCH195': 'num_dependent_children',\n", | |
| " \n", | |
| " # Education\n", | |
| " 'QULNOW5': 'current_qualification_studying',\n", | |
| " 'ENROLL5': 'enrolled_in_education',\n", | |
| " \n", | |
| " # Current health/disability status\n", | |
| " 'LNGLST5': 'has_longstanding_illness',\n", | |
| " 'LIMACT5': 'illness_limits_activities', \n", | |
| " 'DISEA5': 'disability_equality_act',\n", | |
| " \n", | |
| " # Previous health/disability status\n", | |
| " 'LNGLST1': 'had_longstanding_illness_q1',\n", | |
| " 'LIMACT1': 'illness_limited_activities_q1',\n", | |
| " 'DISEA1': 'disability_equality_act_q1'\n", | |
| "}\n", | |
| "\n", | |
| "# Create X_train with renamed columns\n", | |
| "X_train = lfs[list(predictor_mapping.keys())].rename(columns=predictor_mapping)\n", | |
| "\n", | |
| "# Get weights\n", | |
| "weights = lfs['LGWT22'].copy()\n", | |
| "\n", | |
| "# Convert categorical variables to strings\n", | |
| "categorical_vars = [\n", | |
| " 'sex', 'marital_status', 'ethnicity', 'highest_qualification', 'region',\n", | |
| " 'full_or_part_time', 'public_or_private_sector', 'housing_tenure', \n", | |
| " 'enrolled_in_education', 'current_qualification_studying',\n", | |
| " 'has_longstanding_illness', 'illness_limits_activities', 'disability_equality_act',\n", | |
| " 'had_longstanding_illness_q1', 'illness_limited_activities_q1', 'disability_equality_act_q1',\n", | |
| " 'occupation_code', 'industry_code'\n", | |
| "]\n", | |
| "\n", | |
| "for col in categorical_vars:\n", | |
| " if col in X_train.columns:\n", | |
| " X_train[col] = X_train[col].astype('Int64').astype(str).replace('<NA>', 'missing')\n", | |
| "\n", | |
| "# Remove rows with missing weights or target\n", | |
| "mask = weights.notna() & y_train['activity_length_after_inactivity'].notna()\n", | |
| "X_train = X_train[mask]\n", | |
| "y_train = y_train[mask]\n", | |
| "weights = weights[mask]\n", | |
| "\n", | |
| "\n", | |
| "print(f\"Final shapes - X: {X_train.shape}, y: {y_train.shape}\")\n", | |
| "print(f\"Positive class rate: {y_train['activity_length_after_inactivity'].mean():.3f}\")\n", | |
| "\n", | |
| "from microimpute.comparisons import autoimpute\n", | |
| "import plotly.express as px\n", | |
| "from microdf import MicroDataFrame\n", | |
| "\n", | |
| "df = pd.concat([X_train, y_train], axis=1)\n", | |
| "df[\"employment_income\"] = df.gross_weekly_pay.clip(lower=0) * 52\n", | |
| "df[\"gender\"] = df.sex.astype(int).map({1: \"MALE\", 2: \"FEMALE\"})\n", | |
| "df[\"weight\"] = weights\n", | |
| "\n", | |
| "df_w = MicroDataFrame(df, weights=weights)\n", | |
| "\n", | |
| "from policyengine.utils.charts import *\n", | |
| "\n", | |
| "fig = px.bar(\n", | |
| " (df_w.was_inactive_at_some_point * df_w.became_active_afterwards).groupby(df_w.age).mean(),\n", | |
| " color_discrete_sequence=[BLUE]\n", | |
| ").update_layout(\n", | |
| " showlegend=False,\n", | |
| " title=\"Percentage of people who became economically active in the last 5 quarters, by age (LFS)\",\n", | |
| " yaxis_tickformat=\".0%\",\n", | |
| ")\n", | |
| "\n", | |
| "format_fig(fig)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 55, | |
| "id": "c1402bfb", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "\n", | |
| " <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n", | |
| " <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n", | |
| " <link href=\"https://fonts.googleapis.com/css2?family=Roboto+Serif:ital,opsz,wght@0,8..144,100..900;1,8..144,100..900&display=swap\" rel=\"stylesheet\">\n", | |
| " " | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "from policyengine.utils.charts import add_fonts\n", | |
| "\n", | |
| "add_fonts()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 56, | |
| "id": "a75c732e", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "imputed_vars = [\n", | |
| " \"was_inactive_at_some_point\",\n", | |
| " \"became_active_afterwards\",\n", | |
| "]\n", | |
| "\n", | |
| "predictor_vars = [\n", | |
| " \"age\",\n", | |
| " \"gender\",\n", | |
| " \"employment_income\",\n", | |
| "]\n", | |
| "\n", | |
| "efrs = baseline.calculate_dataframe([\n", | |
| " \"age\",\n", | |
| " \"gender\",\n", | |
| " \"employment_income\",\n", | |
| "], 2025)\n", | |
| "\n", | |
| "from quantile_forest import RandomForestQuantileRegressor as QRF\n", | |
| "\n", | |
| "df.gender = df.gender.map({\n", | |
| " \"MALE\": 0,\n", | |
| " \"FEMALE\": 1,\n", | |
| "})\n", | |
| "\n", | |
| "efrs.gender = efrs.gender.map({\n", | |
| " \"MALE\": 0,\n", | |
| " \"FEMALE\": 1,\n", | |
| "})\n", | |
| "\n", | |
| "df = df.astype(float)\n", | |
| "efrs = efrs.astype(float)\n", | |
| "\n", | |
| "model = QRF()\n", | |
| "model = model.fit(df[predictor_vars], df[imputed_vars])\n", | |
| "\n", | |
| "efrs[imputed_vars] = model.predict(efrs[predictor_vars])" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 57, | |
| "id": "bf204593", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "efrs[\"joined_labour_force_recently\"] = efrs.was_inactive_at_some_point * efrs.became_active_afterwards\n", | |
| "\n", | |
| "# Children not in the LFS, don't impute for them\n", | |
| "efrs[\"joined_labour_force_recently\"] = np.where(\n", | |
| " ~efrs.age.between(16, 65),\n", | |
| " 0,\n", | |
| " efrs[\"joined_labour_force_recently\"]\n", | |
| ")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 58, | |
| "id": "cfbd833a", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "# Impute target wage for those who joined the labour force recently\n", | |
| "\n", | |
| "target_wage_model = QRF()\n", | |
| "\n", | |
| "target_wage_model = target_wage_model.fit(\n", | |
| " efrs[efrs.joined_labour_force_recently == 1][predictor_vars],\n", | |
| " efrs[efrs.joined_labour_force_recently == 1].employment_income\n", | |
| ")\n", | |
| "\n", | |
| "efrs[\"target_wage\"] = target_wage_model.predict(efrs[predictor_vars])\n", | |
| "efrs[\"target_wage\"][efrs.joined_labour_force_recently == 0] = 0" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 93, | |
| "id": "250dbc74", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "def calculate_employer_ni(wage, exemption = False):\n", | |
| " if exemption:\n", | |
| " return 0\n", | |
| " wages_over_threshold = np.maximum(wage - 5_000, 0)\n", | |
| " return wages_over_threshold * 0.15\n", | |
| "\n", | |
| "def calculate_post_tax_salary(wage):\n", | |
| " # very rough estimate of post-tax salary after it and employee ni\n", | |
| " if wage <= 12_570:\n", | |
| " return wage\n", | |
| " elif wage <= 50_270:\n", | |
| " income_tax = (wage - 12_570) * 0.2\n", | |
| " employee_ni = (wage - 12_570) * 0.12\n", | |
| " else:\n", | |
| " income_tax = (50_270 - 12_570) * 0.2 + (wage - 50_270) * 0.4\n", | |
| " employee_ni = (50_270 - 12_570) * 0.12 + (wage - 50_270) * 0.02\n", | |
| "\n", | |
| " return wage - income_tax - employee_ni\n", | |
| "\n", | |
| "efrs[\"baseline_target_employer_ni\"] = calculate_employer_ni(efrs.target_wage)\n", | |
| "efrs[\"reform_target_employer_ni\"] = calculate_employer_ni(efrs.target_wage, exemption=True)\n", | |
| "efrs[\"change_target_employer_ni\"] = efrs.reform_target_employer_ni - efrs.baseline_target_employer_ni\n", | |
| "\n", | |
| "# 40% incidence\n", | |
| "\n", | |
| "efrs[\"change_in_target_salary\"] = -efrs.change_target_employer_ni * 0.4\n", | |
| "efrs[\"original_target_salary_post_tax\"] = (efrs.target_wage).apply(calculate_post_tax_salary)\n", | |
| "efrs[\"target_salary_post_tax\"] = (efrs.target_wage + efrs.change_in_target_salary).apply(calculate_post_tax_salary)\n", | |
| "efrs[\"change_in_target_salary_post_tax\"] = efrs.target_salary_post_tax - efrs.original_target_salary_post_tax\n", | |
| "efrs[\"rel_change_in_target_salary\"] = efrs.change_in_target_salary_post_tax / (efrs.original_target_salary_post_tax+1)\n", | |
| "\n", | |
| "rel_change_in_participation = efrs.rel_change_in_target_salary / 0.01 * 0.36\n", | |
| "\n", | |
| "efrs[\"joins_labour_force\"] = np.random.random() < rel_change_in_participation" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 103, | |
| "id": "150e8ef0", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/plain": [ | |
| "212.0630625" | |
| ] | |
| }, | |
| "execution_count": 103, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "(efrs.joins_labour_force * baseline.calculate(\"household_weight\", 2025, map_to=\"person\").values).sum()/1e3" | |
| ] | |
| } | |
| ], | |
| "metadata": { | |
| "kernelspec": { | |
| "display_name": ".venv", | |
| "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.11.13" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 5 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment