diff_diff.SyntheticControl#

class diff_diff.SyntheticControl[source]#

Bases: object

Classic Synthetic Control Method estimator (Abadie-Diamond-Hainmueller 2010).

Parameters:
  • v_method ({"nested", "custom", "cv", "inverse_variance"}, default "nested") – How the predictor-importance matrix V is chosen. "nested" selects V data-driven by minimizing the pre-period outcome MSPE of W*(V) (ADH 2010 §2.3). "custom" uses the user-supplied custom_v and skips the outer search. "cv" selects V by out-of-sample cross-validation (ADH 2015 §; Abadie 2021 Eq. 9): the pre-period is split at v_cv_t0 into a training and a validation window; V is chosen to minimize the validation-window outcome MSPE of the training-fit weights, then the final weights are re-estimated on the validation-window predictors. "inverse_variance" uses the closed-form v_h = 1/Var(X_{h·}) (Abadie 2021 §3.2(a); variance over donors+treated), applied to the RAW predictors so the effective objective is the unit-variance-rescaled Σ_h diff_h²/Var_h — no search, deterministic. Note this rescaling is what standardize="std" does, so the standardize setting does not compose with it (equivalent to uniform V on standardized predictors); applying 1/Var on already-standardized rows would double-rescale to Σ_h diff_h²/Var_h².

  • custom_v (array-like, optional) – Diagonal of V (length = number of predictors). Required iff v_method="custom"; must be None for every other v_method (nested / cv / inverse_variance). Must be finite and non-negative; trace-normalized internally.

  • optimizer_options (dict, optional) – Extra options merged into every scipy.optimize.minimize call in the outer V search (e.g. maxiter, xatol, fatol).

  • n_starts (int, default 4) – Number of starting points for the multistart outer V search.

  • inner_max_iter (int, default 10000) – Max iterations for the inner Frank-Wolfe simplex solve.

  • inner_min_decrease (float, default 1e-5) – Inner-solve convergence scale (matches the SDID/Frank-Wolfe precedent in prep.py). The Frank-Wolfe stop threshold is (inner_min_decrease * max(||b||, 1e-12))**2 where b is the V^½-scaled treated predictor vector — scale-aware so convergence is meaningful at any data magnitude. 1e-5 reproduces R Synth’s donor weights to ~1e-4 on the Basque benchmark while still signalling convergence; tighter values (e.g. 1e-6) can exhaust inner_max_iter.

  • standardize ({"std", "none"}, default "std") – Predictor standardization. "std" divides each predictor row by its standard deviation across donors+treated (ddof=1), matching R Synth. "none" is a deviation from R (see REGISTRY).

  • alpha (float, default 0.05) – Significance level recorded for downstream (placebo) inference.

  • seed (int, optional) – Seed for the multistart random (Dirichlet) starting points.

  • v_cv_t0 (int, optional) – Training/validation split index for v_method="cv" only (positional into the pre-periods: training = pre[:v_cv_t0], validation = pre[v_cv_t0:]). Must leave at least 1 training and 1 validation pre-period. Default None → len(pre_periods) // 2 (Abadie 2021’s t0 = T0/2). Must be None unless v_method="cv".

Methods

__init__([v_method, custom_v, ...])

fit(data, outcome, treatment, unit, time, *)

Fit the classic synthetic control model.

get_params()

Get estimator parameters.

set_params(**params)

Set estimator parameters.

__init__(v_method='nested', custom_v=None, optimizer_options=None, n_starts=4, inner_max_iter=10000, inner_min_decrease=1e-05, standardize='std', alpha=0.05, seed=None, v_cv_t0=None)[source]#
Parameters:
  • v_method (str)

  • custom_v (Any | None)

  • optimizer_options (Dict[str, Any] | None)

  • n_starts (int)

  • inner_max_iter (int)

  • inner_min_decrease (float)

  • standardize (str)

  • alpha (float)

  • seed (int | None)

  • v_cv_t0 (int | None)

classmethod __new__(*args, **kwargs)#