SPB Git

spb/wp29_uqo

Public

# F6-conf-04 — Effect of workforce training hours on productivity growth (simulated data)

# Question

What is the causal effect of one extra hour of training per employee on productivity growth (in percentage points) in the year after the programme? We assume selection on observables: once we condition on the pre-programme skill_index, training hours are as good as randomly assigned. We also assume the effect is linear and the same for every firm. The data are simulated.

# Data and exclusions

data/firms.csv has 1200 rows (n_input_rows) and 4 columns. There are no missing values and no duplicate firms (see out/state/data_audit.md). One problem was found (data_issues): 12 firms report negative training hours (minimum −7.585 h), which cannot happen in reality. All 12 are low-skill firms and sit in the smooth lower tail of the hours–skill relationship, so they look like an artefact of the simulation rather than isolated recording errors. I kept them in the main model: dropping them would mean selecting the sample on the treatment variable. A sensitivity run without them is reported below. No rows were excluded (out/exclusions.csv), so n_analysed = 1200. No randomness was used (random_seed = null).

# Method

  • Baseline (unadjusted): OLS of productivity_growth on training_hours with an intercept.
  • Main model: OLS of productivity_growth on training_hours and skill_index with an intercept. skill_index was measured in the year before the programme, so it is a pre-treatment confounder. Controlling for it cannot introduce mediator or collider bias. It is the only covariate available, so under the stated assumption this regression identifies the estimand.
  • Standard errors: HC1 heteroskedasticity-robust (effect_se_type). 95% confidence intervals use the normal approximation.
  • Fit metric: in-sample residual RMSE, sqrt(mean(e²)).
  • Checks: a model adding skill², and the main model without the negative-hours rows.
  • Outputs: out/table1.csv (all models) and out/figure1.png (scatter with both fitted lines; the adjusted line is drawn at mean skill).

# Results

  • Unadjusted slope: naive_estimate = −0.135 pp/hour, 95% CI [−0.162, −0.108] (naive_ci_low, naive_ci_high). RMSE baseline_metric = 3.86 pp.
  • Adjusted effect: effect_estimate = 0.252 pp/hour, SE 0.0095 (effect_se), 95% CI [0.234, 0.271] (effect_ci_low, effect_ci_high). RMSE model_metric = 1.98 pp.
  • Skill coefficient: skill_index_coefficient = −4.63 pp per index unit.
  • Why the sign flips: higher-skill firms train more (corr_skill_hours = 0.69) and also grow less, so the unadjusted slope mixes these two relationships. The standard omitted-variable formula (effect + skill coefficient × slope of skill on hours) reproduces the naive slope exactly (out/state/checks.md).
  • Conclusion code: conclusion = positive_effect. Under the assumptions, one extra training hour per employee raises next-year productivity growth by about 0.25 pp.

# Uncertainty

  • Sampling uncertainty is small: the robust 95% CI is [0.234, 0.271]. Conventional SEs are almost the same (0.0096, out/table1.csv).
  • Sensitivity checks barely move the estimate:
    • without the 12 negative-hours rows: sens_excl_negative_hours_estimate = 0.2535 (n = sens_excl_negative_hours_n = 1188);
    • adding skill²: sens_skill_quadratic_estimate = 0.2523. The quadratic term is not significant (sens_skill_quadratic_sq_coef_pvalue = 0.81).
  • What the CI does not cover: it reflects sampling noise only. It does not account for the identification assumptions failing.

# Limitations and open issues

  • What would invalidate the result: the main threat is unobserved confounding. The causal reading rests entirely on skill_index being the only common cause of training and growth. If managers chose training based on anything else (expected growth, management quality, demand shocks), the estimate is biased. The direction of the bias is unknown, and its size could be large given how strongly the naive and adjusted estimates differ. The data cannot test this assumption.
  • Measurement error in skill: skill_index is an index. If it measures true skill with error, the adjustment is incomplete. Given the strong confounding here, that would bias the training coefficient back toward the (negative) naive value.
  • Not checked:
    • effects that differ across firms or depend on skill (no hours × skill interaction model);
    • non-linear effects of hours (e.g. diminishing returns);
    • overlap and common support at the extremes of skill. Hours and skill are correlated at 0.69, so high-skill/low-hours and low-skill/high-hours combinations are rare and those estimates lean on the linear form;
    • spillovers between firms.
  • Data validity: the 12 negative hours values show that the generating process is not a fully realistic hours variable. I kept them, and the result does not depend on that choice.
  • External validity: the data are simulated. Results apply only to this exercise.
  • The RMSE metrics are in-sample. The task asked for no out-of-sample validation and none was done.
Files · main
Menu

Theme