InterruptedTimeSeries#
- class causalpy.experiments.interrupted_time_series.InterruptedTimeSeries[source]#
The class for interrupted time series analysis.
Supports both two-period (permanent intervention) and three-period (temporary intervention) designs. When
treatment_end_timeis provided, the analysis splits the post-intervention period into an intervention period and a post-intervention period, enabling analysis of effect persistence and decay.- Parameters:
data (
NativeDataFrame) – Time series data as any eager dataframe Narwhals supports. For a pandas dataframe the index carries the time axis, and it should be either a DatetimeIndex or numeric (integer/float), with unique values in monotonically increasing order. Dataframes from other libraries have no index, so those callers must passtime_column.treatment_time (
int|float|Timestamp) – The time when treatment occurred, should be in reference to the data index. Must match the index type (DatetimeIndex requires pd.Timestamp). INCLUSIVE: Observations at exactlytreatment_timeare included in the post-intervention period (uses>=comparison).formula (
str) – A statistical model formula using patsy syntax (e.g., “y ~ 1 + t + C(month)”).model (
PyMCModel|RegressorMixin|PyMCForecastModel|None) – A PyMC (Bayesian) or sklearn (OLS) model. If None, defaults to a PyMC LinearRegression model. Alternatively, aPyMCForecastModelwrapping apymc_forecastforecasting model can serve as the counterfactual backend (requires the optionalpymc-forecastdependency); seecausalpy.pymc_forecast_modelsfor when to prefer it.treatment_end_time (
int|float|Timestamp|None) – The time when treatment ended, enabling three-period analysis. Must be greater thantreatment_timeand within the data range. If None (default), the analysis assumes a permanent intervention (two-period design). INCLUSIVE: Observations at exactlytreatment_end_timeare included in the post-intervention period (uses>=comparison).time_column (
str|None) – Column holding the time axis. It becomes the index of the data. Required for non-pandas inputs, which carry no index. If None (default), the pandas index ofdatais used. Passing it for data that already has a meaningful index raises, since only one of the two can be the time axis.
Notes
Lazy lifecycle
Construction only validates input and builds design matrices — nothing is sampled. Call
fit()to run posterior inference (it returnsself, so construction and fitting chain in one expression), and optionallysample_prior_predictive()first for prior predictive checks (plot(group="prior"),effect_summary(group="prior")). Results live onexp.result/exp.prior_result.Estimate extraction
The model is fitted to pre-intervention observations and predicts the untreated trajectory after the intervention. Pointwise impact is the observed post-intervention outcome minus that one-sided counterfactual prediction, and cumulative impact is its running sum. Bayesian backends subtract the posterior conditional expectation
murather than noisy posterior-predictive drawsy_hat; OLS subtracts its point prediction.This fit-predict-subtract procedure is a reduced-form estimator. From a Bayesian structural perspective, the same impact can be viewed as the response to an intervention shock in a state-space model of the outcome series; see the knowledgebase page on structural causal models for the reduced-form versus structural distinction.
The three-period design is useful for analyzing temporary interventions such as:
Marketing campaigns with defined start and end dates
Policy trials or pilot programs
Clinical treatments with limited duration
Seasonal interventions
Use
effect_summary(period="intervention")to analyze effects during the intervention, andeffect_summary(period="post")to analyze effect persistence after the intervention ends.Examples
Two-period design (permanent intervention):
>>> import causalpy as cp >>> df = ( ... cp.load_data("its") ... .assign(date=lambda x: pd.to_datetime(x["date"])) ... .set_index("date") ... ) >>> treatment_time = pd.to_datetime("2017-01-01") >>> result = cp.InterruptedTimeSeries( ... df, ... treatment_time, ... formula="y ~ 1 + t + C(month)", ... model=cp.pymc_models.LinearRegression( ... sample_kwargs={"random_seed": 42, "progressbar": False} ... ), ... ).fit()
Three-period design (temporary intervention):
>>> treatment_time = pd.to_datetime("2017-01-01") >>> treatment_end_time = pd.to_datetime("2017-06-01") >>> result = cp.InterruptedTimeSeries( ... df, ... treatment_time, ... formula="y ~ 1 + t + C(month)", ... model=cp.pymc_models.LinearRegression( ... sample_kwargs={"random_seed": 42, "progressbar": False} ... ), ... treatment_end_time=treatment_end_time, ... ).fit() >>> # Get period-specific effect summaries >>> intervention_summary = result.effect_summary(period="intervention") >>> post_summary = result.effect_summary(period="post")
Methods
Analyze effect persistence between intervention and post-intervention periods.
Construct the model graph without sampling anything.
InterruptedTimeSeries.effect_summary(*[, ...])Generate a decision-ready summary of causal effects for Interrupted Time Series.
InterruptedTimeSeries.fit(**kwargs)Run the posterior phase and populate
result.InterruptedTimeSeries.generate_report(*[, ...])Generate a self-contained HTML report for this experiment.
InterruptedTimeSeries.get_plot_data(*[, ...])Recover the data of the experiment along with the prediction and causal impact information.
InterruptedTimeSeries.input_validation(data, ...)Validate the input data and model formula for correctness.
InterruptedTimeSeries.plot(*[, group, ...])Plot the interrupted time-series results.
Ask the model to print its posterior coefficients.
Run the optional prior phase and populate
prior_result.Set optional maketables rendering options for this experiment.
InterruptedTimeSeries.summary([round_to])Print summary of main results and model coefficients.
Attributes
datapostData from on or after the treatment time (inclusive).
datapreData from before the treatment time (exclusive).
has_prior_predictiveWhether the prior phase has run (draws, and bundle where kept).
idataReturn fitted DataTree when the model backend supports it.
is_builtWhether the model graph / fit design exists (no draws implied).
is_configureddesign matrices are ready.
is_fittedWhether posterior draws and the posterior result bundle exist.
modelThe underlying model instance.
prior_resultPrior-group result bundle; raises before prior sampling.
resultPosterior-group result bundle; raises before
fit().supports_bayessupports_olssupports_pymc_forecastlabelsdata- __init__(data, treatment_time, formula, model=None, treatment_end_time=None, time_column=None)[source]#
- Parameters:
data (DataFrameLike)
formula (str)
model (PyMCModel | RegressorMixin | PyMCForecastModel | None)
time_column (str | None)
- Return type:
None
- classmethod __new__(*args, **kwargs)#