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_time is 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 pass time_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 exactly treatment_time are 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, a PyMCForecastModel wrapping a pymc_forecast forecasting model can serve as the counterfactual backend (requires the optional pymc-forecast dependency); see causalpy.pymc_forecast_models for when to prefer it.

  • treatment_end_time (int | float | Timestamp | None) – The time when treatment ended, enabling three-period analysis. Must be greater than treatment_time and within the data range. If None (default), the analysis assumes a permanent intervention (two-period design). INCLUSIVE: Observations at exactly treatment_end_time are 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 of data is 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 returns self, so construction and fitting chain in one expression), and optionally sample_prior_predictive() first for prior predictive checks (plot(group="prior"), effect_summary(group="prior")). Results live on exp.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 mu rather than noisy posterior-predictive draws y_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, and effect_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

InterruptedTimeSeries.analyze_persistence([...])

Analyze effect persistence between intervention and post-intervention periods.

InterruptedTimeSeries.build()

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.

InterruptedTimeSeries.print_coefficients([...])

Ask the model to print its posterior coefficients.

InterruptedTimeSeries.sample_prior_predictive(...)

Run the optional prior phase and populate prior_result.

InterruptedTimeSeries.set_maketables_options(*)

Set optional maketables rendering options for this experiment.

InterruptedTimeSeries.summary([round_to])

Print summary of main results and model coefficients.

Attributes

datapost

Data from on or after the treatment time (inclusive).

datapre

Data from before the treatment time (exclusive).

has_prior_predictive

Whether the prior phase has run (draws, and bundle where kept).

idata

Return fitted DataTree when the model backend supports it.

is_built

Whether the model graph / fit design exists (no draws implied).

is_configured

design matrices are ready.

is_fitted

Whether posterior draws and the posterior result bundle exist.

model

The underlying model instance.

prior_result

Prior-group result bundle; raises before prior sampling.

result

Posterior-group result bundle; raises before fit().

supports_bayes

supports_ols

supports_pymc_forecast

labels

data

__init__(data, treatment_time, formula, model=None, treatment_end_time=None, time_column=None)[source]#
Parameters:
Return type:

None

classmethod __new__(*args, **kwargs)#