# `causalis.scenarios.cuped.model`

Controlled-experiment Using Pre-Experiment Data (CUPED) scenario.

This module provides the `CUPEDModel` which implements regression-adjusted inference for Randomized Controlled Trials (RCTs) using pre-treatment covariates. It primarily implements the Lin (2013) fully interacted OLS specification, which is a robust generalization of the canonical CUPED estimator.

## Module Contents

### Classes

`CUPEDModel` | CUPED-style regression adjustment estimator for ATE/ITT in randomized experiments.

### API

class causalis.scenarios.cuped.model.CUPEDModel(cov_type: str = 'HC2', alpha: float = 0.05, use_t: Optional[bool] = None, use_t_auto_n_threshold: int = 5000, relative_ci_method: Literal[delta, bootstrap] = 'delta', relative_denominator: Literal[adjusted_control, raw_control] = 'adjusted_control', relative_ci_bootstrap_draws: int = 1000, relative_ci_bootstrap_seed: Optional[int] = None, refutation_config: Optional[causalis.scenarios.cuped.refutation.config.CUPEDRefutationConfig] = None, covariate_variance_min: float = 1e-12)

  CUPED-style regression adjustment estimator for ATE/ITT in randomized experiments.

  The CUPED estimator uses pre-experiment data (covariates) to reduce the variance of the treatment effect estimate without introducing bias. While the canonical CUPED estimator uses a single variance-reduction parameter $\theta$, this implementation follows Lin (2013) and uses a fully interacted OLS specification.

  Notes

  The canonical CUPED adjusted outcome is defined as:

  .. math::

      Y_{cuped} = Y - \theta (X - E[X])

  where $\theta = \frac{Cov(Y, X)}{Var(X)}$ minimizes $Var(Y_{cuped})$.

  This model implements the Lin (2013) specification, which is equivalent to saturated OLS and robust to heterogeneous treatment effects:

  .. math::

      Y = \alpha + \tau D + \beta (X - \bar{X}) + \gamma D(X - \bar{X}) + \epsilon

  where:

  - $D$ is the binary treatment indicator ($D=1$ for treatment, $D=0$ for control).

  - $X$ are the pre-treatment covariates (centered globally).

  - $\tau$ is the Average Treatment Effect (ATE).

  Centering covariates at their global mean $\bar{X}$ ensures that the coefficient $\tau$ on the treatment indicator $D$ directly estimates the ATE.

  Examples

  > > > from causalis.scenarios.cuped.dgp import generate_cuped_tweedie_26 from causalis.scenarios.cuped.model import CUPEDModel from causalis.data_contracts import CausalData

  > > > Generate synthetic data with pre-treatment covariate

  > > > data = generate_cuped_tweedie_26(seed=42, return_causal_data=False) causaldata = CausalData( … df=data, … treatment=’d’, … outcome=’y’, … confounders=[‘y_pre’] … )

  > > > Fit CUPED model adjusting for ‘y_pre’

  > > > model = CUPEDModel().fit(causaldata, covariates=[‘y_pre’])

  > > > Estimate ATE

  > > > estimate = model.estimate() print(f”ATE: {estimate.value:.4f}”) ATE: 0.6937 print(f”P-value: {estimate.p_value:.4f}”) P-value: 0.0000

  Parameters

  cov_type : str, default=”HC2” Covariance estimator passed to statsmodels (e.g., “nonrobust”, “HC0”, “HC1”, “HC2”, “HC3”). Note: for cluster-randomized designs, use cluster-robust SEs (not implemented here). alpha : float, default=0.05 Significance level for confidence intervals. use_t : bool | None, default=None If bool, passed to statsmodels `.fit(..., use_t=use_t)` directly. If None, automatic policy is used: for robust HC* covariances, `use_t=True` when `n < use_t_auto_n_threshold`, else `False`. For non-robust covariance, `use_t=True`. use_t_auto_n_threshold : int, default=5000 Sample-size threshold for automatic `use_t` selection when `use_t=None` and covariance is HC* robust. relative_ci_method : {“delta”, “bootstrap”}, default=”delta” Method for relative CI of `100 * tau / denominator`. - “delta”: joint delta method that accounts for covariance between the adjusted ATE and the selected denominator. - “bootstrap”: percentile bootstrap CI on the relative effect. relative_denominator : {“adjusted_control”, “raw_control”}, default=”adjusted_control” Denominator used for relative effects. - “adjusted_control”: model-implied control mean at the full-sample covariate mean. - “raw_control”: observed control-group outcome mean. relative_ci_bootstrap_draws : int, default=1000 Number of bootstrap resamples used when `relative_ci_method="bootstrap"`. relative_ci_bootstrap_seed : int | None, default=None RNG seed used for bootstrap relative CI. refutation_config : CUPEDRefutationConfig | None, default=None Grouped configuration for regression checks, refutation thresholds, and check actions. covariate_variance_min : float, default=1e-12 Minimum variance threshold for retaining a CUPED covariate. Covariates with variance less than or equal to this threshold are dropped before fitting.

  Notes

  - Validity requires covariates be pre-treatment. Post-treatment covariates can bias estimates.

  - Covariates are globally centered over the full sample only. This centering convention is required so the treatment coefficient in the Lin specification remains the ATE/ITT.

  - The Lin (2013) specification is recommended as a robust regression-adjustment default in RCTs.

  Initialization

  fit(data: causalis.dgp.causaldata.CausalData, covariates: Optional[Sequence[str]] = None, run_checks: Optional[bool] = None) → causalis.scenarios.cuped.model.CUPEDModel

    Fit CUPED-style regression adjustment (Lin-interacted OLS) on a CausalData object.

    Parameters

    data : CausalData Validated dataset with columns: outcome (post), treatment, and confounders (pre covariates). covariates : Sequence[str], required Explicit subset of `data_contracts.confounders_names` to use as CUPED covariates. Pass `[]` for an unadjusted (naive) fit. run_checks : bool | None, optional Override whether regression checks are computed in this fit call. If `None`, uses `self.refutation_config.run_regression_checks`.

    Returns

    CUPEDModel Fitted estimator.

    Raises

    ValueError If `covariates` is omitted, not a sequence of strings, contains columns missing from the DataFrame, contains columns outside `data_contracts.confounders_names`, or the design matrix is rank deficient.

  estimate(alpha: Optional[float] = None, diagnostic_data: bool = True) → causalis.data_contracts.causal_estimate.CausalEstimate

    Return the adjusted ATE/ITT estimate and inference.

    Parameters

    alpha : float, optional Override the instance significance level for confidence intervals. diagnostic_data : bool, default True Whether to include diagnostic data_contracts in the result.

    Returns

    CausalEstimate A results object containing effect estimates and inference.

  summary_dict(alpha: Optional[float] = None) → Dict[str, Any]

    Convenience JSON/logging output.

    Parameters

    alpha : float, optional Override the instance significance level for confidence intervals.

    Returns

    dict Dictionary with estimates, inference, and refutation checks.

  assumptions_table() → Optional[pandas.DataFrame]

    Return fitted regression assumptions table (GREEN/YELLOW/RED) when available.

  __repr__() → str