Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vasilis/drlearner #137

Merged
merged 51 commits into from
Nov 11, 2019
Merged
Changes from 1 commit
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
f31d86a
separating drlearner
vasilismsr Nov 6, 2019
7c4d76d
better docstring
vasilismsr Nov 6, 2019
6e2c972
notebook
vasilismsr Nov 6, 2019
b9d5238
drlearner documentation finalized.
vasilismsr Nov 6, 2019
ad72eab
removed doubly robust learner from metalearners
vasilismsr Nov 6, 2019
868b5c1
revmoed drlearner test from metalearners and started new test file fo…
vasilismsr Nov 6, 2019
a293f0f
revmoed drlearner test from metalearners and started new test file fo…
vasilismsr Nov 6, 2019
c63d6b3
changed tests in dml to adhere to the CATE API. Some calls to effect …
vasilismsr Nov 6, 2019
d2494b6
added exhaustive tests for drlearner. Fixed bugs from corner cases
vasilismsr Nov 7, 2019
e75fd48
bug in docstring regarding how split is called to generate crossfit f…
vasilismsr Nov 7, 2019
fbc3f1d
changed bootstarp tests to conform with keyword only effect and effec…
vasilismsr Nov 7, 2019
3397d95
bootstrap tests, fixing bugs related to positional arguments T0, T1
vasilismsr Nov 7, 2019
b13581e
linting
vasilismsr Nov 7, 2019
e4c355d
more tests for drlearner and small bugs
vasilismsr Nov 7, 2019
8611577
reverted back to coef_ and intercept_. Fixed docstring. Added exhaust…
vasilismsr Nov 7, 2019
0dcea06
added checks of fitted dims for W and Z during scoring in _OrthoLearn…
vasilismsr Nov 7, 2019
7c55fb0
testing notebook
vasilismsr Nov 7, 2019
b5c0a07
linting
vasilismsr Nov 7, 2019
59d9fb1
docstring fix regarding n_splits in multiple places. Fixed notebook f…
vasilismsr Nov 7, 2019
d3274ff
changed statsmodels inference inptu properties to reflect that we onl…
vasilismsr Nov 7, 2019
988c53d
small change in test drlearner
vasilismsr Nov 7, 2019
e48f7de
docstring for linear drlearner
vasilismsr Nov 7, 2019
95fa08f
improved example in docstring of lineardrlearner
vasilismsr Nov 7, 2019
ef0dff5
adding more slacks to some drlearner coverage tests
vasilismsr Nov 7, 2019
07a79e2
Merge branch 'master' into vasilis/drlearner
vasilismsr Nov 7, 2019
d2b7835
linting
vasilismsr Nov 7, 2019
0474015
linting
vasilismsr Nov 7, 2019
f6d1505
removed OrthoLearner testing notebook
vasilismsr Nov 7, 2019
cb60dc4
comments on fit score dimension mismatch
vasilismsr Nov 8, 2019
9768a76
removed leftover print statement from cate estimator
vasilismsr Nov 8, 2019
c315539
replaced :code: with
vasilismsr Nov 8, 2019
51e0595
added :meth:
vasilismsr Nov 8, 2019
f377e95
added :meth:
vasilismsr Nov 8, 2019
aa21807
removed + for string concat
vasilismsr Nov 8, 2019
a3b7b52
removed redundant test code
vasilismsr Nov 8, 2019
b00052c
added comment on overlapping tests between DML and DRLearner
vasilismsr Nov 8, 2019
cd597f4
removed redundant rand_sol code in test_drlearner
vasilismsr Nov 8, 2019
42fae99
removed + operator for string concat
vasilismsr Nov 8, 2019
8de555b
added TODO for allowing for 2d y of shape (n,1) and also added test t…
vasilismsr Nov 8, 2019
084561d
removed redundant adding and subtracting in statsmodelscateestimator
vasilismsr Nov 8, 2019
d606f2a
changed :attr: to :meth:
vasilismsr Nov 8, 2019
7803c2e
added TODO so that we merge functionality between statsmodelsinferenc…
vasilismsr Nov 8, 2019
610db58
replaced printing with subTests
vasilismsr Nov 8, 2019
68d5180
linting
vasilismsr Nov 8, 2019
fdd536a
fixed docstring in dml. Added utility function of inverse_onehot enco…
vasilismsr Nov 9, 2019
bfb1ff8
removed replacing None weights with np.ones in drlearner scoring sinc…
vasilismsr Nov 9, 2019
179c2cf
typo in error mst
vasilismsr Nov 9, 2019
9c4271e
made statsmodelslinearregression be child of BaseEstimator
vasilismsr Nov 9, 2019
8ea37c8
added comment on code design choice in model_final of drlearner, rela…
vasilismsr Nov 9, 2019
36ddc55
put docstrings in methods and removed them from attributes
vasilismsr Nov 9, 2019
c1549c8
Merge branch 'master' into vasilis/drlearner
vasilismsr Nov 10, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
put docstrings in methods and removed them from attributes
vasilismsr committed Nov 9, 2019

Verified

This commit was signed with the committer’s verified signature.
bbenzikry Beni Ben zikry
commit 36ddc5538d6b6fcf88196e1616b3b5f30b626920
113 changes: 74 additions & 39 deletions econml/drlearner.py
Original file line number Diff line number Diff line change
@@ -224,27 +224,6 @@ class takes as input the parameter `model_regressor``, which is an arbitrary sci

Attributes
----------
models_propensity: list of objects of type(model_propensity)
A list of instances of the model_propensity object. Each element corresponds to a crossfitting
fold and is the model instance that was fitted for that training fold.
models_regression: list of objects of type(model_regression)
A list of instances of the model_regression object. Each element corresponds to a crossfitting
fold and is the model instance that was fitted for that training fold.
model_cate(T=t) : object of type(model_final)
An instance of the model_final object that was fitted after calling fit which corresponds
to the CATE model for treatment T=t, compared to baseline. Available only when multitask_model_final=False.
multitask_model_cate : object of type(model_final)
An instance of the model_final object that was fitted after calling fit which corresponds whose
vector of outcomes correspond to the CATE model for each treatment, compared to baseline.
Available only when multitask_model_final=False.
featurizer : object of type(featurizer)
An instance of the fitted featurizer that was used to preprocess X in the final CATE model training.
Available only when featurizer is not None and X is not None.
cate_feature_names(input_feature_names=None) : list of feature names or None
A list of feature names that correspond to the input features in the final CATE model. If
input_feature_names is not None and featurizer is None, then the input_feature_names are returned.
If the featurizer is not None, then this attribute is available only when the featurizer has
a method: `get_feature_names(input_feature_names)`. Otherwise None is returned.
score_ : float
The MSE in the final doubly robust potential outcome regressions, i.e.

@@ -274,6 +253,7 @@ def _combine(self, X, W):
return np.hstack([arr for arr in [X, W] if arr is not None])

def fit(self, Y, T, X=None, W=None, *, sample_weight=None):
# TODO Allow for non-vector y, i.e. of shape (n, 1)
assert np.ndim(Y) == 1, "Can only accept single dimensional outcomes Y! Use Y.ravel()."
if (X is None) and (W is None):
raise AttributeError("At least one of X or W has to not be None!")
@@ -411,11 +391,35 @@ def score(self, Y, T, X=None, W=None):

@property
def multitask_model_cate(self):
"""
Get the fitted final CATE model.

Returns
-------
multitask_model_cate: object of type(model_final)
An instance of the model_final object that was fitted after calling fit which corresponds whose
vector of outcomes correspond to the CATE model for each treatment, compared to baseline.
Available only when multitask_model_final=True.
"""
if not self._multitask_model_final:
raise AttributeError("Separate CATE models were fitted for each treatment! Use model_cate.")
return super().model_final.model_cate

def model_cate(self, T=1):
"""
Get the fitted final CATE model.

Parameters
----------
T: alphanumeric
The treatment with respect to which we want the fitted CATE model.

Returns
-------
model_cate: object of type(model_final)
An instance of the model_final object that was fitted after calling fit which corresponds
to the CATE model for treatment T=t, compared to baseline. Available when multitask_model_final=False.
"""
if self._multitask_model_final:
raise AttributeError("A single multitask model was fitted for all treatments! Use multitask_model_cate.")
_, T = self._expand_treatments(None, T)
@@ -424,17 +428,60 @@ def model_cate(self, T=1):

@property
def models_propensity(self):
"""
Get the fitted propensity models.

Returns
-------
models_propensity: list of objects of type(`model_propensity`)
A list of instances of the `model_propensity` object. Each element corresponds to a crossfitting
fold and is the model instance that was fitted for that training fold.
"""
return [mdl._model_propensity for mdl in super().models_nuisance]

@property
def models_regression(self):
"""
Get the fitted regression models.

Returns
-------
model_regression: list of objects of type(`model_regression`)
A list of instances of the model_regression object. Each element corresponds to a crossfitting
fold and is the model instance that was fitted for that training fold.
"""
return [mdl._model_regression for mdl in super().models_nuisance]

@property
def featurizer(self):
"""
Get the fitted featurizer.

Returns
-------
featurizer: object of type(featurizer)
An instance of the fitted featurizer that was used to preprocess X in the final CATE model training.
Available only when featurizer is not None and X is not None.
"""
return super().model_final._featurizer

def cate_feature_names(self, input_feature_names=None):
"""
Get the output feature names.

Parameters
----------
input_feature_names: list of strings of length X.shape[1] or None
The names of the input features

Returns
-------
out_feature_names: list of strings or None
The names of the output features :math:`\\phi(X)`, i.e. the features with respect to which the
final CATE model for each treatment is linear. It is the names of the features that are associated
with each entry of the :meth:`coef_` parameter. Available only when the featurizer is not None and has
a method: `get_feature_names(input_feature_names)`. Otherwise None is returned.
"""
if self.featurizer is None:
return input_feature_names
elif hasattr(self.featurizer, 'get_feature_names'):
@@ -545,23 +592,6 @@ class LinearDRLearner(StatsModelsCateEstimatorDiscreteMixin, DRLearner):

Attributes
----------
models_propensity: list of objects of type(model_propensity)
A list of instances of the model_propensity object. Each element corresponds to a crossfitting
fold and is the model instance that was fitted for that training fold.
models_regression: list of objects of type(model_regression)
A list of instances of the model_regression object. Each element corresponds to a crossfitting
fold and is the model instance that was fitted for that training fold.
model_cate(T=t) : object of type(model_final)
An instance of the model_final object that was fitted after calling fit which corresponds
to the CATE model for treatment T=t, compared to baseline. Available only when multitask_model_final=False.
featurizer : object of type(featurizer)
An instance of the fitted featurizer that was used to preprocess X in the final CATE model training.
Available only when featurizer is not None and X is not None.
cate_feature_names(input_feature_names=None) : list of feature names or None
A list of feature names that correspond to the input features in the final CATE model. If
input_feature_names is not None and featurizer is None, then the input_feature_names are returned.
If the featurizer is not None, then this attribute is available only when the featurizer has
a method: `get_feature_names(input_feature_names)`. Otherwise None is returned.
score_ : float
The MSE in the final doubly robust potential outcome regressions, i.e.

@@ -572,7 +602,6 @@ class LinearDRLearner(StatsModelsCateEstimatorDiscreteMixin, DRLearner):

If `sample_weight` is not None at fit time, then a weighted average across samples is returned.

TODO Allow for non-vector y, i.e. of shape (n, 1)
"""

def __init__(self,
@@ -619,6 +648,12 @@ def fit(self, Y, T, X=None, W=None, *, sample_weight=None, sample_var=None, infe
# Replacing fit from DRLearner, to add statsmodels inference in docstring
return super().fit(Y, T, X=X, W=W, sample_weight=sample_weight, sample_var=sample_var, inference=inference)

@property
def multitask_model_cate(self):
# Replacing this method which is invalid for this class, so that we make the
# dosctring empty and not appear in the docs.
return super().multitask_model_cate

@property
def statsmodels(self):
return self.model_final._model_final