Diagnostics
compute_positivity_metrics
compute_positivity_metrics(df: DataFrame, ps_col: str = PS_COL, treatment_col: str = TREATMENT_COL, eps: float = 0.01, common_support_threshold: float = 0.05) -> dict
Compute positivity/overlap diagnostics for the propensity score.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
Input DataFrame with treatment and propensity score columns. |
required |
ps_col
|
str
|
Name of the propensity score column. |
PS_COL
|
treatment_col
|
str
|
Name of the treatment status column (1 treated, 0 control). |
TREATMENT_COL
|
eps
|
float
|
Propensity scores outside [eps, 1 - eps] are counted as extreme. |
0.01
|
common_support_threshold
|
float
|
Quantile threshold passed to get_common_support_range. |
0.05
|
Returns:
| Type | Description |
|---|---|
dict
|
dict with sample sizes, shares of extreme propensity scores (overall and |
dict
|
per arm), the trimmed common support range (intersection of the arms' |
dict
|
quantile-trimmed PS ranges — observations can fall outside it even under |
dict
|
perfect overlap when common_support_threshold > 0) and shares outside it, |
dict
|
the KS test comparing the arms' propensity score distributions, and a |
dict
|
flag_extreme_ps bool (True if any propensity scores fall outside |
dict
|
[eps, 1 - eps] — evidence of a practical positivity problem, not proof of |
dict
|
a formal violation). |
Source code in CausalEstimate/diagnostics/positivity.py
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | |
compute_weight_diagnostics
compute_weight_diagnostics(df: DataFrame, ps_col: str = PS_COL, treatment_col: str = TREATMENT_COL, weight_type: Literal['ATE', 'ATT'] = 'ATE', clip_percentile: float = 1) -> dict
Compute IPW weight diagnostics: effective sample size and weight summaries.
Weights are computed with compute_ipw_weights; clip_percentile=1 (default) means raw, unclipped weights, matching the estimators' default. Propensity scores of exactly 0 or 1 raise ValueError: their IPW weights are undefined and would only reflect the numerical stabilizer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
Input DataFrame with treatment and propensity score columns. |
required |
ps_col
|
str
|
Name of the propensity score column. |
PS_COL
|
treatment_col
|
str
|
Name of the treatment status column (1 treated, 0 control). |
TREATMENT_COL
|
weight_type
|
Literal['ATE', 'ATT']
|
"ATE" or "ATT". |
'ATE'
|
clip_percentile
|
float
|
Upper-tail clipping passed to compute_ipw_weights. |
1
|
Returns:
| Type | Description |
|---|---|
dict
|
dict with per-arm ESS, ESS as a fraction of arm size, and per-arm weight |
dict
|
summaries (max, mean, 95th and 99th percentile). Pooled equivalents |
dict
|
(ess_total, ess_fraction_total, max_weight, mean_weight, weight_q95, |
dict
|
weight_q99) are included only for weight_type="ATE": ATT weights put the |
dict
|
two arms on different scales (treated weights are identically 1), so |
dict
|
pooled Kish ESS and pooled quantiles would be misleading there. |
Source code in CausalEstimate/diagnostics/weights.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | |
compute_ess
compute_ess(weights: ndarray) -> float
Effective sample size of a weighted sample (Kish): (sum w)^2 / sum(w^2).
Equals n for uniform weights and approaches 1 as a single weight dominates. Defined for nonnegative weights; nonfinite, negative, or all-zero weights raise ValueError.
Source code in CausalEstimate/diagnostics/weights.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
compute_ipw_weights
compute_ipw_weights(A: ndarray, ps: ndarray, weight_type: Literal['ATE', 'ATT'] = 'ATE', clip_percentile: float = 1, eps: float = 1e-09) -> np.ndarray
Computes Inverse Propensity Score (IPW) weights with optional clipping.
This function calculates weights for estimating the Average Treatment Effect (ATE) or the Average Treatment Effect on the Treated (ATT).
Formulas: - ATE: w = A/ps + (1-A)/(1-ps) - ATT: w = A + (1-A) * ps/(1-ps)
Args:
A: Binary treatment assignment vector (1 for treated, 0 for control).
ps: Propensity score vector (estimated probability of treatment).
weight_type: The type of estimand, either "ATE" or "ATT".
clip_percentile: The upper percentile at which to clip weights to prevent
extreme values. A value of 1.0 (default) applies no
clipping. For example, 0.99 clips the top 1%.
eps: A small constant to add to denominators for numerical stability.
Returns:
| Type | Description |
|---|---|
ndarray
|
An array of computed IPW weights. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in CausalEstimate/estimators/functional/utils.py
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | |
compute_evalue
compute_evalue(estimate: float, ci_lower: Optional[float] = None, ci_upper: Optional[float] = None, scale: Literal['RR', 'RD'] = 'RR', baseline_risk: Optional[float] = None) -> dict
E-value for unmeasured confounding (VanderWeele & Ding, 2017).
The E-value is the minimum strength of association, on the risk-ratio scale, that an unmeasured confounder would need with both treatment and outcome (conditional on measured covariates) to fully explain away the observed effect. For RR >= 1, E = RR + sqrt(RR * (RR - 1)); protective effects use 1 / RR. The CI E-value applies the same formula to the confidence bound closest to the null and is 1 when the interval contains the null.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
estimate
|
float
|
Effect estimate on the given scale. |
required |
ci_lower
|
Optional[float]
|
Lower confidence bound; pass together with ci_upper. |
None
|
ci_upper
|
Optional[float]
|
Upper confidence bound. |
None
|
scale
|
Literal['RR', 'RD']
|
"RR" for risk ratios (RR, RRT effect types), or "RD" for risk differences (ATE, ARR, ATT, ATC on a binary outcome). RD values are converted to risk ratios via (baseline_risk + RD) / baseline_risk. |
'RR'
|
baseline_risk
|
Optional[float]
|
Outcome risk in the untreated (e.g. the estimator's
|
None
|
Returns:
| Type | Description |
|---|---|
dict
|
dict with keys "evalue" and "evalue_ci" (None if no CI was given). |
Source code in CausalEstimate/diagnostics/sensitivity.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | |