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/policy #377

Merged
merged 49 commits into from
Mar 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
2d3fa56
started policy module
vasilismsr Jan 13, 2021
148104e
finished cython implementation
vasilismsr Jan 18, 2021
0abe48a
finished integration with cate interpreter. Enabled multiple treatmen…
vasilismsr Jan 18, 2021
58acc42
final touches in interpreter
vasilismsr Jan 18, 2021
ff43a1f
Merge branch 'master' into vasilis/policy
vasilismsr Jan 18, 2021
37a3635
merged with master
vasilismsr Jan 18, 2021
3afc13e
removed use('agg')
vasilismsr Jan 18, 2021
9bd27cf
added doubly robust policy learning methods
vasilismsr Jan 19, 2021
b6e3b60
fixed issues with interpreters
vasilismsr Jan 19, 2021
9500871
linting
vasilismsr Jan 19, 2021
225375a
fixd notedook
vasilismsr Jan 19, 2021
b32e857
fixed interpeer checks
vasilismsr Jan 19, 2021
0b452f5
merged master
vasilismsr Jan 19, 2021
07edcc4
fixed deprecated drlearner imports
vasilismsr Jan 19, 2021
308e315
Merge branch 'master' into vasilis/policy
vsyrgkanis Jan 20, 2021
0b2e149
added base policy
vasilismsr Jan 21, 2021
e63d5f8
Merge branch 'master' into vasilis/policy
vsyrgkanis Jan 29, 2021
709e9bb
merged with master
vasilismsr Mar 16, 2021
fb0a5ce
fixed merge bug
vasilismsr Mar 17, 2021
30a3033
cleaned notebook changes
vasilismsr Mar 17, 2021
4318743
notebook changes cleanup
vasilismsr Mar 17, 2021
9c7255c
bug in case study notebook
vasilismsr Mar 17, 2021
1d3e318
perfected coverage of cate interpreters. fixed small nan bug in corne…
vasilismsr Mar 17, 2021
c933cb9
merged policy tree and grf tree in same base class
vasilismsr Mar 18, 2021
26266a1
added tests for all policy methods for good coverage
vasilismsr Mar 19, 2021
c276bad
added more tests
vasilismsr Mar 19, 2021
c5451c0
added missing docstrings
vasilismsr Mar 19, 2021
08ceaab
fixed docstrings in interpreters
vasilismsr Mar 19, 2021
63325f0
linting
vasilismsr Mar 19, 2021
65f90a7
linting
vasilismsr Mar 19, 2021
458f84d
changed plotting of policy tree. Fxied test to not use graphviz
vasilismsr Mar 19, 2021
511cb50
made policy/forest private
vasilismsr Mar 19, 2021
1012298
fixed imports
vasilismsr Mar 19, 2021
6c2aa7e
Merge branch 'master' into vasilis/policy
vsyrgkanis Mar 19, 2021
356ec7e
removed TODO for inference. Added policy learning module to docs. fix…
vasilismsr Mar 19, 2021
0cda93a
Merge branch 'vasilis/policy' of github.com:microsoft/EconML into vas…
vasilismsr Mar 19, 2021
a190ab6
test suggestion
vasilismsr Mar 20, 2021
5c32f90
fixed NaN bug when tree has single node
vasilismsr Mar 20, 2021
b7f82be
made rscorer test more robust
vasilismsr Mar 20, 2021
b7be4a3
added dosctrings and fixed other dosctrings
vasilismsr Mar 20, 2021
a439c4d
fixed docstring in tree
vasilismsr Mar 20, 2021
4f8b57a
added policy_treatment_names method that uses the parsed treatment n…
vasilismsr Mar 21, 2021
50736f1
fixed randomness in weightedkfold, that was causing tests to fail due…
vasilismsr Mar 21, 2021
b411039
fixed docstrings
vasilismsr Mar 21, 2021
206055a
fxied passing parameter bug
vasilismsr Mar 21, 2021
3ee6439
relaxed rscorer test with an absolute deviation
vasilismsr Mar 21, 2021
4123e33
Merge branch 'master' into vasilis/policy
vsyrgkanis Mar 22, 2021
95bbfda
fixed dosctrings from reviews
vasilismsr Mar 22, 2021
f487386
Merge branch 'vasilis/policy' of github.com:microsoft/EconML into vas…
vasilismsr Mar 22, 2021
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
12 changes: 12 additions & 0 deletions doc/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,18 @@ Sieve Methods
econml.iv.sieve.HermiteFeatures
econml.iv.sieve.DPolynomialFeatures

.. _policy_api:

Policy Learning
---------------

.. autosummary::
:toctree: _autosummary

econml.policy.DRPolicyForest
econml.policy.DRPolicyTree
econml.policy.PolicyForest
econml.policy.PolicyTree

.. _interpreters_api:

Expand Down
2 changes: 1 addition & 1 deletion doc/spec/estimation/dr.rst
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ Usage FAQs

.. testcode::

from econml.drlearner import DRLearner
from econml.dr import DRLearner
from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.model_selection import GridSearchCV
model_reg = lambda: GridSearchCV(
Expand Down
30 changes: 23 additions & 7 deletions econml/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

__all__ = ['automated_ml', 'bootstrap',
'cate_interpreter', 'causal_forest',
'data', 'deepiv', 'dml', 'dr', 'drlearner',
'inference', 'iv',
'metalearners', 'ortho_forest', 'orf', 'ortho_iv',
'score', 'sklearn_extensions', 'tree',
'two_stage_least_squares', 'utilities', "dowhy", "__version__"]
__all__ = ['automated_ml',
'bootstrap',
'cate_interpreter',
'causal_forest',
'data',
'deepiv',
'dml',
'dr',
'drlearner',
'inference',
'iv',
'metalearners',
'ortho_forest',
'orf',
'ortho_iv',
'policy',
'score',
'sklearn_extensions',
'tree',
'two_stage_least_squares',
'utilities',
'dowhy',
'__version__']

__version__ = '0.9.2'
14 changes: 14 additions & 0 deletions econml/_ensemble/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

from ._ensemble import BaseEnsemble, _partition_estimators
from ._utilities import (_get_n_samples_subsample, _accumulate_prediction, _accumulate_prediction_var,
_accumulate_prediction_and_var, _accumulate_oob_preds)

__all__ = ["BaseEnsemble",
"_partition_estimators",
"_get_n_samples_subsample",
"_accumulate_prediction",
"_accumulate_prediction_var",
"_accumulate_prediction_and_var",
"_accumulate_oob_preds"]
File renamed without changes.
117 changes: 117 additions & 0 deletions econml/_ensemble/_utilities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import numbers
import numpy as np


def _get_n_samples_subsample(n_samples, max_samples):
"""
Get the number of samples in a sub-sample without replacement.
Parameters
----------
n_samples : int
Number of samples in the dataset.
max_samples : int or float
The maximum number of samples to draw from the total available:
- if float, this indicates a fraction of the total and should be
the interval `(0, 1)`;
- if int, this indicates the exact number of samples;
- if None, this indicates the total number of samples.
Returns
-------
n_samples_subsample : int
The total number of samples to draw for the subsample.
"""
if max_samples is None:
return n_samples

if isinstance(max_samples, numbers.Integral):
if not (1 <= max_samples <= n_samples):
msg = "`max_samples` must be in range 1 to {} but got value {}"
raise ValueError(msg.format(n_samples, max_samples))
return max_samples

if isinstance(max_samples, numbers.Real):
if not (0 < max_samples <= 1):
msg = "`max_samples` must be in range (0, 1) but got value {}"
raise ValueError(msg.format(max_samples))
return int(round(n_samples * max_samples))

msg = "`max_samples` should be int or float, but got type '{}'"
raise TypeError(msg.format(type(max_samples)))


def _accumulate_prediction(predict, X, out, lock, *args, **kwargs):
"""
This is a utility function for joblib's Parallel.
It can't go locally in ForestClassifier or ForestRegressor, because joblib
complains that it cannot pickle it when placed there.
"""
prediction = predict(X, *args, check_input=False, **kwargs)
with lock:
if len(out) == 1:
out[0] += prediction
else:
for i in range(len(out)):
out[i] += prediction[i]


def _accumulate_prediction_var(predict, X, out, lock, *args, **kwargs):
"""
This is a utility function for joblib's Parallel.
It can't go locally in ForestClassifier or ForestRegressor, because joblib
complains that it cannot pickle it when placed there.
Accumulates the mean covariance of a tree prediction. predict is assumed to
return an array of (n_samples, d) or a tuple of arrays. This method accumulates in the placeholder
out[0] the (n_samples, d, d) covariance of the columns of the prediction across
the trees and for each sample (or a tuple of covariances to be stored in each element
of the list out).
"""
prediction = predict(X, *args, check_input=False, **kwargs)
with lock:
if len(out) == 1:
out[0] += np.einsum('ijk,ikm->ijm',
prediction.reshape(prediction.shape + (1,)),
prediction.reshape((-1, 1) + prediction.shape[1:]))
else:
for i in range(len(out)):
pred_i = prediction[i]
out[i] += np.einsum('ijk,ikm->ijm',
pred_i.reshape(pred_i.shape + (1,)),
pred_i.reshape((-1, 1) + pred_i.shape[1:]))


def _accumulate_prediction_and_var(predict, X, out, out_var, lock, *args, **kwargs):
"""
This is a utility function for joblib's Parallel.
It can't go locally in ForestClassifier or ForestRegressor, because joblib
complains that it cannot pickle it when placed there.
Combines `_accumulate_prediction` and `_accumulate_prediction_var` in a single
parallel run, so that out will contain the mean of the predictions across trees
and out_var the covariance.
"""
prediction = predict(X, *args, check_input=False, **kwargs)
with lock:
if len(out) == 1:
out[0] += prediction
out_var[0] += np.einsum('ijk,ikm->ijm',
prediction.reshape(prediction.shape + (1,)),
prediction.reshape((-1, 1) + prediction.shape[1:]))
else:
for i in range(len(out)):
pred_i = prediction[i]
out[i] += prediction
out_var[i] += np.einsum('ijk,ikm->ijm',
pred_i.reshape(pred_i.shape + (1,)),
pred_i.reshape((-1, 1) + pred_i.shape[1:]))


def _accumulate_oob_preds(tree, X, subsample_inds, alpha_hat, jac_hat, counts, lock):
mask = np.ones(X.shape[0], dtype=bool)
mask[subsample_inds] = False
alpha, jac = tree.predict_alpha_and_jac(X[mask])
with lock:
alpha_hat[mask] += alpha
jac_hat[mask] += jac
counts[mask] += 1
Loading