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

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}
...     ),
... )

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,
... )
>>> # Get period-specific effect summaries
>>> intervention_summary = result.effect_summary(period="intervention")
>>> post_summary = result.effect_summary(period="post")

Methods

InterruptedTimeSeries.algorithm()

Run the experiment algorithm: fit model, predict, and calculate causal impact.

InterruptedTimeSeries.analyze_persistence([...])

Analyze effect persistence between intervention and post-intervention periods.

InterruptedTimeSeries.effect_summary(*[, ...])

Generate a decision-ready summary of causal effects for Interrupted Time Series.

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(*[, round_to, ...])

Plot the interrupted time-series results.

InterruptedTimeSeries.print_coefficients([...])

Ask the model to print its coefficients.

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).

idata

Return fitted DataTree when the model backend supports it.

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)#