Reweighting
onlinecml.reweighting.ipw.OnlineIPW
Bases: BaseOnlineEstimator
Online Inverse Probability Weighting estimator for the ATE.
Estimates the Average Treatment Effect via importance-weighted pseudo-outcomes, updated one observation at a time. The propensity score model is updated after each pseudo-outcome computation (predict-then-learn protocol).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ps_model
|
OnlinePropensityScore or None
|
Propensity score model. If None, defaults to
|
None
|
clip_min
|
float
|
Lower clip bound for propensity scores. Default 0.01. |
0.01
|
clip_max
|
float
|
Upper clip bound for propensity scores. Default 0.99. |
0.99
|
normalize
|
bool
|
If True, use normalized (stabilized) IPW weights by dividing by the running mean weight within each arm. Default False. |
False
|
Notes
The IPW pseudo-outcome for observation i is:
.. math::
\psi_i = \frac{W_i Y_i}{\hat{p}_i} - \frac{(1-W_i) Y_i}{1 - \hat{p}_i}
The running mean of psi converges to the ATE under unconfoundedness,
overlap, and SUTVA.
Predict-then-learn: the propensity score is predicted before the classifier is updated on the current observation. This avoids look-ahead bias in the pseudo-outcome.
Limitation: predict_one(x) returns the current running ATE
estimate for any input x. IPW does not produce individual CATE
estimates. Use OnlineAIPW or meta-learners for individual CATE.
Cold start: Before any training, propensity is 0.5, giving
IPW weight = 2.0 regardless of treatment. Use warmup to skip
ATE accumulation until the PS model has seen enough data.
Drift adaptation: The default cumulative mean cannot forget old
observations. Use forgetting_factor < 1.0 (e.g. 0.97) to switch
to an EWMA that down-weights old pseudo-outcomes automatically.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
warmup
|
int
|
Number of initial observations to skip when accumulating the ATE estimate. The PS model still trains during warmup. Default 0. |
0
|
forgetting_factor
|
float
|
Controls how quickly old pseudo-outcomes are forgotten.
|
1.0
|
Examples:
>>> from onlinecml.datasets import LinearCausalStream
>>> estimator = OnlineIPW()
>>> for x, w, y, _ in LinearCausalStream(n=500, true_ate=2.0, seed=42):
... estimator.learn_one(x, w, y)
>>> abs(estimator.predict_ate()) < 5.0 # loose bound for short stream
True
Source code in onlinecml/reweighting/ipw.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 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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | |
weight_stats
property
Summary statistics of IPW weights seen so far.
Returns:
| Type | Description |
|---|---|
dict
|
Dictionary with keys |
learn_one(x, treatment, outcome, propensity=None)
Process one observation and update the ATE estimate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Feature dictionary for this observation. |
required |
treatment
|
int
|
Treatment indicator (0 = control, 1 = treated). |
required |
outcome
|
float
|
Observed outcome. |
required |
propensity
|
float or None
|
If provided, uses this logged propensity instead of the internal model's prediction. Useful for off-policy evaluation. |
None
|
Source code in onlinecml/reweighting/ipw.py
predict_one(x)
Return the current running ATE estimate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Feature dictionary (not used; IPW produces no individual CATE). |
required |
Returns:
| Type | Description |
|---|---|
float
|
Current ATE estimate. IPW does not estimate individual CATE — the same value is returned for all inputs. |
Source code in onlinecml/reweighting/ipw.py
onlinecml.reweighting.aipw.OnlineAIPW
Bases: BaseOnlineEstimator
Online Doubly Robust (AIPW) estimator for ATE and individual CATE.
Estimates the Average Treatment Effect using the Augmented IPW (doubly robust) estimator. Maintains three online models: a propensity score, a treated outcome model, and a control outcome model. All models are updated using the predict-first-then-learn protocol.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ps_model
|
OnlinePropensityScore or None
|
Propensity score model. Defaults to
|
None
|
treated_model
|
Regressor or None
|
Outcome model for treated units |
None
|
control_model
|
Regressor or None
|
Outcome model for control units |
None
|
clip_min
|
float
|
Lower clip bound for propensity scores. Default 0.01. |
0.01
|
clip_max
|
float
|
Upper clip bound for propensity scores. Default 0.99. |
0.99
|
Notes
The doubly robust pseudo-outcome is:
.. math::
\psi_i = \hat{\mu}_1(X_i) - \hat{\mu}_0(X_i)
+ \frac{W_i (Y_i - \hat{\mu}_1(X_i))}{\hat{p}(X_i)}
- \frac{(1-W_i)(Y_i - \hat{\mu}_0(X_i))}{1 - \hat{p}(X_i)}
The estimator is consistent if either the propensity score OR both outcome models are correctly specified (double robustness).
Predict-first-then-learn: all three models predict before any of them are updated on the current observation. This approximates cross-fitting in the online setting.
Unlike OnlineIPW, predict_one(x) returns an individual CATE
estimate: mu1(x) - mu0(x).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
warmup
|
int
|
Number of initial observations to skip when accumulating the ATE estimate. All models still train during warmup. Default 0. |
0
|
forgetting_factor
|
float
|
Controls how quickly old pseudo-outcomes are forgotten.
|
1.0
|
Examples:
>>> from onlinecml.datasets import LinearCausalStream
>>> estimator = OnlineAIPW()
>>> for x, w, y, _ in LinearCausalStream(n=500, true_ate=2.0, seed=42):
... estimator.learn_one(x, w, y)
>>> abs(estimator.predict_ate()) < 5.0
True
Source code in onlinecml/reweighting/aipw.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 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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | |
learn_one(x, treatment, outcome, propensity=None)
Process one observation and update all internal models.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Feature dictionary for this observation. |
required |
treatment
|
int
|
Treatment indicator (0 = control, 1 = treated). |
required |
outcome
|
float
|
Observed outcome. |
required |
propensity
|
float or None
|
If provided, uses this logged propensity instead of the internal model. Useful for off-policy evaluation. |
None
|
Source code in onlinecml/reweighting/aipw.py
predict_one(x)
Predict the individual CATE for a single unit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Feature dictionary for the unit. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Estimated CATE: |
Source code in onlinecml/reweighting/aipw.py
onlinecml.reweighting.overlap_weights.OnlineOverlapWeights
Bases: BaseOnlineEstimator
Online Overlap Weights estimator for the ATE.
Uses overlap weights — proportional to the probability of belonging to the opposite treatment group — instead of inverse probability weights. Overlap weights are bounded and yield more stable estimates under near-positivity violations.
The overlap weight for unit i is:
.. math::
h_i = \begin{cases}
1 - \hat{p}(X_i) & \text{if } W_i = 1 \\
\hat{p}(X_i) & \text{if } W_i = 0
\end{cases}
The ATE estimator is:
.. math::
\hat{\tau}_{OW} = \frac{
\sum_i h_i W_i Y_i / \hat{p}_i
- \sum_i h_i (1-W_i) Y_i / (1-\hat{p}_i)
}{\sum_i h_i}
In the online setting this is approximated by maintaining running means of the numerator and denominator terms.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ps_model
|
OnlinePropensityScore or None
|
Propensity score model. Defaults to
|
None
|
Notes
Overlap weights target the Average Treatment Effect on the Overlap Population (ATO), which emphasizes units with propensity scores near 0.5. The estimand differs slightly from the ATE when the propensity distribution is asymmetric.
References
Li, F., Morgan, K.L., and Zaslavsky, A.M. (2018). Balancing covariates via propensity score weighting. Journal of the American Statistical Association, 113(521), 390-400.
Examples:
>>> from onlinecml.datasets import LinearCausalStream
>>> estimator = OnlineOverlapWeights()
>>> for x, w, y, _ in LinearCausalStream(n=500, seed=42):
... estimator.learn_one(x, w, y)
>>> isinstance(estimator.predict_ate(), float)
True
Source code in onlinecml/reweighting/overlap_weights.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 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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | |
learn_one(x, treatment, outcome, propensity=None)
Process one observation and update the ATE estimate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Feature dictionary for this observation. |
required |
treatment
|
int
|
Treatment indicator (0 = control, 1 = treated). |
required |
outcome
|
float
|
Observed outcome. |
required |
propensity
|
float or None
|
If provided, uses this logged propensity. |
None
|
Source code in onlinecml/reweighting/overlap_weights.py
predict_one(x)
Return the current running ATE estimate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Feature dictionary (not used; OW has no individual CATE). |
required |
Returns:
| Type | Description |
|---|---|
float
|
Current ATE estimate. |
Source code in onlinecml/reweighting/overlap_weights.py
onlinecml.reweighting.cbps.OnlineCBPS
Bases: BaseOnlineEstimator
Online Covariate Balancing Propensity Score (CBPS) ATE estimator.
CBPS simultaneously estimates the propensity score and reweights observations so that covariate moments are balanced between treatment arms. In the online setting this is approximated by:
- Predicting the propensity
p = P(W=1|X)using a running logistic model trained with an IPW-corrected signal. - Computing the CBPS IPW pseudo-outcome:
psi = W*Y/p - (1-W)*Y/(1-p) - Maintaining a balance penalty that nudges the propensity model toward producing balanced covariate moments (via a soft running correction to the prediction).
The balance correction is a first-order online approximation of the
exact CBPS moment condition E[X*(W/p - (1-W)/(1-p))] = 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ps_model
|
river classifier or None
|
Propensity score model. Defaults to |
None
|
clip_min
|
float
|
Minimum clipped propensity. Default 0.01. |
0.01
|
clip_max
|
float
|
Maximum clipped propensity. Default 0.99. |
0.99
|
balance_alpha
|
float
|
Step size for the online balance correction (0 disables it). Default 0.01. |
0.01
|
Notes
This is a streaming approximation to Imai & Ratkovic (2014). The exact CBPS objective requires solving a GMM system; we approximate it incrementally using a running covariate-balance signal.
References
Imai, K. and Ratkovic, M. (2014). Covariate balancing propensity score. Journal of the Royal Statistical Society: Series B, 76(1), 243-263.
Examples:
>>> from onlinecml.datasets import LinearCausalStream
>>> from onlinecml.reweighting import OnlineCBPS
>>> cbps = OnlineCBPS()
>>> for x, w, y, _ in LinearCausalStream(n=500, seed=0):
... cbps.learn_one(x, w, y)
>>> cbps.predict_ate()
Source code in onlinecml/reweighting/cbps.py
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 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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | |
balance_report
property
Running mean balance signal E[X*(W/p - (1-W)/(1-p))] per covariate.
Values close to 0 indicate that the propensity model is producing balanced weights for that covariate.
learn_one(x, treatment, outcome, propensity=None)
Process one observation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Covariate dictionary. |
required |
treatment
|
int
|
Treatment indicator (0 or 1). |
required |
outcome
|
float
|
Observed outcome. |
required |
propensity
|
float or None
|
Logged propensity. If provided, skips the internal PS model. |
None
|
Source code in onlinecml/reweighting/cbps.py
predict_one(x)
Return the current ATE estimate (CBPS has no unit-level CATE).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Covariate dictionary (unused; ATE is population-level). |
required |
Returns:
| Type | Description |
|---|---|
float
|
Current running ATE estimate. |