PlaceboInTime#

class causalpy.checks.placebo_in_time.PlaceboInTime[source]#

Placebo-in-time sensitivity check with hierarchical null model.

Shifts the treatment time backward into the pre-intervention period to create n_folds placebo experiments. Extracts the posterior cumulative impact from each fold, then fits a hierarchical Bayesian model to characterise the “status quo” distribution of effects when no intervention occurred. The actual intervention’s cumulative effect is compared against this learned null.

When expected_effect_prior and rope_half_width are provided, additionally computes Bayesian assurance (operating characteristics) via simulation.

Parameters:
  • n_folds (int) – Number of placebo folds to create. Must be >= 1.

  • selection_method (Literal['sequential', 'random']) –

    How to choose placebo windows.

    • "sequential" — evenly-spaced sliding windows stepping backward from the treatment time (original behaviour).

    • "random" — randomly sample eligible windows from the pre-intervention period, subject to min_training_pct, min_gap, and exclude_periods constraints.

  • min_training_pct (float) –

    (random mode only) Minimum fraction of total pre-period observations that must precede each candidate placebo window.

    Note: the eligible pre-period is further shortened because a candidate’s pseudo-intervention window must also end before the actual treatment. When treatment_end_time is not set on the experiment, intervention_length defaults to data.index.max() - treatment_time (roughly the post-period length), which can make the effective eligible window much smaller than (1 - min_training_pct) suggests.

  • min_gap (int) – (random mode only) Minimum number of pre-intervention observations between any two selected folds, measured as positions in the sorted pre-period index. The default of 1 only forbids picking the same candidate twice; use a larger value to spread folds further apart. When allow_overlap is False (the default) non-overlap of pseudo-intervention windows is enforced independently of min_gap.

  • allow_overlap (bool) – (random mode only) If False (the default), selected pseudo-intervention windows are required to be non-overlapping in index/time units. Two folds at times t_a and t_b are considered non-overlapping when abs(t_a - t_b) >= intervention_length. Set to True to allow overlapping windows, which relaxes the constraint at the cost of violating the exchangeability assumption of the hierarchical status-quo model (each fold mean is treated as an independent draw from a common mu_status_quo).

  • exclude_periods (set[str] | None) – (random mode only) Set of period labels to exclude from candidate selection. For datetime-indexed data, use "YYYY-MM" strings; for numeric indices, use string representations of the index values.

  • experiment_factory (Any | None) – Custom factory (data, treatment_time) -> BaseExperiment. If None (default), the factory is derived from the pipeline’s experiment_config. Required for standalone (non-pipeline) use.

  • sample_kwargs (dict[str, Any] | None) – MCMC settings for the hierarchical status-quo model. Defaults to {"draws": 1000, "chains": 4, "target_accept": 0.97}.

  • threshold (float) – Probability cutoff. Used both for passed (P(actual effect outside null) must exceed this) and for the ROPE decision rule when computing assurance.

  • prior_scale (float) – Multiplier for auto-computed prior widths on the hierarchical model. The priors are mu ~ Normal(center, 5 * prior_scale * data_scale) and tau ~ HalfNormal(2 * prior_scale * data_scale).

  • expected_effect_prior (Any | None) – Prior belief about the true total effect under the alternative hypothesis. Accepts any object with an .rvs(n) method (PreliZ, scipy) or a numpy array of pre-drawn samples. When provided together with rope_half_width, assurance analysis runs automatically.

  • rope_half_width (float | None) – Half-width of the ROPE interval [-rope, +rope]. Required when expected_effect_prior is provided.

  • n_design_replications (int | None) – Number of simulation replications for assurance. Defaults to min(theta_new.size, expected_effect_samples.size).

  • random_seed (int | None) – RNG seed for the assurance simulation and random fold selection.

Examples

>>> import causalpy as cp
>>> check = cp.checks.PlaceboInTime(n_folds=3)

Random selection with constraints:

>>> check = cp.checks.PlaceboInTime(
...     n_folds=4,
...     selection_method="random",
...     min_training_pct=0.30,
...     min_gap=2,
...     random_seed=42,
... )

Methods

PlaceboInTime.bayesian_rope_decision(...)

Apply a ROPE-based Bayesian decision rule.

PlaceboInTime.run(experiment[, context])

Run placebo-in-time analysis with hierarchical null model.

PlaceboInTime.validate(experiment)

Check the experiment is compatible with PlaceboInTime.

Attributes

applicable_methods

__init__(n_folds=3, selection_method='sequential', min_training_pct=0.3, min_gap=1, allow_overlap=False, exclude_periods=None, experiment_factory=None, sample_kwargs=None, threshold=0.95, prior_scale=1.0, expected_effect_prior=None, rope_half_width=None, n_design_replications=None, random_seed=None)[source]#
Parameters:
  • n_folds (int)

  • selection_method (Literal['sequential', 'random'])

  • min_training_pct (float)

  • min_gap (int)

  • allow_overlap (bool)

  • exclude_periods (set[str] | None)

  • experiment_factory (Any | None)

  • sample_kwargs (dict[str, Any] | None)

  • threshold (float)

  • prior_scale (float)

  • expected_effect_prior (Any | None)

  • rope_half_width (float | None)

  • n_design_replications (int | None)

  • random_seed (int | None)

Return type:

None

classmethod __new__(*args, **kwargs)#