Skip to content

Commit d2118d5

Browse files
authored
add double ml notebook and fix a minor typo in dml doc (#24)
* add double ml notebook and fix a minor typo in dml doc * change the plot for cross price elasticities * add a bootstrap CI for OJ data * fix plot legend typo * change dml shuffle True and update notebook based on all feedbacks * Added random state to metalearner tests.
1 parent 5f2b5d6 commit d2118d5

4 files changed

Lines changed: 997 additions & 6 deletions

File tree

doc/spec/estimation/dml.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ One particularly attractive special case of the DML framework is the case when :
116116
f_i(X, W) =~& \ldot{\gamma_i}{(X; W)}\\
117117
\end{align}
118118
119-
In this case we have a more structural form for the two regression tasks of estimating :math:`q` and :math:`p`. In particular, we can write:
119+
In this case we have a more structural form for the two regression tasks of estimating :math:`q` and :math:`f`. In particular, we can write:
120120

121121
.. math::
122122
:nowrap:

econml/dml.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def fit(self, Y, T, X=None, W=None):
9696

9797
y_res = np.zeros(shape(Y))
9898
t_res = np.zeros(shape(T))
99-
for idx, (train_idxs, test_idxs) in enumerate(KFold(self._n_splits).split(X)):
99+
for idx, (train_idxs, test_idxs) in enumerate(KFold(self._n_splits, shuffle=True).split(X)):
100100
Y_train, Y_test = Y[train_idxs], Y[test_idxs]
101101
T_train, T_test = T[train_idxs], T[test_idxs]
102102
X_train, X_test = X[train_idxs], X[test_idxs]

econml/tests/test_metalearners.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ class TestMetalearners(unittest.TestCase):
1515

1616
@classmethod
1717
def setUpClass(cls):
18+
# Set random seed
19+
cls.random_state = np.random.RandomState(12345)
1820
# Generate data
1921
# DGP constants
2022
cls.d = 5
@@ -23,7 +25,7 @@ def setUpClass(cls):
2325
cls.beta = np.array([0.25, -0.38, 1.41, 0.50, -1.22])
2426
cls.heterogeneity_index = 1
2527
# Test data
26-
cls.X_test = multivariate_normal(
28+
cls.X_test = cls.random_state.multivariate_normal(
2729
np.zeros(cls.d),
2830
np.diag(np.ones(cls.d)),
2931
cls.n_test)
@@ -162,7 +164,7 @@ def _test_inputs(self, learner_instance):
162164

163165
@classmethod
164166
def _untreated_outcome(cls, x):
165-
return np.dot(x, cls.beta) + normal(0, 1)
167+
return np.dot(x, cls.beta) + cls.random_state.normal(0, 1)
166168

167169
@classmethod
168170
def _const_te(cls, x):
@@ -185,9 +187,9 @@ def _generate_data(cls, n, d, untreated_outcome, treatment_effect, propensity):
185187
propensity (func): probability of treatment conditional on covariates
186188
"""
187189
# Generate covariates
188-
X = multivariate_normal(np.zeros(d), np.diag(np.ones(d)), n)
190+
X = cls.random_state.multivariate_normal(np.zeros(d), np.diag(np.ones(d)), n)
189191
# Generate treatment
190-
T = np.apply_along_axis(lambda x: binomial(1, propensity(x), 1)[0], 1, X)
192+
T = np.apply_along_axis(lambda x: cls.random_state.binomial(1, propensity(x), 1)[0], 1, X)
191193
# Calculate outcome
192194
Y0 = np.apply_along_axis(lambda x: untreated_outcome(x), 1, X)
193195
treat_effect = np.apply_along_axis(lambda x: treatment_effect(x), 1, X)

notebooks/Double Machine Learning Examples.ipynb

Lines changed: 989 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)