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
Rowlambdacv_errorselected
Float64Float64Bool
12.99765.91776false
21.55263.69243false
30.8041640.139861false
40.4165150.0205184false
50.2157330.0193637false
60.1117380.0186825false
70.05787460.0184889false
80.0299760.0168936true

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.003

A 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)