euromod.eu_euromod.calibrate.estimation¶
The tax-benefit schedule and how it is estimated.
The schedule¶
A country’s tax-benefit system is summarised by the function of Heathcote,
Storesletten and Violante (HSV). For a household with gross income y, measured
in multiples of mean income, disposable income is (1 - lambda) * y**(1 - tau),
so the average net tax rate is:
1 - (1 - lambda) * y**(-tau)
lambda is the net tax rate at mean income (the level) and tau measures
how fast the rate rises with income (the progressivity; tau = 0 is a flat
rate). Benefits are included, so the rate is negative for households that receive
more than they pay.
The estimator¶
Taking logs makes the schedule linear:
log(disposable) = log(1 - lambda) + (1 - tau) * log(y)
fit_hsv() estimates it by weighted least squares, with the survey weights
dwt. There is a closed-form solution, so nothing is optimised numerically and
the result does not depend on starting values.
To compare a reform with a baseline it is often useful to hold the level fixed and
let only the progressivity move. With lambda_fixed the intercept is known, and
tau comes from a regression through the origin of
log(disposable) - log(1 - lambda) on log(y).
Household types are subsets of one sample (HOUSEHOLD_TYPES). They share
its income scale, so their estimates can be compared with each other.
Below are listed the main public classes of the euromod.eu_euromod.calibrate.estimation module.
|
Mean income and mean net tax rate in equally wide income bins. |
|
How well a fitted schedule describes a sample. |
|
Estimate the HSV schedule on a household sample. |
|
Average net tax rate of the HSV schedule. |
|
Marginal net tax rate of the HSV schedule: the share of an extra euro of gross |
|
Observed net tax rate of households at mean income. |
|
Pool the household samples of several countries, e.g. into a euro-area sample. |
|
The households of one type. |
|
Export fitted schedules as a |
- |
Functions¶
- euromod.eu_euromod.calibrate.estimation.binned_means(sample, bins=80)¶
Mean income and mean net tax rate in equally wide income bins.
Used to judge the shape of the fitted schedule without the scatter of individual households.
- Parameters:
sample (pandas.DataFrame) – A household sample.
bins (
int) – Number of bins between the lowest and highestincome_norm.
- Returns:
One row per non-empty bin:
income_normandnet_tax_rate(plain means over the households in the bin),dwt_sum(their total weight) andn(their number).- Return type:
- euromod.eu_euromod.calibrate.estimation.fit_diagnostics(sample, fit, bins=80)¶
How well a fitted schedule describes a sample.
- Parameters:
sample (pandas.DataFrame) – The household sample the schedule was fitted on.
bins (
int) – Number of income bins for the binned errors.
- Returns:
net_tax_rate_at_mean: seenet_tax_rate_at_mean_income().rmse,mae: weighted errors of the net tax rate, household by household. Dominated by the spread of households around the schedule.rmse_binned,mae_binned: the same againstbinned_means(), weighted by bin population. These measure the shape of the schedule.gini_gross,gini_disposable: observed Gini coefficients.gini_fitted: Gini of the disposable income the fitted schedule assigns to the same gross incomes. The gap togini_disposableis the redistribution the two-parameter schedule does not capture.
- Return type:
- euromod.eu_euromod.calibrate.estimation.fit_hsv(sample, *, lambda_fixed=None)¶
Estimate the HSV schedule on a household sample.
- Parameters:
sample (pandas.DataFrame) – A household sample with
income_norm,disposable_normanddwt.lambda_fixed (float, optional) – Hold the level at this value and estimate only
tau.
- Returns:
lambda,tau,se_tauandn, plusse_intercept(standard error oflog(1 - lambda)),se_lambdaandr2when both parameters are estimated;r2_uncenteredwhenlambdais fixed.
Standard errors are the classical ones of weighted least squares.
- Return type:
Example
>>> fit = fit_hsv(sample) >>> fit["lambda"], fit["tau"] (0.1925, 0.1631) >>> fit_hsv(select_households(sample, "married"))["tau"] 0.1918
- euromod.eu_euromod.calibrate.estimation.hsv(income, lambda_, tau)¶
Average net tax rate of the HSV schedule.
- Parameters:
- Return type:
Example
>>> hsv(np.array([0.5, 1.0, 2.0]), 0.1925, 0.1631) array([0.0958, 0.1925, 0.2788])
- euromod.eu_euromod.calibrate.estimation.marginal_hsv(income, lambda_, tau)¶
Marginal net tax rate of the HSV schedule: the share of an extra euro of gross income that does not reach disposable income.
- Parameters:
- Return type:
- euromod.eu_euromod.calibrate.estimation.net_tax_rate_at_mean_income(sample, band=0.05)¶
Observed net tax rate of households at mean income.
A weighted straight line is fitted through the net tax rates of households whose income is within
bandof the mean, and read off at the mean. This is the data counterpart oflambda.- Parameters:
sample (pandas.DataFrame) – A household sample.
band (float) – Half-width of the income window around 1.0.
- Returns:
If no household falls in the window, the rate of the closest household.
- Return type:
- euromod.eu_euromod.calibrate.estimation.pool(samples)¶
Pool the household samples of several countries, e.g. into a euro-area sample.
Each country keeps its own income scale (1.0 is that country’s mean income) and its own survey weights, so a country counts in proportion to its population.
- Parameters:
samples (dict) – Household samples by system name, e.g.
{"AT_2022": ..., "BE_2022": ...}.- Returns:
All households, with a
countrycolumn.- Return type:
- euromod.eu_euromod.calibrate.estimation.select_households(sample, household_type)¶
The households of one type.
- Parameters:
sample (pandas.DataFrame) – A household sample.
household_type (
str) – A key ofHOUSEHOLD_TYPES, or any condition on the sample’s columns, e.g."hh_size == 1".
- Return type:
- euromod.eu_euromod.calibrate.estimation.to_calibration(fits, *, system, dataset='', model_version='', constants=None)¶
Export fitted schedules as a
euromod.calibrate.Calibration.The
Calibrationevaluates the schedule with a numba-compiled function, which can be called from other compiled code, and can be saved to and loaded from JSON. It needssympyandnumba(pip install euromod[calibrate]).- Parameters:
fits (dict) – One result of
fit_hsv(), or several by household type:{"all": fit, "married": fit_married}.system (
str) – Name of the system the fits belong to.dataset (
str, optional) – Recorded in the calibration.model_version (
str, optional) – Recorded in the calibration.constants (
dict, optional) – Constants that were overridden in the run, as passed tosimulate().
- Returns:
With one group per household type.
- Return type:
euromod.calibrate.Calibration
Example
>>> cal = to_calibration(fit_hsv(sample), system="PT_2022") >>> cal(np.array([0.5, 1.0, 2.0])) array([0.0958, 0.1925, 0.2788]) >>> cal.to_json("PT_2022_hsv.json") >>> schedule = cal.numba_function # schedule(income, lambda_t, tau)
Attributes¶
- euromod.eu_euromod.calibrate.estimation.HOUSEHOLD_TYPES¶