From 24d77d779e7afd455e02c65e4fdd527f7aae8f29 Mon Sep 17 00:00:00 2001 From: Roland Stevenson Date: Sat, 9 Nov 2024 13:18:42 +0100 Subject: [PATCH 1/3] resolves #796 remove dep on pygam, use IsotonicRegression --- causalml/propensity.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/causalml/propensity.py b/causalml/propensity.py index f3aee9e3..7f74a9fb 100644 --- a/causalml/propensity.py +++ b/causalml/propensity.py @@ -1,10 +1,10 @@ from abc import ABCMeta, abstractmethod import logging import numpy as np -from pygam import LogisticGAM, s from sklearn.metrics import roc_auc_score as auc from sklearn.linear_model import LogisticRegressionCV from sklearn.model_selection import StratifiedKFold, train_test_split +from sklearn.isotonic import IsotonicRegression import xgboost as xgb @@ -179,9 +179,9 @@ def predict(self, X): def calibrate(ps, treatment): - """Calibrate propensity scores with logistic GAM. + """Calibrate propensity scores with IsotonicRegression. - Ref: https://pygam.readthedocs.io/en/latest/api/logisticgam.html + Ref: https://scikit-learn.org/stable/modules/isotonic.html Args: ps (numpy.array): a propensity score vector @@ -191,9 +191,10 @@ def calibrate(ps, treatment): (numpy.array): a calibrated propensity score vector """ - gam = LogisticGAM(s(0)).fit(ps, treatment) + pm_ir = IsotonicRegression(out_of_bounds="clip") + ps_ir = pm_ir.fit_transform(ps, treatment) - return gam.predict_proba(ps) + return ps_ir def compute_propensity_score( From e2837158a4886e6e37a2bb38cc3aa18343d108b6 Mon Sep 17 00:00:00 2001 From: Roland Stevenson Date: Sun, 10 Nov 2024 00:14:06 +0100 Subject: [PATCH 2/3] restrict propensity scores to (0,1); (0+2eps,1-2eps) --- causalml/propensity.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/causalml/propensity.py b/causalml/propensity.py index 7f74a9fb..5a094837 100644 --- a/causalml/propensity.py +++ b/causalml/propensity.py @@ -191,7 +191,8 @@ def calibrate(ps, treatment): (numpy.array): a calibrated propensity score vector """ - pm_ir = IsotonicRegression(out_of_bounds="clip") + two_eps = 2.0*np.finfo(float).eps + pm_ir = IsotonicRegression(out_of_bounds="clip", y_min=two_eps, y_max=1.0-two_eps) ps_ir = pm_ir.fit_transform(ps, treatment) return ps_ir From 716730396eb6537488aeeaacf96e4ed116df27b4 Mon Sep 17 00:00:00 2001 From: Roland Stevenson Date: Sun, 10 Nov 2024 00:17:09 +0100 Subject: [PATCH 3/3] linted --- causalml/propensity.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/causalml/propensity.py b/causalml/propensity.py index 5a094837..f18cf28f 100644 --- a/causalml/propensity.py +++ b/causalml/propensity.py @@ -191,8 +191,8 @@ def calibrate(ps, treatment): (numpy.array): a calibrated propensity score vector """ - two_eps = 2.0*np.finfo(float).eps - pm_ir = IsotonicRegression(out_of_bounds="clip", y_min=two_eps, y_max=1.0-two_eps) + two_eps = 2.0 * np.finfo(float).eps + pm_ir = IsotonicRegression(out_of_bounds="clip", y_min=two_eps, y_max=1.0 - two_eps) ps_ir = pm_ir.fit_transform(ps, treatment) return ps_ir