Skip to content

Estimators

IPW

IPW(effect_type='ATE', treatment_col='treatment', outcome_col='outcome', ps_col='ps', clip_percentile: float = 1, eps: float = 1e-09)

Bases: BaseEstimator

Inverse Probability Weighting estimator.

Parameters:

Name Type Description Default
effect_type

Type of causal effect to estimate

'ATE'
treatment_col

Name of treatment column

'treatment'
outcome_col

Name of outcome column

'outcome'
ps_col

Name of propensity score column

'ps'
clip_percentile float

percentile to clip the weights at

1
eps float

Small constant for numerical stability in denominators

1e-09
Source code in CausalEstimate/estimators/ipw.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
def __init__(
    self,
    effect_type="ATE",
    treatment_col="treatment",
    outcome_col="outcome",
    ps_col="ps",
    clip_percentile: float = 1,
    eps: float = 1e-9,
):
    """
    Inverse Probability Weighting estimator.

    Args:
        effect_type: Type of causal effect to estimate
        treatment_col: Name of treatment column
        outcome_col: Name of outcome column
        ps_col: Name of propensity score column
        clip_percentile: percentile to clip the weights at
        eps: Small constant for numerical stability in denominators
    """
    # Initialize base class with core parameters
    super().__init__(
        effect_type=effect_type,
        treatment_col=treatment_col,
        outcome_col=outcome_col,
        ps_col=ps_col,
    )
    self.clip_percentile = clip_percentile
    self.eps = eps

AIPW

AIPW(effect_type: str = 'ATE', treatment_col: str = 'treatment', outcome_col: str = 'outcome', ps_col: str = 'ps', probas_t1_col: str = 'probas_t1', probas_t0_col: str = 'probas_t0', clip_percentile: float = 1, eps: float = 1e-09)

Bases: BaseEstimator

Augmented Inverse Probability Weighting (AIPW) estimator.

Parameters:

Name Type Description Default
effect_type str

Type of causal effect to estimate

'ATE'
treatment_col str

Name of treatment column

'treatment'
outcome_col str

Name of outcome column

'outcome'
ps_col str

Name of propensity score column

'ps'
probas_t1_col str

Name of predicted probabilities under treatment column

'probas_t1'
probas_t0_col str

Name of predicted probabilities under control column

'probas_t0'
clip_percentile float

Upper percentile for clipping, in (0, 1]. Default 1 (no clipping).

1
eps float

Small constant for numerical stability in denominators

1e-09
Source code in CausalEstimate/estimators/aipw.py
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
def __init__(
    self,
    effect_type: str = "ATE",
    treatment_col: str = "treatment",
    outcome_col: str = "outcome",
    ps_col: str = "ps",
    probas_t1_col: str = "probas_t1",
    probas_t0_col: str = "probas_t0",
    clip_percentile: float = 1,
    eps: float = 1e-9,
):
    """
    Augmented Inverse Probability Weighting (AIPW) estimator.

    Args:
        effect_type: Type of causal effect to estimate
        treatment_col: Name of treatment column
        outcome_col: Name of outcome column
        ps_col: Name of propensity score column
        probas_t1_col: Name of predicted probabilities under treatment column
        probas_t0_col: Name of predicted probabilities under control column
        clip_percentile: Upper percentile for clipping, in (0, 1]. Default 1 (no clipping).
        eps: Small constant for numerical stability in denominators
    """
    # Initialize base class with core parameters
    super().__init__(
        effect_type=effect_type,
        treatment_col=treatment_col,
        outcome_col=outcome_col,
        ps_col=ps_col,
    )

    # AIPW-specific parameters
    self.probas_t1_col = probas_t1_col
    self.probas_t0_col = probas_t0_col
    self.clip_percentile = clip_percentile
    self.eps = eps

TMLE

TMLE(effect_type: str = 'ATE', treatment_col: str = 'treatment', outcome_col: str = 'outcome', ps_col: str = 'ps', probas_col: str = 'probas', probas_t1_col: str = 'probas_t1', probas_t0_col: str = 'probas_t0', clip_percentile: float = 1, eps: float = 1e-09, y_bounds: Optional[Tuple[float, float]] = None)

Bases: BaseEstimator

Targeted Maximum Likelihood Estimation (TMLE) estimator.

Binary outcomes use the logistic fluctuation directly. A continuous outcome (ATE/ATT only) is rescaled to [0, 1] with y_bounds (default: observed min/max of the outcome), targeted on that scale, and the results are mapped back (Gruber & van der Laan, 2010).

Parameters:

Name Type Description Default
effect_type str

Type of causal effect to estimate

'ATE'
treatment_col str

Name of treatment column

'treatment'
outcome_col str

Name of outcome column

'outcome'
ps_col str

Name of propensity score column

'ps'
probas_col str

Name of predicted probabilities column

'probas'
probas_t1_col str

Name of predicted probabilities under treatment column

'probas_t1'
probas_t0_col str

Name of predicted probabilities under control column

'probas_t0'
clip_percentile float

Upper percentile for clipping, in (0, 1]. Default 1 (no clipping).

1
eps float

Small constant for numerical stability in denominators

1e-09
y_bounds Optional[Tuple[float, float]]

(min, max) of a continuous outcome. Predictions are clipped to these bounds. Passing it forces the continuous path even for a 0/1 outcome; RR/RRT/ARR ignore it.

None
Source code in CausalEstimate/estimators/tmle.py
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
def __init__(
    self,
    effect_type: str = "ATE",
    treatment_col: str = "treatment",
    outcome_col: str = "outcome",
    ps_col: str = "ps",
    probas_col: str = "probas",
    probas_t1_col: str = "probas_t1",
    probas_t0_col: str = "probas_t0",
    clip_percentile: float = 1,
    eps: float = 1e-9,
    y_bounds: Optional[Tuple[float, float]] = None,
):
    """
    Targeted Maximum Likelihood Estimation (TMLE) estimator.

    Binary outcomes use the logistic fluctuation directly. A continuous
    outcome (ATE/ATT only) is rescaled to [0, 1] with ``y_bounds``
    (default: observed min/max of the outcome), targeted on that scale,
    and the results are mapped back (Gruber & van der Laan, 2010).

    Args:
        effect_type: Type of causal effect to estimate
        treatment_col: Name of treatment column
        outcome_col: Name of outcome column
        ps_col: Name of propensity score column
        probas_col: Name of predicted probabilities column
        probas_t1_col: Name of predicted probabilities under treatment column
        probas_t0_col: Name of predicted probabilities under control column
        clip_percentile: Upper percentile for clipping, in (0, 1]. Default 1 (no clipping).
        eps: Small constant for numerical stability in denominators
        y_bounds: (min, max) of a continuous outcome. Predictions are
            clipped to these bounds. Passing it forces the continuous
            path even for a 0/1 outcome; RR/RRT/ARR ignore it.
    """
    # Initialize base class with core parameters
    super().__init__(
        effect_type=effect_type,
        treatment_col=treatment_col,
        outcome_col=outcome_col,
        ps_col=ps_col,
    )

    # TMLE-specific parameters
    self.probas_col = probas_col
    self.probas_t1_col = probas_t1_col
    self.probas_t0_col = probas_t0_col
    self.clip_percentile = clip_percentile
    self.eps = eps
    self.y_bounds = y_bounds

Matching

Matching(effect_type: str = 'ATE', treatment_col: str = TREATMENT_COL, outcome_col: str = OUTCOME_COL, ps_col: str = PS_COL, match_optimal: bool = True, n_controls: int = 1, caliper: float = None, strict: bool = True)

Bases: BaseEstimator

Propensity Score Matching estimator.

Parameters:

Name Type Description Default
effect_type str

Type of causal effect to estimate

'ATE'
treatment_col str

Name of treatment column

TREATMENT_COL
outcome_col str

Name of outcome column

OUTCOME_COL
ps_col str

Name of propensity score column

PS_COL
match_optimal bool

Whether to use optimal matching (True) or greedy matching (False)

True
n_controls int

Number of controls to match for each treated individual

1
caliper float

Maximum allowable distance (propensity score difference) for matching

None
strict bool

If True (and using greedy matching), raise error if any treated subject cannot be matched. If False, skip unmatched subjects.

True
Source code in CausalEstimate/estimators/matching.py
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
def __init__(
    self,
    effect_type: str = "ATE",
    treatment_col: str = TREATMENT_COL,
    outcome_col: str = OUTCOME_COL,
    ps_col: str = PS_COL,
    match_optimal: bool = True,
    n_controls: int = 1,
    caliper: float = None,
    strict: bool = True,
):
    """
    Propensity Score Matching estimator.

    Args:
        effect_type: Type of causal effect to estimate
        treatment_col: Name of treatment column
        outcome_col: Name of outcome column
        ps_col: Name of propensity score column
        match_optimal: Whether to use optimal matching (True) or greedy matching (False)
        n_controls: Number of controls to match for each treated individual
        caliper: Maximum allowable distance (propensity score difference) for matching
        strict: If True (and using greedy matching), raise error if any treated subject
               cannot be matched. If False, skip unmatched subjects.
    """
    # Initialize base class with core parameters
    super().__init__(
        effect_type=effect_type,
        treatment_col=treatment_col,
        outcome_col=outcome_col,
        ps_col=ps_col,
    )

    # Matching-specific parameters
    self.match_optimal = match_optimal
    self.n_controls = n_controls
    self.caliper = caliper
    self.strict = strict

MultiEstimator

MultiEstimator(estimators: List[BaseEstimator], verbose: bool = False)

estimators is a list of estimator instances (AIPW, TMLE, IPW, etc.). Each is already configured with its own column names and effect_type.

Source code in CausalEstimate/core/multi_estimator.py
25
26
27
28
29
30
31
def __init__(self, estimators: List[BaseEstimator], verbose: bool = False):
    """
    `estimators` is a list of estimator instances (AIPW, TMLE, IPW, etc.).
    Each is already configured with its own column names and effect_type.
    """
    self.estimators = estimators
    self.verbose = verbose

compute_effects

compute_effects(df: DataFrame, n_bootstraps: int = 1, apply_common_support: bool = False, common_support_threshold: float = 0.05, return_bootstrap_samples: bool = False) -> Dict[str, Dict]

Loops over self.estimators, applies optional common support and bootstrap, and returns a dictionary with each estimator's results.

When bootstrapping is enabled (n_bootstraps > 1), each estimator's output will include: - effect: the mean effect across bootstrap samples - std_err: the standard deviation of the bootstrap effects - CI95_lower and CI95_upper: the 95% confidence interval (using the percentile method) - Optionally, raw bootstrap estimates under 'bootstrap_samples' if return_bootstrap_samples is True.

Source code in CausalEstimate/core/multi_estimator.py
 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
def compute_effects(
    self,
    df: pd.DataFrame,
    n_bootstraps: int = 1,
    apply_common_support: bool = False,
    common_support_threshold: float = 0.05,
    return_bootstrap_samples: bool = False,
) -> Dict[str, Dict]:
    """
    Loops over self.estimators, applies optional common support and bootstrap,
    and returns a dictionary with each estimator's results.

    When bootstrapping is enabled (n_bootstraps > 1), each estimator's output will include:
      - effect: the mean effect across bootstrap samples
      - std_err: the standard deviation of the bootstrap effects
      - CI95_lower and CI95_upper: the 95% confidence interval (using the percentile method)
      - Optionally, raw bootstrap estimates under 'bootstrap_samples' if return_bootstrap_samples is True.
    """
    if n_bootstraps < 1:
        raise ValueError("n_bootstraps must be at least 1.")

    if apply_common_support:
        df, ps_col, treatment_col, outcome_col = self._validate_common_support(
            df, common_support_threshold
        )
    else:
        first_estimator = self.estimators[0]
        ps_col = first_estimator.ps_col
        treatment_col = first_estimator.treatment_col
        outcome_col = first_estimator.outcome_col

    if self.verbose:
        log_table_stats(df, treatment_col, outcome_col, ps_col)

    results = {}
    for estimator in self.estimators:
        est_name = estimator.__class__.__name__
        if n_bootstraps > 1:
            est_results = self._compute_bootstrap(
                estimator, df, n_bootstraps, return_bootstrap_samples
            )
            est_results["n_bootstraps"] = n_bootstraps
        else:
            est_results = estimator.compute_effect(df)
            est_results["n_bootstraps"] = 0
        results[est_name] = est_results

    return results