Skip to content

Causal impact

polars_ts.causal.causal_impact

CausalImpact: Bayesian causal inference for intervention analysis.

Estimates the causal effect of an intervention on a time series using a Bayesian structural time series (BSTS) counterfactual model. The pre-intervention period trains the model; the post-intervention counterfactual projection is subtracted from the observed series to yield the estimated treatment effect with credible intervals.

Design notes (from issue #148 feedback): - Returns (point, lower, upper) from day one — no bolt-on bootstrap. - Exposes full BSTS spec so priors are never hidden. - Pre-period diagnostics run by default. - Built-in placebo tests via placebo_test. - Covariates with covariate_role guard to prevent post-treatment bias (issue #185).

References

Brodersen et al. (2015). Inferring causal impact using Bayesian structural time series models. Annals of Applied Statistics.

_FitState dataclass

Internal per-series fit state.

CausalImpact

Bases: CausalImpactReportingMixin

Bayesian CausalImpact estimator.

Parameters

trend BSTS trend type: "level" or "local_linear". seasonal Number of seasons for the BSTS seasonal component. None disables seasonality. sigma_obs Observation noise standard deviation. sigma_level Level component noise standard deviation. sigma_trend Trend component noise standard deviation. sigma_seasonal Seasonal component noise standard deviation. coverage Credible interval coverage (e.g. 0.9 for 90%). covariates Column names of exogenous covariates. When provided, an OLS regression is fit on the pre-period, and the regression component is added to the BSTS counterfactual. covariate_role Mapping from covariate name to role:

- ``"always"``: covariate is used in both pre- and post-period.
- ``"pre_only"``: covariate is used only for pre-period fitting
  and excluded from post-period counterfactual projection
  (prevents post-treatment bias).

Covariates not listed default to ``"always"`` with a warning.

id_col Column identifying each time series. time_col Column with timestamps. target_col Column with observed values.

Notes

The BSTS prior hyperparameters (sigma_*) are exposed explicitly because the posterior interval is dominated by the prior when the pre-period is short (<60 observations). Always inspect pre_mape and pre_coverage diagnostics before trusting effect estimates.

Post-treatment covariates must be excluded from the counterfactual because they encode the treatment effect as a nuisance variable, biasing the estimate toward zero. Use covariate_role="pre_only" for any variable that may be affected by the intervention.

fit(df, intervention_date)

Fit the causal impact model.

Parameters

df Panel DataFrame with id_col, time_col, target_col, and any columns listed in covariates. Must contain both pre- and post-intervention observations. intervention_date The first date/time of the post-intervention period. All observations with time_col >= intervention_date are treated as post-intervention.

Returns

CausalImpact Self, for chaining.

_validate_covariate_roles(covariates, covariate_role)

Validate and return resolved covariate roles.

Raises warnings for covariates without explicit role assignment.

_fit_regression(pre_y, pre_X)

Fit demeaned OLS regression on pre-period data.

Demeaning avoids the regression absorbing the level/trend that the BSTS model should capture. Returns (beta, X_mean, y_mean) where beta is shape (n_covariates,).

causal_impact(df, intervention_date, trend='local_linear', seasonal=None, sigma_obs=1.0, sigma_level=0.1, sigma_trend=0.01, sigma_seasonal=0.01, coverage=0.9, covariates=None, covariate_role=None, id_col='unique_id', time_col='ds', target_col='y')

Estimate the causal effect of an intervention on time series.

Convenience function wrapping :class:CausalImpact.

Parameters

df Panel DataFrame. intervention_date First date of the post-intervention period. trend, seasonal, sigma_obs, sigma_level, sigma_trend, sigma_seasonal BSTS model configuration (see :class:CausalImpact). coverage Credible interval coverage. covariates Column names of exogenous covariates. covariate_role Mapping from covariate name to "pre_only" or "always". id_col, time_col, target_col Column names.

Returns

dict[Any, CausalImpactResult] Mapping from series ID to result.