causalis.scenarios.unconfoundedness.refutation.unconfoundedness.sensitivity

Sensitivity functions refactored into a dedicated module.

This module centralizes bias-aware sensitivity helpers and the public entry points used by refutation utilities for unconfoundedness.

Module Contents

Functions

compute_irm_sensitivity_elements

Compute DoubleML-style sensitivity elements for binary-treatment IRM.

compute_bias_aware_ci

Compute bias-aware confidence intervals.

format_bias_aware_summary

Render a single, unified bias-aware summary string.

get_sensitivity_summary

Render a single, unified bias-aware summary string.

sensitivity_benchmark

Benchmark confounders one by one by refitting a short IRM that excludes each requested confounder from the supplied CausalData.

sensitivity_analysis

Compute bias-aware components and cache them.

interpret_sensitivity_analysis

Run sensitivity analysis and return a structured interpretation.

Data

__all__

API

causalis.scenarios.unconfoundedness.refutation.unconfoundedness.sensitivity.__all__

[‘sensitivity_analysis’, ‘sensitivity_benchmark’, ‘get_sensitivity_summary’, ‘interpret_sensitivity_…

causalis.scenarios.unconfoundedness.refutation.unconfoundedness.sensitivity.compute_irm_sensitivity_elements(*, model: Any, y: numpy.ndarray, d: numpy.ndarray, g0: numpy.ndarray, g1: numpy.ndarray, m_hat: numpy.ndarray, w: Optional[numpy.ndarray] = None, w_bar: Optional[numpy.ndarray] = None, psi: Optional[numpy.ndarray] = None, inv_m: Optional[numpy.ndarray] = None, inv_1m: Optional[numpy.ndarray] = None, score: Any = 'ATE') dict[str, Any]

Compute DoubleML-style sensitivity elements for binary-treatment IRM.

causalis.scenarios.unconfoundedness.refutation.unconfoundedness.sensitivity.compute_bias_aware_ci(effect_estimation: Dict[str, Any] | Any, *, r2_y: float, r2_d: float, rho: float = 1.0, H0: float = 0.0, alpha: float = 0.05, use_signed_rr: bool = False) Dict[str, Any]

Compute bias-aware confidence intervals.

Returns a dict with:

  • theta, se, alpha, z

  • sampling_ci

  • theta_bounds_cofounding = [theta_lower, theta_upper] = theta ± bound_width

  • bias_aware_ci = [theta - (bound_width + zse), theta + (bound_width + zse)]

  • max_bias_base, max_bias, bound_width and components (sigma2, nu2)

Parameters

effect_estimation : Dict[str, Any] or Any The effect estimation object. r2_y : float Sensitivity parameter for the outcome (R^2 form, R_Y^2). r2_d : float Sensitivity parameter for the treatment (R^2 form, R_D^2). rho : float, default 1.0 Correlation parameter. H0 : float, default 0.0 Null hypothesis for robustness values. alpha : float, default 0.05 Significance level. use_signed_rr : bool, default False Whether to use signed rr in the quadratic combination of sensitivity components. If True and m_alpha/rr are available, the bias bound is computed via the per-unit quadratic form and RV/RVa are not reported.

Returns

dict Dictionary with bias-aware results.

causalis.scenarios.unconfoundedness.refutation.unconfoundedness.sensitivity.format_bias_aware_summary(res: Dict[str, Any], label: str | None = None) str

Render a single, unified bias-aware summary string.

Parameters

res : Dict[str, Any] The result dictionary from compute_bias_aware_ci. label : str, optional, default None The label for the estimand.

Returns

str Formatted summary string.

causalis.scenarios.unconfoundedness.refutation.unconfoundedness.sensitivity.get_sensitivity_summary(effect_estimation: Dict[str, Any] | Any, *, label: Optional[str] = None) Optional[str]

Render a single, unified bias-aware summary string.

If bias-aware components are missing, shows a sampling-only variant with max_bias=0 and then formats via format_bias_aware_summary for consistency.

Parameters

effect_estimation : Dict[str, Any] or Any The effect estimation object. label : str, optional, default None The label for the estimand.

Returns

Optional[str] Formatted summary string or None if extraction fails.

causalis.scenarios.unconfoundedness.refutation.unconfoundedness.sensitivity.sensitivity_benchmark(effect_estimation: Dict[str, Any] | Any, data: causalis.dgp.causaldata.CausalData, benchmarking_set: List[str] | Literal[all], fit_args: Optional[Dict[str, Any]] = None) pandas.DataFrame

Benchmark confounders one by one by refitting a short IRM that excludes each requested confounder from the supplied CausalData.

This function intentionally performs a genuine short-model refit for every benchmarked confounder because theta_short and delta are defined by that re-estimation step. The residual-based strengths alone are not enough to recover those values.

Parameters

effect_estimation : dict or Any Estimate/model container exposing a fitted IRM-like model. data : CausalData The causal dataset used for benchmarking. It must match the fitted long model on treatment, outcome, confounders, and row order. benchmarking_set : list[str] or “all” Confounders to benchmark one by one. Passing "all" benchmarks every confounder in data.confounders in that order. fit_args : dict, optional Additional keyword arguments passed to IRM.estimate(...) on each short model. If score is omitted, ATE/ATTE is inferred from the supplied estimate/model, and defaults to ATE. If store_diagnostics or legacy diagnostic_data is omitted, the short benchmark refits use store_diagnostics=False by default.

Returns

pandas.DataFrame A long-form DataFrame with one row per benchmarked confounder and columns benchmark_confounder, r2_y, r2_d, rho, theta_long, theta_short, and delta.

causalis.scenarios.unconfoundedness.refutation.unconfoundedness.sensitivity.sensitivity_analysis(effect_estimation: Dict[str, Any] | Any, *, r2_y: float, r2_d: float, rho: float = 1.0, H0: float = 0.0, alpha: float = 0.05, use_signed_rr: bool = False) Dict[str, Any]

Compute bias-aware components and cache them.

This function turns a fitted estimate into a simple hidden-confounding
stress test. In the default mode, the bound width is

.. math::

    |

ho| \cdot \sqrt{\sigma^2 u^2} \cdot \sqrt{ rac{r2_y}{1-r2_y} rac{r2_d}{1-r2_d}},

so the reported confounding interval is

.. math::

    [       heta -  ext{bound\_width},      heta +  ext{bound\_width}].

Here :math:`r2_y` controls how much residual outcome variation an omitted
confounder could explain, :math:`r2_d` does the same for treatment
assignment, and :math:`

ho` sets the sign and strength alignment between the two channels.

Parameters
----------
effect_estimation : Dict[str, Any] or Any
    The effect estimation object.
r2_y : float
    Sensitivity parameter for the outcome (R^2 form, R_Y^2; converted to odds form internally).
r2_d : float
    Sensitivity parameter for the treatment (R^2 form, R_D^2).
rho : float, default 1.0
    Correlation parameter.
H0 : float, default 0.0
    Null hypothesis for robustness values.
alpha : float, default 0.05
    Significance level.
use_signed_rr : bool, default False
    Whether to use signed rr in the quadratic combination of sensitivity components.
    If True and m_alpha/rr are available, the bias bound is computed via the
    per-unit quadratic form and RV/RVa are not reported.

Returns
-------
dict
    Dictionary with bias-aware results:
      - theta, se, alpha, z
      - sampling_ci
      - theta_bounds_cofounding = (theta - bound_width, theta + bound_width)
      - bias_aware_ci = faithful CI for the bounds
      - max_bias and components (sigma2, nu2)
      - params (r2_y, r2_d, rho, use_signed_rr)

Examples
--------
>>> from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
>>> from causalis.dgp import obs_linear_26_dataset
>>> from causalis.scenarios.unconfoundedness.model import IRM
>>> data = obs_linear_26_dataset(
...     n=1000,
...     seed=3141,
...     include_oracle=False,
...     return_causal_data=True,
... )
>>> irm = IRM(
...     data=data,
...     ml_g=RandomForestRegressor(
...         n_estimators=200,
...         max_depth=6,
...         min_samples_leaf=5,
...         random_state=3141,
...     ),
...     ml_m=RandomForestClassifier(
...         n_estimators=200,
...         max_depth=6,
...         min_samples_leaf=5,
...         random_state=3141,
...     ),
...     n_folds=3,
...     random_state=3141,
... )
>>> estimate = irm.fit().estimate(score="ATE")
>>> out = sensitivity_analysis(estimate, r2_y=0.02, r2_d=0.02, rho=1.0)
>>> out["theta_bounds_cofounding"]  # doctest: +SKIP
>>> out["bias_aware_ci"]  # doctest: +SKIP
causalis.scenarios.unconfoundedness.refutation.unconfoundedness.sensitivity.interpret_sensitivity_analysis(effect_estimation: Dict[str, Any] | Any, *, r2_y: float, r2_d: float, rho: float = 1.0, H0: float = 0.0, alpha: float = 0.05, use_signed_rr: bool = False) Dict[str, Any]

Run sensitivity analysis and return a structured interpretation.

Parameters

effect_estimation : Dict[str, Any] or Any The effect estimation object. r2_y : float Sensitivity parameter for outcome residual confounding strength. r2_d : float Sensitivity parameter for treatment residual confounding strength. rho : float, default 1.0 Correlation parameter for unobserved confounding. H0 : float, default 0.0 Null hypothesis used for significance checks. alpha : float, default 0.05 Significance level. use_signed_rr : bool, default False Whether to use signed rr in the quadratic sensitivity combination.

Returns

Dict[str, Any] Dictionary with: - raw: the output of sensitivity_analysis(...) - interpretation: machine-readable interpretation fields - summary: compact human-readable interpretation