SyntheticDifferenceInDifferences#
- class causalpy.experiments.synthetic_difference_in_differences.SyntheticDifferenceInDifferences[source]#
Bayesian Synthetic Difference-in-Differences experiment.
Combines the synthetic control method’s unit weighting with difference-in-differences time weighting. The treatment effect (tau) is computed analytically from the posterior weight distributions via the double-difference formula, rather than being estimated inside the MCMC model (cut-posterior formulation).
- Parameters:
data (
DataFrame) – A dataframe in wide format (columns = units, rows = time periods).treatment_time (
int|float|Timestamp) – The time when treatment occurred, should be in reference to the data index.control_units (
list[str]) – A list of control unit column names.treated_units (
list[str]) – A list of treated unit column names.model (
PyMCModel|RegressorMixin|None) – ASyntheticDifferenceInDifferencesWeightFitterinstance. Defaults toSyntheticDifferenceInDifferencesWeightFitter.**kwargs (
dict) – Additional keyword arguments (currently unused).
Notes
Estimate extraction
The Bayesian weight model produces posterior draws of synthetic-control unit weights and pre-period time weights. For each draw, the class constructs treated-minus-synthetic gaps and evaluates the weighted double-difference analytically to obtain the scalar
tau_posteriorATT; the effect is not read from a regression coefficient or obtained by population-standardized g-computation. The time-indexedpost_impactconsumed byeffect_summary()is the post-period treated-minus-synthetic trajectory rather than this time-weighted scalar.This implements Bayesian SDiD method. The model fits two weight modules via MCMC:
Unit weights (omega): balance control units against treated units in the pre-treatment period, similar to synthetic control.
Time weights (lambda): balance pre-treatment periods against post-treatment periods for control units.
The treatment effect is then computed analytically via the double-difference:
\[\tau = \bar{\Delta}_{\text{post}} - \boldsymbol{\lambda}^\top \boldsymbol{\Delta}_{\text{pre}}\]where \(\Delta_t = y_{\text{tr},t} - (\omega_0 + \boldsymbol{\omega}^\top \mathbf{Y}_{\text{co},t})\) is the gap between the observed treated outcome and the synthetic control at time t.
References
Examples
>>> import causalpy as cp >>> df = cp.load_data("sc") >>> treatment_time = 70 >>> result = cp.SyntheticDifferenceInDifferences( ... df, ... treatment_time, ... control_units=["a", "b", "c", "d", "e", "f", "g"], ... treated_units=["actual"], ... model=cp.pymc_models.SyntheticDifferenceInDifferencesWeightFitter( ... sample_kwargs={ ... "tune": 20, ... "draws": 20, ... "chains": 2, ... "cores": 2, ... "progressbar": False, ... } ... ), ... )
Methods
Run the SDiD algorithm: fit weight modules, compute tau analytically.
Generate a decision-ready summary of causal effects for SDiD.
SyntheticDifferenceInDifferences.fit(*args, ...)Fit the underlying model.
Generate a self-contained HTML report for this experiment.
Recover the data of an experiment along with the prediction and causal impact information.
Validate the input data for correctness.
SyntheticDifferenceInDifferences.plot(*[, ...])Plot SDiD results: counterfactual, period impact, and cumulative impact.
Ask the model to print its coefficients.
Set optional maketables rendering options for this experiment.
Print summary of main results.
Attributes
datapostData from on or after the treatment time (inclusive).
datapreData from before the treatment time (exclusive).
idataReturn fitted InferenceData when the model backend supports it.
supports_bayessupports_olssupports_pymc_forecastlabelsdata- classmethod __new__(*args, **kwargs)#