Diagnostics and Placebos
MSC is useful only when the controls can reconstruct treated-unit pre-treatment paths. Start with pre-fit diagnostics.
using MSC
using Statistics
sim = simulate_msc(ncontrols = 25, ntreated = 5, T0 = 55, T1 = 6, tau = 1.0, seed = 5)
est = msc_estimate(sim.Y, sim.N0, sim.T0; nlambda = 8, nfolds = 4, max_iter = 900)
Xpre = sim.Y[1:sim.N0, 1:sim.T0]'
Ypre = sim.Y[(sim.N0 + 1):end, 1:sim.T0]'
(
att = round(est.estimate, digits = 3),
pre_rmse = round(prefit_rmse(est.fit, Xpre, Ypre), digits = 3),
selected_lambda = est.fit.lambda,
)(att = 1.016, pre_rmse = 0.051, selected_lambda = 0.02997598394605845)Cross-validation output is stored as a table:
cv_table(est.fit)8×3 DataFrame
| Row | lambda | cv_error | selected |
|---|---|---|---|
| Float64 | Float64 | Bool | |
| 1 | 2.9976 | 5.91776 | false |
| 2 | 1.5526 | 3.69243 | false |
| 3 | 0.804164 | 0.139861 | false |
| 4 | 0.416515 | 0.0205184 | false |
| 5 | 0.215733 | 0.0193637 | false |
| 6 | 0.111738 | 0.0186825 | false |
| 7 | 0.0578746 | 0.0184889 | false |
| 8 | 0.029976 | 0.0168936 | true |
One time-placebo moves the intervention date into the original pre-treatment period:
pl = placebo(est; T0_placebo = 30, lambdas = [est.fit.lambda], max_iter = 700)
round(pl.estimate, digits = 3)0.003A placebo distribution randomly assigns control units to placebo treatment groups:
dist = placebo_distribution(
est;
replications = 10,
ntreated = 3,
lambdas = [est.fit.lambda],
max_iter = 500,
)
(mean = round(mean(dist), digits = 3), se = round(std(dist), digits = 3))(mean = -0.001, se = 0.012)