diff_diff.SyntheticControlResults#

class diff_diff.SyntheticControlResults[source]#

Bases: object

Results from a classic Synthetic Control Method (SCM) estimation.

Implements Abadie, Diamond & Hainmueller (2010), “Synthetic Control Methods for Comparative Case Studies.” A single treated unit’s counterfactual is the convex combination Σ_j w_j · Y_jt of donor units chosen to match the treated unit’s pre-period outcomes and predictors; the treatment effect path is the gap α̂_1t = Y_1t Σ_j w_j · Y_jt over the post periods.

att#

Average post-period gap (the reported point estimate). The per-period gaps are in gap_path.

Type:

float

se#

Always NaN — classic SCM has no analytical standard error (inference is permutation/placebo based; see Abadie-Diamond-Hainmueller 2010 §2.4).

Type:

float

t_stat, p_value

Always NaN (no analytical SE).

Type:

float

conf_int#

Always (NaN, NaN) (no analytical SE).

Type:

tuple[float, float]

n_obs#

Number of observations (treated + donor rows over all periods) used.

Type:

int

n_donors#

Number of donor units in the (post-filter) donor pool.

Type:

int

n_pre_periods#

Number of pre-treatment periods.

Type:

int

n_post_periods#

Number of post-treatment periods.

Type:

int

donor_weights#

Mapping {donor_unit_id: weight} on the unit simplex. Weights below the interpretability floor (1e-6) are dropped.

Type:

dict

v_weights#

Mapping {predictor_label: v} — the diagonal predictor-importance matrix V, trace-normalized to sum to 1. On the degenerate single-donor path (one donor forces w=[1]) V is unidentified — every V yields the same synthetic — so v_weights is uniform for every v_method (including cv / inverse_variance), with a UserWarning emitted at fit time.

Type:

dict

predictor_balance#

Predictor-balance table: for each predictor, the treated value, the synthetic value (donor-weighted), and the donor-pool mean. Under v_method="cv" the reported donor_weights come from the ADH-2015 step-4 refit on the validation-window re-aggregated predictors, so the treated / synthetic / donor_mean values are reported on that same validation-window basis (each spec re-aggregated over pre[v_cv_t0:]) — the row’s predictor label remains the full spec identity, so it stays aligned with v_weights. For every other v_method the values are the full-pre-period predictor aggregates.

Type:

pandas.DataFrame

gap_path#

Mapping {period: gap} for ALL periods (pre periods carry the fit residual used for pre_rmspe; post periods carry the effect path).

Type:

dict

pre_rmspe#

Root mean squared prediction error over the pre-treatment periods (the primary fit diagnostic).

Type:

float

mspe_v#

The outer-objective value of the selected V: the pre-period outcome MSPE of W*(V*) under v_method="nested", or the held-out validation-window outcome MSPE under v_method="cv" (the CV selection criterion). None when there is no outer search — the v_method="custom" and "inverse_variance" paths and the degenerate single-donor path. Not comparable across v_method values (different objective windows).

Type:

float, optional

treated_unit#

The treated unit’s identifier.

Type:

Any

pre_periods, post_periods

Calendar-sorted pre / post period values.

Type:

list

v_method#

"nested" (data-driven V), "custom" (user-supplied V), "cv" (out-of-sample cross-validation V), or "inverse_variance" (closed-form 1/Var(X) V).

Type:

str

v_cv_t0#

The training/validation split index actually used under v_method="cv" (the resolved value — equals n_pre_periods // 2 when the constructor’s v_cv_t0 was None). None for every other v_method. Survives pickling.

Type:

int, optional

standardize#

"std" (per-row SD scaling) or "none".

Type:

str

alpha#

Significance level recorded for downstream (placebo) inference.

Type:

float

rmspe_ratio#

The treated unit’s post/pre RMSPE ratio = sqrt(MSPE_post / MSPE_pre) — the in-space placebo test statistic (ADH 2010 §2.4), computed at fit time.

Type:

float

placebo_p_value#

In-space placebo permutation p-value (rank / (n_placebos + 1)), NaN until in_space_placebo() is run. SEPARATE from the (always-NaN) analytical p_value; is_significant stays bound to p_value.

Type:

float

n_placebos, n_failed

Donor placebos that entered the permutation reference set / were excluded for non-convergence. Both 0 until in_space_placebo() is run.

Type:

int

survey_metadata#

Reserved; always None in this release.

Type:

Any, optional

Significance for classic SCM comes from :meth:`in_space_placebo` (opt-in
in-space placebo permutation inference); :meth:`get_placebo_df` returns the
per-unit RMSPE-ratio table used for the rank.

Methods

__init__(att, se, t_stat, p_value, conf_int, ...)

get_gap_df()

Get the gap (effect) path as a DataFrame, in calendar order.

get_in_time_placebo_df()

Get the in-time placebo table (see in_time_placebo()).

get_in_time_placebo_gaps()

Long-form in-time placebo gap paths, for the backdating overlay plot.

get_leave_one_out_df()

Get the leave-one-out donor-robustness table (see leave_one_out()).

get_leave_one_out_gaps()

Long-form leave-one-out gap paths, for the overlay ("spaghetti") plot.

get_placebo_df()

Get the in-space placebo distribution as a DataFrame (one row per unit).

get_weights_df()

Get donor weights as a DataFrame, sorted by weight descending.

in_space_placebo([n_starts])

In-space placebo permutation inference (Abadie-Diamond-Hainmueller 2010, Section 2.4).

in_time_placebo([placebo_periods, n_starts])

In-time (backdating) placebo (Abadie-Diamond-Hainmueller 2015, Section 4).

leave_one_out([n_starts])

Leave-one-out donor robustness (Abadie-Diamond-Hainmueller 2015, Section 4).

print_summary([alpha])

Print the summary to stdout.

summary([alpha])

Generate a formatted summary of the estimation results.

to_dataframe()

Convert scalar results to a single-row pandas DataFrame.

to_dict()

Convert scalar results to a dictionary.

Attributes

alpha

coef_var

SE / abs(ATT).

is_significant

Always False — classic SCM produces no analytical p-value.

mspe_v

n_failed

n_placebos

placebo_p_value

rmspe_ratio

significance_stars

Significance stars based on p-value (empty here — p_value is NaN).

survey_metadata

v_cv_t0

att

se

t_stat

p_value

conf_int

n_obs

n_donors

n_pre_periods

n_post_periods

donor_weights

v_weights

predictor_balance

gap_path

pre_rmspe

treated_unit

pre_periods

post_periods

v_method

standardize

__init__(att, se, t_stat, p_value, conf_int, n_obs, n_donors, n_pre_periods, n_post_periods, donor_weights, v_weights, predictor_balance, gap_path, pre_rmspe, treated_unit, pre_periods, post_periods, v_method, standardize, alpha=0.05, mspe_v=None, v_cv_t0=None, survey_metadata=None, placebo_p_value=nan, rmspe_ratio=nan, n_placebos=0, n_failed=0)#
Parameters:
Return type:

None

classmethod __new__(*args, **kwargs)#