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.