Augmented Inverse Probability Weighting (AIPW)
A doubly robust estimator of a marginal causal effect that combines a propensity-score model with treatment-specific outcome regressions: it standardizes predicted outcomes for every eligible person, then uses inverse-probability-weighted residuals to correct the prediction when one of those nuisance models is misspecified.
On this page
AIPW estimates what would happen if everyone in a study received each treatment in turn. It makes two educated predictions: who was likely to receive the treatment, and what outcome each person was likely to have. If either prediction model is well built, the combined estimate can still be reliable, but it cannot fix missing confounders or groups who never had a realistic chance to receive both treatments.
What AIPW estimates
Augmented inverse probability weighting (AIPW), also called the augmented inverse probability weighted estimator or one-step doubly robust estimator, estimates a marginal causal contrast. For a binary treatment A and binary outcome Y, the usual target is the average treatment effect (ATE), E[Y^1] - E[Y^0]: the difference in outcome risk if every eligible person received treatment versus if every eligible person received the comparator.
AIPW needs two models fit using pre-index covariates X: a propensity model e(X)=Pr(A=1|X), and outcome models m1(X)=E[Y|A=1,X] and m0(X)=E[Y|A=0,X]. The estimator starts with the standardized prediction, mean(m1-m0), then adds each person's observed-minus-predicted outcome residual, weighted by the inverse probability of the treatment that person actually received. For the risk difference, its person-level contribution is m1(X)-m0(X) + A{Y-m1(X)}/e(X) - (1-A){Y-m0(X)}/{1-e(X)}. Averaging those contributions gives the AIPW estimate.
What “doubly robust” does and does not mean
Under exchangeability, consistency, and positivity, AIPW is consistent when either the propensity model or the outcome model is correctly specified. When both are materially wrong, AIPW has no double-robustness guarantee. It does not protect against unmeasured confounding, a wrong time zero, an ill-defined treatment, selection into the database, or lack of a real comparator. “Two chances” is a model-specification property, not a license to fit two unvalidated black boxes.
Pros, cons, and trade-offs
Compared with IPTW alone, AIPW has an outcome-regression correction and is therefore more forgiving when one nuisance model is wrong; compared with g-computation alone, it has a propensity-based correction when the outcome model is wrong. It also naturally produces a marginal risk difference, rather than a conditional odds ratio. Its costs are two nuisance models to diagnose, inverse-probability instability when estimated propensities approach zero or one, and an influence-function standard error that is reliable only if the nuisance-fitting strategy is appropriate. In a modest, pre-specified parametric analysis, transparent logistic models may be preferable. With flexible or aggressively selected machine-learning nuisance models, cross-fitting is the standard approach to limit overfitting bias and support ordinary influence-function inference; it is not a substitute for checking the estimator-specific regularity conditions.
When NOT to use — and when it is actively misleading
Do not apply AIPW to a cohort with practical positivity failure: if clinically severe patients almost always receive one treatment, small estimated probabilities create enormous residual corrections and the result depends on extrapolation, not observed comparisons. Do not use a baseline AIPW estimator for sustained strategies with time-varying confounding affected by prior treatment; use an explicitly longitudinal g-method such as longitudinal TMLE or a suitably specified marginal structural model. Do not tune the propensity or outcome model after viewing the treatment effect. Pre-specify covariates, inspect overlap, calibration, weight tails, and effective sample size before interpreting the estimate.
RWE operational checks
In claims, construct every covariate strictly before the index date and restrict to a period with observable medical and pharmacy coverage; otherwise absence of a code can mean missing capture, not no comorbidity. In EHR data, include measurement setting and missingness indicators where justified, because care intensity can predict both treatment and recorded outcomes. In linked data, distinguish a linkage-selected cohort from the source population. In all sources, report the target population, propensity overlap by arm, truncation or restriction rule if any, both nuisance-model specifications, balance diagnostics, and the marginal estimand.
Decision diagram
flowchart TD
Cohort[Eligible active-comparator new-user cohort<br/>pre-index covariates X] --> PS["Fit propensity e(X)"]
Cohort --> OR["Fit outcome model m(A,X)"]
PS --> Check{Overlap and calibrated<br/>probabilities credible?}
Check -->|no| Restrict[Redefine target population or stop<br/>do not hide non-overlap]
Check -->|yes| Predict["Predict m1(X) and m0(X)<br/>for every person"]
OR --> Predict
Predict --> Augment[Add inverse-probability-weighted<br/>observed-minus-predicted residual]
Augment --> ATE[Average influence-function contributions<br/>marginal ATE risk difference + SE when justified]Worked example
Scenario
In a hypothetical claims cohort of new users of drug A or B, the outcome is a 180-day hospitalization. Age and a pre-index severity score affect both drug choice and hospitalization. The analyst estimates the ATE risk difference using an AIPW estimator after confirming that estimated propensities are away from zero and one. This synthetic example does not restrict the target population or clip propensity scores.
Dataset
Illustrative analytic rows. In a real analysis, the data include the full pre-index covariate set rather than only two predictors.
| person_id | treatment_a | age | severity | hospitalized_180d |
|---|---|---|---|---|
| 101 | 1 | 72 | 8 | 1 |
| 102 | 1 | 64 | 5 | 0 |
| 103 | 0 | 70 | 8 | 1 |
| 104 | 0 | 58 | 3 | 0 |
Steps
Result
The resulting quantity is the adjusted 180-day risk difference for the defined eligible cohort, not a conditional odds ratio and not proof of causation if exchangeability or positivity is implausible.
Trade-offs
Code example
Execution not verified · inspect inputs and dependencies before use
Runnable synthetic binary-outcome AIPW example. Inputs are one row per eligible new user with binary treatment `a`, binary outcome `y`, and pre-index covariates `age` and `severity`; output is the ATE risk difference and an influence-function standard error.
import numpy as np
def expit(x):
return 1 / (1 + np.exp(-np.clip(x, -30, 30)))
def fit_logistic(X, y, iterations=50):
"""Small Newton-Raphson fit for this reproducible teaching example."""
beta = np.zeros(X.shape[1])
for _ in range(iterations):
p = expit(X @ beta)
w = np.clip(p * (1 - p), 1e-8, None)
step = np.linalg.solve(X.T @ (w[:, None] * X), X.T @ (y - p))
beta += step
if np.max(np.abs(step)) < 1e-10:
break
return beta
rng = np.random.default_rng(20261011)
n = 2000
age = rng.normal(65, 10, n)
severity = rng.normal(0, 1, n)
e_true = 1 / (1 + np.exp(-(-1.0 + 0.03 * (age - 65) + 0.8 * severity)))
a = rng.binomial(1, e_true)
p_y = 1 / (1 + np.exp(-(-2.0 - 0.5 * a + 0.025 * (age - 65) + 0.7 * severity)))
y = rng.binomial(1, p_y)
x_ps = np.column_stack([np.ones(n), age, severity])
e_hat = expit(x_ps @ fit_logistic(x_ps, a))
if e_hat.min() <= 0.01 or e_hat.max() >= 0.99:
raise ValueError("Practical positivity problem: inspect support or pre-specify a restricted target population; do not silently clip e_hat.")
x_y = np.column_stack([np.ones(n), a, age, severity])
beta_y = fit_logistic(x_y, y)
m1_hat = expit(np.column_stack([np.ones(n), np.ones(n), age, severity]) @ beta_y)
m0_hat = expit(np.column_stack([np.ones(n), np.zeros(n), age, severity]) @ beta_y)
psi = (m1_hat - m0_hat + a * (y - m1_hat) / e_hat
- (1 - a) * (y - m0_hat) / (1 - e_hat))
ate_rd = psi.mean()
se = psi.std(ddof=1) / np.sqrt(n)
print({"AIPW_ATE_risk_difference": ate_rd, "SE": se,
"95%_CI": (ate_rd - 1.96 * se, ate_rd + 1.96 * se)})Execution not verified · inspect inputs and dependencies before use
Runnable parametric AIPW template for an existing `d` data frame with binary `a` and `y`, and pre-index `age` and `severity`. It returns the ATE risk difference and empirical influence-function standard error when both nuisance models are consistently estimated under the relevant regularity conditions.
# d has one row per eligible person: a (0/1), y (0/1), age and severity measured before index.
ps_fit <- glm(a ~ age + severity, family = binomial(), data = d)
e_hat <- predict(ps_fit, type = "response")
if (any(e_hat <= 0.01 | e_hat >= 0.99)) {
stop("Practical positivity problem: inspect support or pre-specify a restricted target population; do not silently clip e_hat.")
}
y_fit <- glm(y ~ a + age + severity, family = binomial(), data = d)
d1 <- transform(d, a = 1)
d0 <- transform(d, a = 0)
m1_hat <- predict(y_fit, newdata = d1, type = "response")
m0_hat <- predict(y_fit, newdata = d0, type = "response")
psi <- m1_hat - m0_hat + d$a * (d$y - m1_hat) / e_hat -
(1 - d$a) * (d$y - m0_hat) / (1 - e_hat)
ate_rd <- mean(psi)
se <- sd(psi) / sqrt(nrow(d))
c(ATE_risk_difference = ate_rd, SE = se,
CI_lower = ate_rd - 1.96 * se, CI_upper = ate_rd + 1.96 * se)Execution not verified · inspect inputs and dependencies before use
Illustrative SAS/STAT template for the same point-treatment AIPW estimand. It requires a one-row-per-person `analytic` table with unique `person_id`, binary `a` and `y`, and pre-index covariates `age` and `severity`; validate `PROC PLM` scoring and variance handling in the local SAS version before production use.
proc logistic data=analytic;
model a(event='1') = age severity;
output out=ps p=e_hat;
run;
proc sort data=ps; by person_id; run;
proc logistic data=analytic;
model y(event='1') = a age severity;
store out=outcome_model;
run;
data counterfactual;
set ps;
a=1; output;
a=0; output;
run;
proc plm restore=outcome_model;
score data=counterfactual out=scored predicted=mu / ilink;
run;
proc sort data=scored; by person_id a; run;
proc transpose data=scored out=wide prefix=m;
by person_id; id a; var mu;
run;
data aipw;
merge ps(in=in_ps) wide; by person_id;
if in_ps;
if e_hat <= 0.01 or e_hat >= 0.99 then do;
put "ERROR: Practical positivity problem; inspect support or pre-specify a restricted target population. Do not silently clip e_hat.";
abort cancel;
end;
psi=m1-m0 + a*(y-m1)/e_hat - (1-a)*(y-m0)/(1-e_hat);
run;
proc means data=aipw mean stderr clm;
var psi;
run;Citations
- [1]Bang H, Robins JM. Doubly robust estimation in missing data and causal inference models. Biometrics. 2005;61(4):962-973.
- [2]Funk MJ, Westreich D, Wiesen C, Sturmer T, Brookhart MA, Davidian M. Doubly robust estimation of causal effects. American Journal of Epidemiology. 2011;173(7):761-767.