From 0fdfe83518eb28fa14946aee6011a1c31a73d53c Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Tue, 10 Sep 2024 12:20:13 +0100 Subject: [PATCH 01/22] add new methods to the notebooks and readme Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c276c4ae..6bec2a5b 100644 --- a/README.md +++ b/README.md @@ -190,6 +190,8 @@ print(f"Best estimator: {ct.best_estimator}") ``` +Now if outcome_model="auto" in the CausalTune constructor, we search over a simultaneous search space for the EconML estimators and for FLAML wrappers for common regressors. The old behavior is now achieved by outcome_model="nested" (Refitting AutoML for each estimator). + ## Supported Models The package supports the following causal estimators: * Meta Learners: From 311f264096a2dc18c4906a3cbca50249da857eb5 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Tue, 10 Sep 2024 12:25:00 +0100 Subject: [PATCH 02/22] Update README.md Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6bec2a5b..77985b41 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,9 @@ print(f"Best estimator: {ct.best_estimator}") ``` -Now if outcome_model="auto" in the CausalTune constructor, we search over a simultaneous search space for the EconML estimators and for FLAML wrappers for common regressors. The old behavior is now achieved by outcome_model="nested" (Refitting AutoML for each estimator). +Now if ***outcome_model="auto"*** in the CausalTune constructor, we search over a simultaneous search space for the EconML estimators and for FLAML wrappers for common regressors. The old behavior is now achieved by ***outcome_model="nested"*** (Refitting AutoML for each estimator). + +You can also preprocess the data in the CausalityDataset using one of the popular category encoders: ***OneHot, WoE, Label, Target***. ## Supported Models The package supports the following causal estimators: From e2285ab3751641e3cbd9d364869c4440f98ef001 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Tue, 10 Sep 2024 14:31:21 +0100 Subject: [PATCH 03/22] Delete notebooks/Standard errors.ipynb Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- notebooks/Standard errors.ipynb | 659 -------------------------------- 1 file changed, 659 deletions(-) delete mode 100644 notebooks/Standard errors.ipynb diff --git a/notebooks/Standard errors.ipynb b/notebooks/Standard errors.ipynb deleted file mode 100644 index 797fcea9..00000000 --- a/notebooks/Standard errors.ipynb +++ /dev/null @@ -1,659 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "id": "a34f30c6", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, - "source": [ - "# Standard errors\n", - "\n", - "This is a notebook demonstrating how to obtain standard errors for your generated impact estimates." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "43b770ca", - "metadata": {}, - "outputs": [], - "source": [ - "%load_ext autoreload\n", - "%autoreload 2\n", - "import os, sys\n", - "import warnings\n", - "warnings.filterwarnings('ignore') # suppress sklearn deprecation warnings for now..\n", - "\n", - "import pandas as pd\n", - "import numpy as np\n", - "from sklearn.model_selection import train_test_split\n", - "\n", - "# the below checks for whether we run dowhy, causaltune, and FLAML from source\n", - "root_path = root_path = os.path.realpath('../..')\n", - "try:\n", - " import causaltune\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"causaltune\"))\n", - "\n", - "try:\n", - " import dowhy\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"dowhy\"))\n", - "\n", - "try:\n", - " import flaml\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"FLAML\"))\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "53241021", - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# this makes the notebook expand to full width of the browser window\n", - "from IPython.core.display import display, HTML\n", - "display(HTML(\"\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "5ed9b5f7", - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, - "outputs": [ - { - "data": { - "application/javascript": "\n// turn off scrollable windows for large output\nIPython.OutputArea.prototype._should_scroll = function(lines) {\n return false;\n}\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%%javascript\n", - "\n", - "// turn off scrollable windows for large output\n", - "IPython.OutputArea.prototype._should_scroll = function(lines) {\n", - " return false;\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "da208ce6", - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, - "outputs": [], - "source": [ - "from causaltune import CausalTune\n", - "from causaltune.datasets import synth_ihdp" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "ab536d1b", - "metadata": {}, - "source": [ - "## Loading data" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "96719b4d", - "metadata": {}, - "outputs": [], - "source": [ - "# load toy dataset and apply standard pre-processing\n", - "cd = synth_ihdp()\n", - "cd.preprocess_dataset()" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "49e4721b", - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
treatmenty_factualrandomx1x2x3x4x5x6x7...x16x17x18x19x20x21x22x23x24x25
015.5999161.0-0.528603-0.3434551.1285540.161703-0.3166031.2952161.0...1.01.01.01.00.00.00.00.00.00.0
106.8758561.0-1.736945-1.8020020.3838282.244319-0.6291891.2952160.0...1.01.01.01.00.00.00.00.00.00.0
202.9962731.0-0.807451-0.202946-0.360898-0.8796060.808706-0.5265560.0...1.00.01.01.00.00.00.00.00.00.0
301.3662060.00.3900830.596582-1.850350-0.879606-0.004017-0.8577870.0...1.00.01.01.00.00.00.00.00.00.0
401.9635381.0-1.045228-0.6027100.0114650.1617030.683672-0.3609401.0...1.01.01.01.00.00.00.00.00.00.0
\n", - "

5 rows × 28 columns

\n", - "
" - ], - "text/plain": [ - " treatment y_factual random x1 x2 x3 x4 \\\n", - "0 1 5.599916 1.0 -0.528603 -0.343455 1.128554 0.161703 \n", - "1 0 6.875856 1.0 -1.736945 -1.802002 0.383828 2.244319 \n", - "2 0 2.996273 1.0 -0.807451 -0.202946 -0.360898 -0.879606 \n", - "3 0 1.366206 0.0 0.390083 0.596582 -1.850350 -0.879606 \n", - "4 0 1.963538 1.0 -1.045228 -0.602710 0.011465 0.161703 \n", - "\n", - " x5 x6 x7 ... x16 x17 x18 x19 x20 x21 x22 x23 x24 \\\n", - "0 -0.316603 1.295216 1.0 ... 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 \n", - "1 -0.629189 1.295216 0.0 ... 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 \n", - "2 0.808706 -0.526556 0.0 ... 1.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 \n", - "3 -0.004017 -0.857787 0.0 ... 1.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 \n", - "4 0.683672 -0.360940 1.0 ... 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 \n", - "\n", - " x25 \n", - "0 0.0 \n", - "1 0.0 \n", - "2 0.0 \n", - "3 0.0 \n", - "4 0.0 \n", - "\n", - "[5 rows x 28 columns]" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# inspect the preprocessed dataset\n", - "display(cd.data.head())" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "d4d1871f", - "metadata": {}, - "source": [ - "## Model training and standard errors" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "fd4b291e", - "metadata": {}, - "outputs": [], - "source": [ - "# training configs\n", - "\n", - "# set evaluation metric\n", - "metric = \"energy_distance\"\n", - "\n", - "# it's best to specify either time_budget or components_time_budget, \n", - "# and let the other one be inferred; time in seconds\n", - "time_budget = None\n", - "components_time_budget = 10\n", - "\n", - "# specify training set size\n", - "train_size = 0.7\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "e0f63d12", - "metadata": {}, - "source": [ - "Note that in the example below, we are passing `'cheap_inference'` to `estimator_list`. This configuration will restrict the selection of estimators to the ones that have analytical standard errors." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "097c923e", - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%%\n" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Fitting a Propensity-Weighted scoring estimator to be used in scoring tasks\n", - "Initial configs: [{'estimator': {'estimator_name': 'backdoor.econml.dr.ForestDRLearner', 'min_propensity': 1e-06, 'n_estimators': 100, 'min_samples_split': 5, 'min_samples_leaf': 5, 'min_weight_fraction_leaf': 0.0, 'max_features': 'auto', 'min_impurity_decrease': 0.0, 'max_samples': 0.45, 'min_balancedness_tol': 0.45, 'honest': True, 'subforest_size': 4}}, {'estimator': {'estimator_name': 'backdoor.econml.dr.LinearDRLearner', 'fit_cate_intercept': True, 'min_propensity': 1e-06}}, {'estimator': {'estimator_name': 'backdoor.econml.dr.SparseLinearDRLearner', 'fit_cate_intercept': True, 'n_alphas': 100, 'n_alphas_cov': 10, 'min_propensity': 1e-06, 'tol': 0.0001, 'max_iter': 10000, 'mc_agg': 'mean'}}, {'estimator': {'estimator_name': 'backdoor.econml.dml.LinearDML', 'fit_cate_intercept': True, 'mc_agg': 'mean'}}, {'estimator': {'estimator_name': 'backdoor.econml.dml.SparseLinearDML', 'fit_cate_intercept': True, 'n_alphas': 100, 'n_alphas_cov': 10, 'tol': 0.0001, 'max_iter': 10000, 'mc_agg': 'mean'}}, {'estimator': {'estimator_name': 'backdoor.econml.dml.CausalForestDML', 'drate': True, 'n_estimators': 100, 'criterion': 'mse', 'min_samples_split': 10, 'min_samples_leaf': 5, 'min_weight_fraction_leaf': 0.0, 'max_features': 'auto', 'min_impurity_decrease': 0.0, 'max_samples': 0.45, 'min_balancedness_tol': 0.45, 'honest': True, 'fit_intercept': True, 'subforest_size': 4}}]\n", - "---------------------\n", - "Best estimator: backdoor.econml.dr.ForestDRLearner\n", - "Best config: {'estimator': {'estimator_name': 'backdoor.econml.dr.ForestDRLearner', 'min_propensity': 1e-06, 'n_estimators': 100, 'min_samples_split': 5, 'min_samples_leaf': 5, 'min_weight_fraction_leaf': 0.0, 'max_features': 'auto', 'min_impurity_decrease': 0.0, 'max_samples': 0.45, 'min_balancedness_tol': 0.45, 'honest': 1, 'subforest_size': 4}}\n", - "Best score: 0.28241795991132435\n" - ] - } - ], - "source": [ - "ct = CausalTune(\n", - " estimator_list='cheap_inference',\n", - " metric=metric,\n", - " verbose=0,\n", - " components_verbose=0,\n", - " time_budget=time_budget,\n", - " components_time_budget=components_time_budget,\n", - " train_size=train_size\n", - ")\n", - "\n", - "\n", - "# run causaltune\n", - "ct.fit(data=cd, outcome=cd.outcomes[0])\n", - "\n", - "print('---------------------')\n", - "# return best estimator\n", - "print(f\"Best estimator: {ct.best_estimator}\")\n", - "# config of best estimator:\n", - "print(f\"Best config: {ct.best_config}\")\n", - "# best score:\n", - "print(f\"Best score: {ct.best_score}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "dd8b4d04", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[3.08417039],\n", - " [4.10807041],\n", - " [4.32885751],\n", - " [4.53901377],\n", - " [4.19668172]])" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# obtaining effect estimates\n", - "\n", - "test_df = ct.test_df\n", - "\n", - "cates = ct.effect(test_df)\n", - "display(cates[:5,])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "8c819410", - "metadata": {}, - "source": [ - "Below we show how to generate standard errors using `CausalTune.effect_stderr()`. By default, this will use the `best_estimator` identified during training.\n", - "\n", - "If this estimator does not have analytical standard errors, it will be refitted `n_bootstrap_samples`-times on the training data." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "0ee744d2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[0.28758771],\n", - " [0.2267228 ],\n", - " [0.29267037],\n", - " [0.22686985],\n", - " [0.28054057]])" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# generating standard errors by refitting train_df \n", - "se = ct.effect_stderr(ct.test_df)\n", - "display(se[:5,])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "9a474ab5", - "metadata": {}, - "source": [ - "In addition to merely generating standard errors, we have the option to generate various other statistical inferences for the effect, such as the standard error, z-test score, and p-value for each sample `X{i}`." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "277adbcc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
point_estimatestderrzstatpvalueci_lowerci_upper
X
03.0840.28810.7240.02.6113.557
14.1080.22718.1190.03.7354.481
24.3290.29314.7910.03.8474.810
34.5390.22720.0070.04.1664.912
44.1970.28114.9590.03.7354.658
\n", - "
" - ], - "text/plain": [ - " point_estimate stderr zstat pvalue ci_lower ci_upper\n", - "X \n", - "0 3.084 0.288 10.724 0.0 2.611 3.557\n", - "1 4.108 0.227 18.119 0.0 3.735 4.481\n", - "2 4.329 0.293 14.791 0.0 3.847 4.810\n", - "3 4.539 0.227 20.007 0.0 4.166 4.912\n", - "4 4.197 0.281 14.959 0.0 3.735 4.658" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ct.effect_inference(test_df)[0].summary_frame(alpha=0.1, value=0, decimals=3).head()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "causality", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.16" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From 0735a53c0184e71e35eabc86833a8d548b4c3690 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Tue, 10 Sep 2024 14:31:52 +0100 Subject: [PATCH 04/22] Add files via upload Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- notebooks/Standard errors.ipynb | 654 ++++++++++++++++++++++++++++++++ 1 file changed, 654 insertions(+) create mode 100644 notebooks/Standard errors.ipynb diff --git a/notebooks/Standard errors.ipynb b/notebooks/Standard errors.ipynb new file mode 100644 index 00000000..edc89c66 --- /dev/null +++ b/notebooks/Standard errors.ipynb @@ -0,0 +1,654 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a34f30c6", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "# Standard errors\n", + "\n", + "This is a notebook demonstrating how to obtain standard errors for your generated impact estimates." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "43b770ca", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2\n", + "import os, sys\n", + "import warnings\n", + "warnings.filterwarnings('ignore') # suppress sklearn deprecation warnings for now..\n", + "\n", + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "# the below checks for whether we run dowhy, causaltune, and FLAML from source\n", + "root_path = root_path = os.path.realpath('../..')\n", + "try:\n", + " import causaltune\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"causaltune\"))\n", + "\n", + "try:\n", + " import dowhy\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"dowhy\"))\n", + "\n", + "try:\n", + " import flaml\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"FLAML\"))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "53241021", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# this makes the notebook expand to full width of the browser window\n", + "from IPython.core.display import display, HTML\n", + "display(HTML(\"\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "5ed9b5f7", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "%%javascript\n", + "\n", + "// turn off scrollable windows for large output\n", + "IPython.OutputArea.prototype._should_scroll = function(lines) {\n", + " return false;\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "da208ce6", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "from causaltune import CausalTune\n", + "from causaltune.datasets import synth_ihdp" + ] + }, + { + "cell_type": "markdown", + "id": "ab536d1b", + "metadata": {}, + "source": [ + "## Loading data" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "96719b4d", + "metadata": {}, + "outputs": [], + "source": [ + "# load toy dataset and apply standard pre-processing\n", + "cd = synth_ihdp()\n", + "cd.preprocess_dataset()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "49e4721b", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
treatmenty_factualrandomx1x2x3x4x5x6x7...x16x17x18x19x20x21x22x23x24x25
015.5999161.0-0.528603-0.3434551.1285540.161703-0.3166031.2952161.0...1.01.01.01.00.00.00.00.00.00.0
106.8758561.0-1.736945-1.8020020.3838282.244319-0.6291891.2952160.0...1.01.01.01.00.00.00.00.00.00.0
202.9962730.0-0.807451-0.202946-0.360898-0.8796060.808706-0.5265560.0...1.00.01.01.00.00.00.00.00.00.0
301.3662061.00.3900830.596582-1.850350-0.879606-0.004017-0.8577870.0...1.00.01.01.00.00.00.00.00.00.0
401.9635380.0-1.045228-0.6027100.0114650.1617030.683672-0.3609401.0...1.01.01.01.00.00.00.00.00.00.0
\n", + "

5 rows × 28 columns

\n", + "
" + ], + "text/plain": [ + " treatment y_factual random x1 x2 x3 x4 \\\n", + "0 1 5.599916 1.0 -0.528603 -0.343455 1.128554 0.161703 \n", + "1 0 6.875856 1.0 -1.736945 -1.802002 0.383828 2.244319 \n", + "2 0 2.996273 0.0 -0.807451 -0.202946 -0.360898 -0.879606 \n", + "3 0 1.366206 1.0 0.390083 0.596582 -1.850350 -0.879606 \n", + "4 0 1.963538 0.0 -1.045228 -0.602710 0.011465 0.161703 \n", + "\n", + " x5 x6 x7 ... x16 x17 x18 x19 x20 x21 x22 x23 x24 \\\n", + "0 -0.316603 1.295216 1.0 ... 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 \n", + "1 -0.629189 1.295216 0.0 ... 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 \n", + "2 0.808706 -0.526556 0.0 ... 1.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 \n", + "3 -0.004017 -0.857787 0.0 ... 1.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 \n", + "4 0.683672 -0.360940 1.0 ... 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 \n", + "\n", + " x25 \n", + "0 0.0 \n", + "1 0.0 \n", + "2 0.0 \n", + "3 0.0 \n", + "4 0.0 \n", + "\n", + "[5 rows x 28 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# inspect the preprocessed dataset\n", + "display(cd.data.head())" + ] + }, + { + "cell_type": "markdown", + "id": "d4d1871f", + "metadata": {}, + "source": [ + "## Model training and standard errors" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "fd4b291e", + "metadata": {}, + "outputs": [], + "source": [ + "# training configs\n", + "\n", + "# set evaluation metric\n", + "metric = \"energy_distance\"\n", + "\n", + "# it's best to specify either time_budget or components_time_budget, \n", + "# and let the other one be inferred; time in seconds\n", + "time_budget = None\n", + "components_time_budget = 10\n", + "\n", + "# specify training set size\n", + "train_size = 0.7\n" + ] + }, + { + "cell_type": "markdown", + "id": "e0f63d12", + "metadata": {}, + "source": [ + "Note that in the example below, we are passing `'cheap_inference'` to `estimator_list`. This configuration will restrict the selection of estimators to the ones that have analytical standard errors.\n", + "\n", + "Now if `outcome_model=\"auto\"` in the CausalTune constructor, we search over a simultaneous search space for the EconML estimators and for FLAML wrappers for common regressors. The old behavior is now achieved by `outcome_model=\"nested\"` (Refitting AutoML for each estimator).\n", + "\n", + "You can also preprocess the data in the CausalityDataset using one of the popular category encoders: OneHot, WoE, Label, Target." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "097c923e", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fitting a Propensity-Weighted scoring estimator to be used in scoring tasks\n", + "Propensity Model Fitted Successfully\n", + "---------------------\n", + "Best estimator: backdoor.econml.dr.ForestDRLearner\n", + "Best config: {'estimator': {'estimator_name': 'backdoor.econml.dr.ForestDRLearner', 'min_propensity': 4.1309041114224745e-06, 'n_estimators': 51, 'min_samples_split': 2, 'min_samples_leaf': 5, 'min_weight_fraction_leaf': 0.0, 'max_features': 'log2', 'min_impurity_decrease': 0, 'max_samples': 0.4714678358460523, 'min_balancedness_tol': 0.48107268073765275, 'honest': 1, 'subforest_size': 5}, 'outcome_estimator': {'alpha': 0.0680343251051132, 'fit_intercept': True, 'eps': 3.581001561497127e-16, 'estimator_name': 'lasso_lars'}}\n", + "Best score: 0.19782534210362535\n" + ] + } + ], + "source": [ + "ct = CausalTune(\n", + " estimator_list='cheap_inference',\n", + " metric=metric,\n", + " verbose=0,\n", + " components_verbose=0,\n", + " time_budget=time_budget,\n", + " components_time_budget=components_time_budget,\n", + " train_size=train_size,\n", + " outcome_model=\"auto\"\n", + ")\n", + "\n", + "\n", + "# run causaltune\n", + "ct.fit(data=cd, outcome=cd.outcomes[0])\n", + "\n", + "print('---------------------')\n", + "# return best estimator\n", + "print(f\"Best estimator: {ct.best_estimator}\")\n", + "# config of best estimator:\n", + "print(f\"Best config: {ct.best_config}\")\n", + "# best score:\n", + "print(f\"Best score: {ct.best_score}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "dd8b4d04", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[3.06847504],\n", + " [5.10172326],\n", + " [2.3049086 ],\n", + " [4.39115942],\n", + " [4.38397264]])" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# obtaining effect estimates\n", + "\n", + "test_df = ct.test_df\n", + "\n", + "cates = ct.effect(test_df)\n", + "display(cates[:5,])" + ] + }, + { + "cell_type": "markdown", + "id": "8c819410", + "metadata": {}, + "source": [ + "Below we show how to generate standard errors using `CausalTune.effect_stderr()`. By default, this will use the `best_estimator` identified during training.\n", + "\n", + "If this estimator does not have analytical standard errors, it will be refitted `n_bootstrap_samples`-times on the training data." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "0ee744d2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0.74527346],\n", + " [0.76067972],\n", + " [0.48614067],\n", + " [0.42494167],\n", + " [0.52123297]])" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# generating standard errors by refitting train_df \n", + "se = ct.effect_stderr(ct.test_df)\n", + "display(se[:5,])" + ] + }, + { + "cell_type": "markdown", + "id": "9a474ab5", + "metadata": {}, + "source": [ + "In addition to merely generating standard errors, we have the option to generate various other statistical inferences for the effect, such as the standard error, z-test score, and p-value for each sample `X{i}`." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "277adbcc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
point_estimatestderrzstatpvalueci_lowerci_upper
X
03.0680.7454.1170.01.8434.294
15.1020.7616.7070.03.8516.353
22.3050.4864.7410.01.5053.105
34.3910.42510.3340.03.6925.090
44.3840.5218.4110.03.5275.241
\n", + "
" + ], + "text/plain": [ + " point_estimate stderr zstat pvalue ci_lower ci_upper\n", + "X \n", + "0 3.068 0.745 4.117 0.0 1.843 4.294\n", + "1 5.102 0.761 6.707 0.0 3.851 6.353\n", + "2 2.305 0.486 4.741 0.0 1.505 3.105\n", + "3 4.391 0.425 10.334 0.0 3.692 5.090\n", + "4 4.384 0.521 8.411 0.0 3.527 5.241" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ct.effect_inference(test_df)[0].summary_frame(alpha=0.1, value=0, decimals=3).head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b200c45-d652-42a8-b8f1-611a119143c3", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From f7bcca05e6448c2aaf53301f3baff7e4677d301e Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Tue, 10 Sep 2024 14:59:00 +0100 Subject: [PATCH 05/22] Delete notebooks/ERUPT under simulated random assignment.ipynb Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- ...PT under simulated random assignment.ipynb | 500 ------------------ 1 file changed, 500 deletions(-) delete mode 100644 notebooks/ERUPT under simulated random assignment.ipynb diff --git a/notebooks/ERUPT under simulated random assignment.ipynb b/notebooks/ERUPT under simulated random assignment.ipynb deleted file mode 100644 index 6ac2b20b..00000000 --- a/notebooks/ERUPT under simulated random assignment.ipynb +++ /dev/null @@ -1,500 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "id": "a34f30c6", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, - "source": [ - "# ERUPT under simulated random assignment" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "c37a7a94", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "OMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead.\n" - ] - } - ], - "source": [ - "%load_ext autoreload\n", - "%autoreload 2\n", - "import os, sys\n", - "import warnings\n", - "warnings.filterwarnings('ignore') # suppress sklearn deprecation warnings for now..\n", - "\n", - "import pandas as pd\n", - "import numpy as np\n", - "from sklearn.model_selection import train_test_split\n", - "\n", - "# the below checks for whether we run dowhy, causaltune, and FLAML from source\n", - "root_path = root_path = os.path.realpath('../..')\n", - "try:\n", - " import causaltune\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"causaltune\"))\n", - "\n", - "try:\n", - " import dowhy\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"dowhy\"))\n", - "\n", - "try:\n", - " import flaml\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"FLAML\"))\n", - "\n", - "from causaltune import CausalTune\n", - "from causaltune.datasets import generate_non_random_dataset\n", - "from causaltune.erupt import DummyPropensity, ERUPT\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "53241021", - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# this makes the notebook expand to full width of the browser window\n", - "from IPython.core.display import display, HTML\n", - "display(HTML(\"\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "5ed9b5f7", - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, - "outputs": [ - { - "data": { - "application/javascript": [ - "\n", - "// turn off scrollable windows for large output\n", - "IPython.OutputArea.prototype._should_scroll = function(lines) {\n", - " return false;\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%%javascript\n", - "\n", - "// turn off scrollable windows for large output\n", - "IPython.OutputArea.prototype._should_scroll = function(lines) {\n", - " return false;\n", - "}" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "af5333b0", - "metadata": {}, - "source": [ - "## Loading data and model training" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "a0211b9a", - "metadata": {}, - "outputs": [], - "source": [ - "# load toy dataset with non-random assignment and apply standard pre-processing\n", - "cd = generate_non_random_dataset()\n", - "cd.preprocess_dataset()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "6cec1abf", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
TYrandomX1X2X3X4X5propensity
001.2393081.0-0.847134-0.3985630.1765390.9573601.1224570.328241
100.1084420.0-0.583898-0.8992651.177333-0.563962-0.6147370.195308
21-0.8973100.0-2.2375900.061438-0.4625190.777278-1.3790220.345805
310.7574751.0-0.0473190.354603-1.9764290.0819450.4240410.695707
400.8534781.0-0.2568320.0487481.536085-1.0274150.6897330.304767
\n", - "
" - ], - "text/plain": [ - " T Y random X1 X2 X3 X4 X5 \\\n", - "0 0 1.239308 1.0 -0.847134 -0.398563 0.176539 0.957360 1.122457 \n", - "1 0 0.108442 0.0 -0.583898 -0.899265 1.177333 -0.563962 -0.614737 \n", - "2 1 -0.897310 0.0 -2.237590 0.061438 -0.462519 0.777278 -1.379022 \n", - "3 1 0.757475 1.0 -0.047319 0.354603 -1.976429 0.081945 0.424041 \n", - "4 0 0.853478 1.0 -0.256832 0.048748 1.536085 -1.027415 0.689733 \n", - "\n", - " propensity \n", - "0 0.328241 \n", - "1 0.195308 \n", - "2 0.345805 \n", - "3 0.695707 \n", - "4 0.304767 " - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "display(cd.data.head())" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "4b5d0795", - "metadata": {}, - "outputs": [], - "source": [ - "# training configs\n", - "\n", - "# set evaluation metric\n", - "metric = \"energy_distance\"\n", - "\n", - "# it's best to specify either time_budget or components_time_budget, \n", - "# and let the other one be inferred; time in seconds\n", - "time_budget = None\n", - "components_time_budget = 10\n", - "\n", - "# specify training set size\n", - "train_size = 0.7" - ] - }, - { - "cell_type": "markdown", - "id": "33681e65-6dd4-4c7d-a62d-925572b39e81", - "metadata": {}, - "source": [ - "Now if outcome_model=\"auto\" in the CausalTune constructor, we search over a simultaneous search space for the EconML estimators and for FLAML wrappers for common regressors. The old behavior is now achieved by outcome_model=\"nested\" (the default for now)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "a51c87f4", - "metadata": {}, - "outputs": [], - "source": [ - "ct = CausalTune(\n", - " estimator_list=[\"CausalForestDML\", \"XLearner\"],\n", - " metric=metric,\n", - " verbose=0,\n", - " components_verbose=0,\n", - " time_budget=time_budget,\n", - " components_time_budget=components_time_budget,\n", - " train_size=train_size,\n", - " outcome_model=\"auto\"\n", - ")\n", - "\n", - "\n", - "# run causaltune\n", - "ct.fit(data=cd, outcome=cd.outcomes[0])\n", - "\n", - "print('---------------------')\n", - "# return best estimator\n", - "print(f\"Best estimator: {ct.best_estimator}\")\n", - "# config of best estimator:\n", - "print(f\"Best config: {ct.best_config}\")\n", - "# best score:\n", - "print(f\"Best score: {ct.best_score}\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "19bcfc2e", - "metadata": {}, - "source": [ - "## Random ERUPT" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "2bea4e38", - "metadata": {}, - "source": [ - "Below we demonstrate how to use Estimated Response Under Proposed Treatment (ERUPT) to estimate the average treatment effect had the treatment been assigned randomly. Recall that the dataset used in this example is constructed in a way that the treatment propensity is a function of a unit's covariates." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "db1b69a3", - "metadata": {}, - "outputs": [], - "source": [ - "use_df = ct.test_df" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "e8afee5a", - "metadata": {}, - "outputs": [], - "source": [ - "# computing mean ERUPT over 10 bootstrapped samples\n", - "\n", - "scores_list = []\n", - "\n", - "for i in range(10):\n", - "\n", - " bootstrap_df = use_df.sample(frac=1, replace=True)\n", - " propensities = bootstrap_df['propensity']\n", - " actual_treatment = bootstrap_df['T']\n", - " outcome = bootstrap_df['Y']\n", - "\n", - " # define the random assignment policy\n", - " random_policy = np.random.randint(0,2, size=len(bootstrap_df))\n", - "\n", - " # define a propensity model that will simply return the propensities when calling predict_proba\n", - " propensity_model = DummyPropensity(p=propensities, treatment=actual_treatment)\n", - "\n", - " # obtain ERUPT under random policy\n", - " e = ERUPT(treatment_name='T', propensity_model=propensity_model)\n", - " scores_list.append(e.score(df=use_df,outcome=outcome,policy=random_policy))\n", - "\n", - "erupt_mean = np.mean(scores_list)\n", - "erupt_sd = np.std(scores_list)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "438112f2", - "metadata": {}, - "outputs": [], - "source": [ - "# compute naive ate as difference in means\n", - "naive_ate, naive_sd, _ = ct.scorer.naive_ate(ct.test_df['T'], ct.test_df['Y'])" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "a0f6d079", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
estimated_effectsd
naive_ate0.2181510.124848
random_erupt0.0231410.216845
\n", - "
" - ], - "text/plain": [ - " estimated_effect sd\n", - "naive_ate 0.218151 0.124848\n", - "random_erupt 0.023141 0.216845" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# comparison of naive ate to mean random erupt over 10 bootstrap runs\n", - "erupt_df = pd.DataFrame([[naive_ate,naive_sd],[erupt_mean,erupt_sd]], columns=['estimated_effect', 'sd'], index=['naive_ate','random_erupt'])\n", - "display(erupt_df)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "a54530bf", - "metadata": {}, - "source": [ - "For more details on the ERUPT implementation, consult [Hitsch and Misra (2018)](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3111957). Note also that we assume that treatment takes integer values from 0 to n." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.14" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From ab41d47fe99e0ff45424d067ef581011de7e9de8 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Tue, 10 Sep 2024 14:59:11 +0100 Subject: [PATCH 06/22] Add files via upload Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- ...PT under simulated random assignment.ipynb | 485 ++++++++++++++++++ 1 file changed, 485 insertions(+) create mode 100644 notebooks/ERUPT under simulated random assignment.ipynb diff --git a/notebooks/ERUPT under simulated random assignment.ipynb b/notebooks/ERUPT under simulated random assignment.ipynb new file mode 100644 index 00000000..70c087f0 --- /dev/null +++ b/notebooks/ERUPT under simulated random assignment.ipynb @@ -0,0 +1,485 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a34f30c6", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "# ERUPT under simulated random assignment" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "c37a7a94", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2\n", + "import os, sys\n", + "import warnings\n", + "warnings.filterwarnings('ignore') # suppress sklearn deprecation warnings for now..\n", + "\n", + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "# the below checks for whether we run dowhy, causaltune, and FLAML from source\n", + "root_path = root_path = os.path.realpath('../..')\n", + "try:\n", + " import causaltune\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"causaltune\"))\n", + "\n", + "try:\n", + " import dowhy\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"dowhy\"))\n", + "\n", + "try:\n", + " import flaml\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"FLAML\"))\n", + "\n", + "from causaltune import CausalTune\n", + "from causaltune.datasets import generate_non_random_dataset\n", + "from causaltune.erupt import DummyPropensity, ERUPT\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "53241021", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# this makes the notebook expand to full width of the browser window\n", + "from IPython.core.display import display, HTML\n", + "display(HTML(\"\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "5ed9b5f7", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "# %%javascript\n", + "\n", + "# // turn off scrollable windows for large output\n", + "# IPython.OutputArea.prototype._should_scroll = function(lines) {\n", + "# return false;\n", + "# }" + ] + }, + { + "cell_type": "markdown", + "id": "af5333b0", + "metadata": {}, + "source": [ + "## Loading data and model training" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a0211b9a", + "metadata": {}, + "outputs": [], + "source": [ + "# load toy dataset with non-random assignment and apply standard pre-processing\n", + "cd = generate_non_random_dataset()\n", + "cd.preprocess_dataset()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "6cec1abf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
TYrandomX1X2X3X4X5propensity
00-0.5290940.0-0.325404-3.200259-1.0962310.454945-0.6829500.096673
10-2.6739121.0-2.2246411.3841330.5064850.145684-0.1952660.472952
21-1.6664440.00.687121-0.2076140.7886991.131345-0.3520910.550413
30-1.6191430.00.740413-0.6662631.027818-0.197965-2.0252200.423549
400.3311061.0-0.907719-1.7755810.072270-1.7603791.4496680.083704
\n", + "
" + ], + "text/plain": [ + " T Y random X1 X2 X3 X4 X5 \\\n", + "0 0 -0.529094 0.0 -0.325404 -3.200259 -1.096231 0.454945 -0.682950 \n", + "1 0 -2.673912 1.0 -2.224641 1.384133 0.506485 0.145684 -0.195266 \n", + "2 1 -1.666444 0.0 0.687121 -0.207614 0.788699 1.131345 -0.352091 \n", + "3 0 -1.619143 0.0 0.740413 -0.666263 1.027818 -0.197965 -2.025220 \n", + "4 0 0.331106 1.0 -0.907719 -1.775581 0.072270 -1.760379 1.449668 \n", + "\n", + " propensity \n", + "0 0.096673 \n", + "1 0.472952 \n", + "2 0.550413 \n", + "3 0.423549 \n", + "4 0.083704 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(cd.data.head())" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "4b5d0795", + "metadata": {}, + "outputs": [], + "source": [ + "# training configs\n", + "\n", + "# set evaluation metric\n", + "metric = \"energy_distance\"\n", + "\n", + "# it's best to specify either time_budget or components_time_budget, \n", + "# and let the other one be inferred; time in seconds\n", + "time_budget = None\n", + "components_time_budget = 10\n", + "\n", + "# specify training set size\n", + "train_size = 0.7" + ] + }, + { + "cell_type": "markdown", + "id": "33681e65-6dd4-4c7d-a62d-925572b39e81", + "metadata": {}, + "source": [ + "Now if `outcome_model=\"auto\"` in the CausalTune constructor, we search over a simultaneous search space for the EconML estimators and for FLAML wrappers for common regressors. The old behavior is now achieved by `outcome_model=\"nested\"` (Refitting AutoML for each estimator).\n", + "\n", + "You can also preprocess the data in the CausalityDataset using one of the popular category encoders: OneHot, WoE, Label, Target." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "a51c87f4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fitting a Propensity-Weighted scoring estimator to be used in scoring tasks\n", + "Propensity Model Fitted Successfully\n", + "---------------------\n", + "Best estimator: backdoor.econml.dml.CausalForestDML\n", + "Best config: {'estimator': {'estimator_name': 'backdoor.econml.dml.CausalForestDML', 'drate': 1, 'n_estimators': 2, 'criterion': 'het', 'min_samples_split': 12, 'min_samples_leaf': 8, 'min_weight_fraction_leaf': 0.0, 'max_features': 'log2', 'min_impurity_decrease': 0, 'max_samples': 0.2884902061383809, 'min_balancedness_tol': 0.4585520111743354, 'honest': 1, 'fit_intercept': 1, 'subforest_size': 5}, 'outcome_estimator': {'alpha': 0.006205274971406812, 'fit_intercept': True, 'eps': 7.833744321548246e-15, 'estimator_name': 'lasso_lars'}}\n", + "Best score: 0.2952285030581425\n" + ] + } + ], + "source": [ + "ct = CausalTune(\n", + " estimator_list=[\"CausalForestDML\", \"XLearner\"],\n", + " metric=metric,\n", + " verbose=0,\n", + " components_verbose=0,\n", + " time_budget=time_budget,\n", + " components_time_budget=components_time_budget,\n", + " train_size=train_size,\n", + " outcome_model=\"auto\"\n", + ")\n", + "\n", + "\n", + "# run causaltune\n", + "ct.fit(data=cd, outcome=cd.outcomes[0])\n", + "\n", + "print('---------------------')\n", + "# return best estimator\n", + "print(f\"Best estimator: {ct.best_estimator}\")\n", + "# config of best estimator:\n", + "print(f\"Best config: {ct.best_config}\")\n", + "# best score:\n", + "print(f\"Best score: {ct.best_score}\")" + ] + }, + { + "cell_type": "markdown", + "id": "19bcfc2e", + "metadata": {}, + "source": [ + "## Random ERUPT" + ] + }, + { + "cell_type": "markdown", + "id": "2bea4e38", + "metadata": {}, + "source": [ + "Below we demonstrate how to use Estimated Response Under Proposed Treatment (ERUPT) to estimate the average treatment effect had the treatment been assigned randomly. Recall that the dataset used in this example is constructed in a way that the treatment propensity is a function of a unit's covariates." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "db1b69a3", + "metadata": {}, + "outputs": [], + "source": [ + "use_df = ct.test_df" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "e8afee5a", + "metadata": {}, + "outputs": [], + "source": [ + "# computing mean ERUPT over 10 bootstrapped samples\n", + "\n", + "scores_list = []\n", + "\n", + "for i in range(10):\n", + "\n", + " bootstrap_df = use_df.sample(frac=1, replace=True)\n", + " propensities = bootstrap_df['propensity']\n", + " actual_treatment = bootstrap_df['T']\n", + " outcome = bootstrap_df['Y']\n", + "\n", + " # define the random assignment policy\n", + " random_policy = np.random.randint(0,2, size=len(bootstrap_df))\n", + "\n", + " # define a propensity model that will simply return the propensities when calling predict_proba\n", + " propensity_model = DummyPropensity(p=propensities, treatment=actual_treatment)\n", + "\n", + " # obtain ERUPT under random policy\n", + " e = ERUPT(treatment_name='T', propensity_model=propensity_model)\n", + " scores_list.append(e.score(df=use_df,outcome=outcome,policy=random_policy))\n", + "\n", + "erupt_mean = np.mean(scores_list)\n", + "erupt_sd = np.std(scores_list)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "438112f2", + "metadata": {}, + "outputs": [], + "source": [ + "# compute naive ate as difference in means\n", + "naive_ate, naive_sd, _ = ct.scorer.naive_ate(ct.test_df['T'], ct.test_df['Y'])" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "a0f6d079", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
estimated_effectsd
naive_ate0.0307400.139801
random_erupt-0.0010590.210618
\n", + "
" + ], + "text/plain": [ + " estimated_effect sd\n", + "naive_ate 0.030740 0.139801\n", + "random_erupt -0.001059 0.210618" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# comparison of naive ate to mean random erupt over 10 bootstrap runs\n", + "erupt_df = pd.DataFrame([[naive_ate,naive_sd],[erupt_mean,erupt_sd]], columns=['estimated_effect', 'sd'], index=['naive_ate','random_erupt'])\n", + "display(erupt_df)" + ] + }, + { + "cell_type": "markdown", + "id": "a54530bf", + "metadata": {}, + "source": [ + "For more details on the ERUPT implementation, consult [Hitsch and Misra (2018)](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3111957). Note also that we assume that treatment takes integer values from 0 to n." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 00005c5f3716e8e4802ecca05d7de3d911af9a2d Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Tue, 10 Sep 2024 14:59:41 +0100 Subject: [PATCH 07/22] Delete notebooks/ERUPT under simulated random assignment.ipynb Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- ...PT under simulated random assignment.ipynb | 485 ------------------ 1 file changed, 485 deletions(-) delete mode 100644 notebooks/ERUPT under simulated random assignment.ipynb diff --git a/notebooks/ERUPT under simulated random assignment.ipynb b/notebooks/ERUPT under simulated random assignment.ipynb deleted file mode 100644 index 70c087f0..00000000 --- a/notebooks/ERUPT under simulated random assignment.ipynb +++ /dev/null @@ -1,485 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "a34f30c6", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, - "source": [ - "# ERUPT under simulated random assignment" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "c37a7a94", - "metadata": {}, - "outputs": [], - "source": [ - "%load_ext autoreload\n", - "%autoreload 2\n", - "import os, sys\n", - "import warnings\n", - "warnings.filterwarnings('ignore') # suppress sklearn deprecation warnings for now..\n", - "\n", - "import pandas as pd\n", - "import numpy as np\n", - "from sklearn.model_selection import train_test_split\n", - "\n", - "# the below checks for whether we run dowhy, causaltune, and FLAML from source\n", - "root_path = root_path = os.path.realpath('../..')\n", - "try:\n", - " import causaltune\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"causaltune\"))\n", - "\n", - "try:\n", - " import dowhy\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"dowhy\"))\n", - "\n", - "try:\n", - " import flaml\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"FLAML\"))\n", - "\n", - "from causaltune import CausalTune\n", - "from causaltune.datasets import generate_non_random_dataset\n", - "from causaltune.erupt import DummyPropensity, ERUPT\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "53241021", - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# this makes the notebook expand to full width of the browser window\n", - "from IPython.core.display import display, HTML\n", - "display(HTML(\"\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "5ed9b5f7", - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, - "outputs": [], - "source": [ - "# %%javascript\n", - "\n", - "# // turn off scrollable windows for large output\n", - "# IPython.OutputArea.prototype._should_scroll = function(lines) {\n", - "# return false;\n", - "# }" - ] - }, - { - "cell_type": "markdown", - "id": "af5333b0", - "metadata": {}, - "source": [ - "## Loading data and model training" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "a0211b9a", - "metadata": {}, - "outputs": [], - "source": [ - "# load toy dataset with non-random assignment and apply standard pre-processing\n", - "cd = generate_non_random_dataset()\n", - "cd.preprocess_dataset()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "6cec1abf", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
TYrandomX1X2X3X4X5propensity
00-0.5290940.0-0.325404-3.200259-1.0962310.454945-0.6829500.096673
10-2.6739121.0-2.2246411.3841330.5064850.145684-0.1952660.472952
21-1.6664440.00.687121-0.2076140.7886991.131345-0.3520910.550413
30-1.6191430.00.740413-0.6662631.027818-0.197965-2.0252200.423549
400.3311061.0-0.907719-1.7755810.072270-1.7603791.4496680.083704
\n", - "
" - ], - "text/plain": [ - " T Y random X1 X2 X3 X4 X5 \\\n", - "0 0 -0.529094 0.0 -0.325404 -3.200259 -1.096231 0.454945 -0.682950 \n", - "1 0 -2.673912 1.0 -2.224641 1.384133 0.506485 0.145684 -0.195266 \n", - "2 1 -1.666444 0.0 0.687121 -0.207614 0.788699 1.131345 -0.352091 \n", - "3 0 -1.619143 0.0 0.740413 -0.666263 1.027818 -0.197965 -2.025220 \n", - "4 0 0.331106 1.0 -0.907719 -1.775581 0.072270 -1.760379 1.449668 \n", - "\n", - " propensity \n", - "0 0.096673 \n", - "1 0.472952 \n", - "2 0.550413 \n", - "3 0.423549 \n", - "4 0.083704 " - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "display(cd.data.head())" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "4b5d0795", - "metadata": {}, - "outputs": [], - "source": [ - "# training configs\n", - "\n", - "# set evaluation metric\n", - "metric = \"energy_distance\"\n", - "\n", - "# it's best to specify either time_budget or components_time_budget, \n", - "# and let the other one be inferred; time in seconds\n", - "time_budget = None\n", - "components_time_budget = 10\n", - "\n", - "# specify training set size\n", - "train_size = 0.7" - ] - }, - { - "cell_type": "markdown", - "id": "33681e65-6dd4-4c7d-a62d-925572b39e81", - "metadata": {}, - "source": [ - "Now if `outcome_model=\"auto\"` in the CausalTune constructor, we search over a simultaneous search space for the EconML estimators and for FLAML wrappers for common regressors. The old behavior is now achieved by `outcome_model=\"nested\"` (Refitting AutoML for each estimator).\n", - "\n", - "You can also preprocess the data in the CausalityDataset using one of the popular category encoders: OneHot, WoE, Label, Target." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "a51c87f4", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Fitting a Propensity-Weighted scoring estimator to be used in scoring tasks\n", - "Propensity Model Fitted Successfully\n", - "---------------------\n", - "Best estimator: backdoor.econml.dml.CausalForestDML\n", - "Best config: {'estimator': {'estimator_name': 'backdoor.econml.dml.CausalForestDML', 'drate': 1, 'n_estimators': 2, 'criterion': 'het', 'min_samples_split': 12, 'min_samples_leaf': 8, 'min_weight_fraction_leaf': 0.0, 'max_features': 'log2', 'min_impurity_decrease': 0, 'max_samples': 0.2884902061383809, 'min_balancedness_tol': 0.4585520111743354, 'honest': 1, 'fit_intercept': 1, 'subforest_size': 5}, 'outcome_estimator': {'alpha': 0.006205274971406812, 'fit_intercept': True, 'eps': 7.833744321548246e-15, 'estimator_name': 'lasso_lars'}}\n", - "Best score: 0.2952285030581425\n" - ] - } - ], - "source": [ - "ct = CausalTune(\n", - " estimator_list=[\"CausalForestDML\", \"XLearner\"],\n", - " metric=metric,\n", - " verbose=0,\n", - " components_verbose=0,\n", - " time_budget=time_budget,\n", - " components_time_budget=components_time_budget,\n", - " train_size=train_size,\n", - " outcome_model=\"auto\"\n", - ")\n", - "\n", - "\n", - "# run causaltune\n", - "ct.fit(data=cd, outcome=cd.outcomes[0])\n", - "\n", - "print('---------------------')\n", - "# return best estimator\n", - "print(f\"Best estimator: {ct.best_estimator}\")\n", - "# config of best estimator:\n", - "print(f\"Best config: {ct.best_config}\")\n", - "# best score:\n", - "print(f\"Best score: {ct.best_score}\")" - ] - }, - { - "cell_type": "markdown", - "id": "19bcfc2e", - "metadata": {}, - "source": [ - "## Random ERUPT" - ] - }, - { - "cell_type": "markdown", - "id": "2bea4e38", - "metadata": {}, - "source": [ - "Below we demonstrate how to use Estimated Response Under Proposed Treatment (ERUPT) to estimate the average treatment effect had the treatment been assigned randomly. Recall that the dataset used in this example is constructed in a way that the treatment propensity is a function of a unit's covariates." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "db1b69a3", - "metadata": {}, - "outputs": [], - "source": [ - "use_df = ct.test_df" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "e8afee5a", - "metadata": {}, - "outputs": [], - "source": [ - "# computing mean ERUPT over 10 bootstrapped samples\n", - "\n", - "scores_list = []\n", - "\n", - "for i in range(10):\n", - "\n", - " bootstrap_df = use_df.sample(frac=1, replace=True)\n", - " propensities = bootstrap_df['propensity']\n", - " actual_treatment = bootstrap_df['T']\n", - " outcome = bootstrap_df['Y']\n", - "\n", - " # define the random assignment policy\n", - " random_policy = np.random.randint(0,2, size=len(bootstrap_df))\n", - "\n", - " # define a propensity model that will simply return the propensities when calling predict_proba\n", - " propensity_model = DummyPropensity(p=propensities, treatment=actual_treatment)\n", - "\n", - " # obtain ERUPT under random policy\n", - " e = ERUPT(treatment_name='T', propensity_model=propensity_model)\n", - " scores_list.append(e.score(df=use_df,outcome=outcome,policy=random_policy))\n", - "\n", - "erupt_mean = np.mean(scores_list)\n", - "erupt_sd = np.std(scores_list)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "438112f2", - "metadata": {}, - "outputs": [], - "source": [ - "# compute naive ate as difference in means\n", - "naive_ate, naive_sd, _ = ct.scorer.naive_ate(ct.test_df['T'], ct.test_df['Y'])" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "a0f6d079", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
estimated_effectsd
naive_ate0.0307400.139801
random_erupt-0.0010590.210618
\n", - "
" - ], - "text/plain": [ - " estimated_effect sd\n", - "naive_ate 0.030740 0.139801\n", - "random_erupt -0.001059 0.210618" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# comparison of naive ate to mean random erupt over 10 bootstrap runs\n", - "erupt_df = pd.DataFrame([[naive_ate,naive_sd],[erupt_mean,erupt_sd]], columns=['estimated_effect', 'sd'], index=['naive_ate','random_erupt'])\n", - "display(erupt_df)" - ] - }, - { - "cell_type": "markdown", - "id": "a54530bf", - "metadata": {}, - "source": [ - "For more details on the ERUPT implementation, consult [Hitsch and Misra (2018)](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3111957). Note also that we assume that treatment takes integer values from 0 to n." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.14" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From cbd53dcc9376498175ad6c24dde53b664e4362b6 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Tue, 10 Sep 2024 14:59:52 +0100 Subject: [PATCH 08/22] Add files via upload Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- ...PT under simulated random assignment.ipynb | 485 ++++++++++++++++++ 1 file changed, 485 insertions(+) create mode 100644 notebooks/ERUPT under simulated random assignment.ipynb diff --git a/notebooks/ERUPT under simulated random assignment.ipynb b/notebooks/ERUPT under simulated random assignment.ipynb new file mode 100644 index 00000000..cf124cdc --- /dev/null +++ b/notebooks/ERUPT under simulated random assignment.ipynb @@ -0,0 +1,485 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a34f30c6", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "# ERUPT under simulated random assignment" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "c37a7a94", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2\n", + "import os, sys\n", + "import warnings\n", + "warnings.filterwarnings('ignore') # suppress sklearn deprecation warnings for now..\n", + "\n", + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "# the below checks for whether we run dowhy, causaltune, and FLAML from source\n", + "root_path = root_path = os.path.realpath('../..')\n", + "try:\n", + " import causaltune\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"causaltune\"))\n", + "\n", + "try:\n", + " import dowhy\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"dowhy\"))\n", + "\n", + "try:\n", + " import flaml\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"FLAML\"))\n", + "\n", + "from causaltune import CausalTune\n", + "from causaltune.datasets import generate_non_random_dataset\n", + "from causaltune.erupt import DummyPropensity, ERUPT\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "53241021", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# this makes the notebook expand to full width of the browser window\n", + "from IPython.core.display import display, HTML\n", + "display(HTML(\"\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "5ed9b5f7", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "%%javascript\n", + "\n", + "// turn off scrollable windows for large output\n", + "IPython.OutputArea.prototype._should_scroll = function(lines) {\n", + " return false;\n", + "}" + ] + }, + { + "cell_type": "markdown", + "id": "af5333b0", + "metadata": {}, + "source": [ + "## Loading data and model training" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a0211b9a", + "metadata": {}, + "outputs": [], + "source": [ + "# load toy dataset with non-random assignment and apply standard pre-processing\n", + "cd = generate_non_random_dataset()\n", + "cd.preprocess_dataset()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "6cec1abf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
TYrandomX1X2X3X4X5propensity
00-0.5290940.0-0.325404-3.200259-1.0962310.454945-0.6829500.096673
10-2.6739121.0-2.2246411.3841330.5064850.145684-0.1952660.472952
21-1.6664440.00.687121-0.2076140.7886991.131345-0.3520910.550413
30-1.6191430.00.740413-0.6662631.027818-0.197965-2.0252200.423549
400.3311061.0-0.907719-1.7755810.072270-1.7603791.4496680.083704
\n", + "
" + ], + "text/plain": [ + " T Y random X1 X2 X3 X4 X5 \\\n", + "0 0 -0.529094 0.0 -0.325404 -3.200259 -1.096231 0.454945 -0.682950 \n", + "1 0 -2.673912 1.0 -2.224641 1.384133 0.506485 0.145684 -0.195266 \n", + "2 1 -1.666444 0.0 0.687121 -0.207614 0.788699 1.131345 -0.352091 \n", + "3 0 -1.619143 0.0 0.740413 -0.666263 1.027818 -0.197965 -2.025220 \n", + "4 0 0.331106 1.0 -0.907719 -1.775581 0.072270 -1.760379 1.449668 \n", + "\n", + " propensity \n", + "0 0.096673 \n", + "1 0.472952 \n", + "2 0.550413 \n", + "3 0.423549 \n", + "4 0.083704 " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(cd.data.head())" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "4b5d0795", + "metadata": {}, + "outputs": [], + "source": [ + "# training configs\n", + "\n", + "# set evaluation metric\n", + "metric = \"energy_distance\"\n", + "\n", + "# it's best to specify either time_budget or components_time_budget, \n", + "# and let the other one be inferred; time in seconds\n", + "time_budget = None\n", + "components_time_budget = 10\n", + "\n", + "# specify training set size\n", + "train_size = 0.7" + ] + }, + { + "cell_type": "markdown", + "id": "33681e65-6dd4-4c7d-a62d-925572b39e81", + "metadata": {}, + "source": [ + "Now if `outcome_model=\"auto\"` in the CausalTune constructor, we search over a simultaneous search space for the EconML estimators and for FLAML wrappers for common regressors. The old behavior is now achieved by `outcome_model=\"nested\"` (Refitting AutoML for each estimator).\n", + "\n", + "You can also preprocess the data in the CausalityDataset using one of the popular category encoders: OneHot, WoE, Label, Target." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "a51c87f4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fitting a Propensity-Weighted scoring estimator to be used in scoring tasks\n", + "Propensity Model Fitted Successfully\n", + "---------------------\n", + "Best estimator: backdoor.econml.dml.CausalForestDML\n", + "Best config: {'estimator': {'estimator_name': 'backdoor.econml.dml.CausalForestDML', 'drate': 1, 'n_estimators': 2, 'criterion': 'het', 'min_samples_split': 12, 'min_samples_leaf': 8, 'min_weight_fraction_leaf': 0.0, 'max_features': 'log2', 'min_impurity_decrease': 0, 'max_samples': 0.2884902061383809, 'min_balancedness_tol': 0.4585520111743354, 'honest': 1, 'fit_intercept': 1, 'subforest_size': 5}, 'outcome_estimator': {'alpha': 0.006205274971406812, 'fit_intercept': True, 'eps': 7.833744321548246e-15, 'estimator_name': 'lasso_lars'}}\n", + "Best score: 0.2952285030581425\n" + ] + } + ], + "source": [ + "ct = CausalTune(\n", + " estimator_list=[\"CausalForestDML\", \"XLearner\"],\n", + " metric=metric,\n", + " verbose=0,\n", + " components_verbose=0,\n", + " time_budget=time_budget,\n", + " components_time_budget=components_time_budget,\n", + " train_size=train_size,\n", + " outcome_model=\"auto\"\n", + ")\n", + "\n", + "\n", + "# run causaltune\n", + "ct.fit(data=cd, outcome=cd.outcomes[0])\n", + "\n", + "print('---------------------')\n", + "# return best estimator\n", + "print(f\"Best estimator: {ct.best_estimator}\")\n", + "# config of best estimator:\n", + "print(f\"Best config: {ct.best_config}\")\n", + "# best score:\n", + "print(f\"Best score: {ct.best_score}\")" + ] + }, + { + "cell_type": "markdown", + "id": "19bcfc2e", + "metadata": {}, + "source": [ + "## Random ERUPT" + ] + }, + { + "cell_type": "markdown", + "id": "2bea4e38", + "metadata": {}, + "source": [ + "Below we demonstrate how to use Estimated Response Under Proposed Treatment (ERUPT) to estimate the average treatment effect had the treatment been assigned randomly. Recall that the dataset used in this example is constructed in a way that the treatment propensity is a function of a unit's covariates." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "db1b69a3", + "metadata": {}, + "outputs": [], + "source": [ + "use_df = ct.test_df" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "e8afee5a", + "metadata": {}, + "outputs": [], + "source": [ + "# computing mean ERUPT over 10 bootstrapped samples\n", + "\n", + "scores_list = []\n", + "\n", + "for i in range(10):\n", + "\n", + " bootstrap_df = use_df.sample(frac=1, replace=True)\n", + " propensities = bootstrap_df['propensity']\n", + " actual_treatment = bootstrap_df['T']\n", + " outcome = bootstrap_df['Y']\n", + "\n", + " # define the random assignment policy\n", + " random_policy = np.random.randint(0,2, size=len(bootstrap_df))\n", + "\n", + " # define a propensity model that will simply return the propensities when calling predict_proba\n", + " propensity_model = DummyPropensity(p=propensities, treatment=actual_treatment)\n", + "\n", + " # obtain ERUPT under random policy\n", + " e = ERUPT(treatment_name='T', propensity_model=propensity_model)\n", + " scores_list.append(e.score(df=use_df,outcome=outcome,policy=random_policy))\n", + "\n", + "erupt_mean = np.mean(scores_list)\n", + "erupt_sd = np.std(scores_list)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "438112f2", + "metadata": {}, + "outputs": [], + "source": [ + "# compute naive ate as difference in means\n", + "naive_ate, naive_sd, _ = ct.scorer.naive_ate(ct.test_df['T'], ct.test_df['Y'])" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "a0f6d079", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
estimated_effectsd
naive_ate0.0307400.139801
random_erupt-0.0010590.210618
\n", + "
" + ], + "text/plain": [ + " estimated_effect sd\n", + "naive_ate 0.030740 0.139801\n", + "random_erupt -0.001059 0.210618" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# comparison of naive ate to mean random erupt over 10 bootstrap runs\n", + "erupt_df = pd.DataFrame([[naive_ate,naive_sd],[erupt_mean,erupt_sd]], columns=['estimated_effect', 'sd'], index=['naive_ate','random_erupt'])\n", + "display(erupt_df)" + ] + }, + { + "cell_type": "markdown", + "id": "a54530bf", + "metadata": {}, + "source": [ + "For more details on the ERUPT implementation, consult [Hitsch and Misra (2018)](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3111957). Note also that we assume that treatment takes integer values from 0 to n." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From c8bfbd81f618986512056513c76d6fbb9f5a2211 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Tue, 10 Sep 2024 15:06:01 +0100 Subject: [PATCH 09/22] Delete notebooks/Multiple treatments examples.ipynb Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- notebooks/Multiple treatments examples.ipynb | 1322 ------------------ 1 file changed, 1322 deletions(-) delete mode 100644 notebooks/Multiple treatments examples.ipynb diff --git a/notebooks/Multiple treatments examples.ipynb b/notebooks/Multiple treatments examples.ipynb deleted file mode 100644 index 4242c362..00000000 --- a/notebooks/Multiple treatments examples.ipynb +++ /dev/null @@ -1,1322 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "afbd11d5-c7d7-4467-9b80-fa73b58bae00", - "metadata": {}, - "source": [ - "# Multiple treatments examples\n", - "- In this notebook, we want to demonstrate common use cases where we have multiple treatments (ab testing is not covered, as you can just use another notebook for it)\n", - "- Simple CausalTune training with multiple treatments\n", - "- Applying custom propensities and train CausalTune (for example, in Uplift models)\n", - "- ERUPT for multiple treatments" - ] - }, - { - "cell_type": "markdown", - "id": "11352cfb-89b2-48be-adb5-e68cd95d2ce8", - "metadata": {}, - "source": [ - "### Setting up the data and causal model: CausalityDataset\n", - "- This notebook demonstrates how to train CausalTune with multiple custom propensities.\n", - "- The easiest example here is uplift modeling. Suppose we trained a model, sent messages, launched an experiment.\n", - "- And now we want to train more complex model using previous round model as propensities." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "fbcf1af0-3ad3-4666-b465-633f950409be", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "OMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead.\n" - ] - } - ], - "source": [ - "%load_ext autoreload\n", - "%autoreload 2\n", - "import os, sys\n", - "import warnings\n", - "warnings.filterwarnings('ignore') # suppress sklearn deprecation warnings for now..\n", - "\n", - "import pandas as pd\n", - "import numpy as np\n", - "from sklearn.model_selection import train_test_split\n", - "\n", - "from typing import List, Union\n", - "import random\n", - "\n", - "# the below checks for whether we run dowhy, causaltune, and FLAML from source\n", - "root_path = root_path = os.path.realpath('../..')\n", - "try:\n", - " import causaltune\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"causaltune\"))\n", - "\n", - "try:\n", - " import dowhy\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"dowhy\"))\n", - "\n", - "try:\n", - " import flaml\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"FLAML\"))\n", - " \n", - " \n", - " \n", - "from causaltune import CausalTune\n", - "from causaltune.datasets import synth_ihdp\n", - "from causaltune.data_utils import CausalityDataset\n", - "from causaltune.erupt import DummyPropensity, ERUPT\n", - "from causaltune.models.passthrough import passthrough_model" - ] - }, - { - "cell_type": "markdown", - "id": "8c238be1-3759-40ba-90bd-ebe30a9c9e5e", - "metadata": {}, - "source": [ - "### Data and generating treatments\n", - "- We first illustrate the model setup with a subset of data from the Infant Health and Development Program (IHDP).\n", - "- Then we synthetically create multiple treatments" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "36870c05-351b-4550-9af9-1aef6b68664d", - "metadata": {}, - "outputs": [], - "source": [ - "data = synth_ihdp(return_df=True).iloc[:,:10]" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "e2bf1659-9e49-4e5a-b3c2-767b04e4af57", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
treatmenty_factualx1x2x3x4x5x6x7x8
015.599916-0.528603-0.3434551.1285540.161703-0.3166031.29521610
106.875856-1.736945-1.8020020.3838282.244320-0.6291891.29521600
202.996273-0.807451-0.202946-0.360898-0.8796060.808706-0.52655600
301.3662060.3900830.596582-1.850350-0.879606-0.004017-0.85778700
401.963538-1.045229-0.6027100.0114650.1617030.683672-0.36094010
\n", - "
" - ], - "text/plain": [ - " treatment y_factual x1 x2 x3 x4 x5 \\\n", - "0 1 5.599916 -0.528603 -0.343455 1.128554 0.161703 -0.316603 \n", - "1 0 6.875856 -1.736945 -1.802002 0.383828 2.244320 -0.629189 \n", - "2 0 2.996273 -0.807451 -0.202946 -0.360898 -0.879606 0.808706 \n", - "3 0 1.366206 0.390083 0.596582 -1.850350 -0.879606 -0.004017 \n", - "4 0 1.963538 -1.045229 -0.602710 0.011465 0.161703 0.683672 \n", - "\n", - " x6 x7 x8 \n", - "0 1.295216 1 0 \n", - "1 1.295216 0 0 \n", - "2 -0.526556 0 0 \n", - "3 -0.857787 0 0 \n", - "4 -0.360940 1 0 " - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "data.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "9015a4f3-7df9-4b8d-ade5-6fa022dbb6ea", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAACYAAAAPCAYAAACInr1QAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAABJ0AAASdAHeZh94AAABhUlEQVR4nM2Vvy8EQRTHP8cWJFfwB2glIgoaIqfxP1CdhASlKFQSntdpFBINdxdBr3L0Irn2Wko/Sh1BcU4xc3JZ83ZvL1d4zc7u9818vvvm7Wyu2WzyHyNqDVR1GThNyf8WkX5LVNUicOFv10SkHNM7ZkRtD+qAGslzwDxwk2BqBDgC3oC8kdYx49eYiNT9xBC05ocnhp7DVeIVuAS2QnlZGH2G+/YJE8AM8AJUjbQN3NuuAO9pa3bCSDUGrPtrRUQagUXHgH3gUERus5qyGInGVHUQKAINoBzQI1yzPwLb3TiyGJE5w8UiMARUReQpoO8Ck0BBRD66MWYx0rayVeLjuKCq07gqHYhILa5niCDDNKaq48As8Axcx7QIOAcegJ1uHSUxkrYyqenzwKgff6oGj6aSqpZwH8VmVkbQmKoOAEu4hqwEUr6M5wBTuL67A+6B4DanMayKLQDDwFWo6X2jrxrAPW/sLP5LysKweqxV4uBJ36NIZPwx5g/MAoGG7FV0wvgBj4OYCC1tHJMAAAAASUVORK5CYII=", - "text/latex": [ - "$\\displaystyle 747$" - ], - "text/plain": [ - "747" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(data)" - ] - }, - { - "cell_type": "markdown", - "id": "1051b3de-cc27-41df-8fe1-56aac7627dd4", - "metadata": {}, - "source": [ - "- Here we just randomly create multiple treatments" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "69cc5159-d305-44c1-9900-b6f57233e6ba", - "metadata": {}, - "outputs": [], - "source": [ - "np.random.seed(42)\n", - "def generate_treatments(N: int, n_groups: int) -> List[List[Union[int, float]]]:\n", - " treatments = [random.randint(0, n_groups) for _ in range(N)]\n", - " values = [[random.random() for _ in range(N)] for _ in range(n_groups+1)]\n", - " row_sums = [sum(row) for row in values]\n", - " probabilities = [[prob / row_sum for prob in row] for row, row_sum in zip(values, row_sums)]\n", - " for i in range(N):\n", - " sum_probs = sum(row[i] for row in probabilities)\n", - " for row in probabilities:\n", - " row[i] /= sum_probs\n", - "\n", - " return [treatments] + probabilities\n", - "\n", - "N = 747\n", - "n_groups = 4\n", - "\n", - "treatments = generate_treatments(N, n_groups)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "09159be8-9f68-45fc-9e2a-e843ce975f0a", - "metadata": {}, - "outputs": [], - "source": [ - "data['treatment'] = treatments[0]\n", - "data['propensity_control'] = treatments[1]\n", - "data['propensity_treatment1'] = treatments[2]\n", - "data['propensity_treatment2'] = treatments[3]\n", - "data['propensity_treatment3'] = treatments[4]\n", - "data['propensity_treatment4'] = treatments[5]\n", - "\n", - "data['propensity_selected_group'] = data.apply(\n", - " lambda row: row['propensity_control'] if row['treatment'] == 0 else \n", - " (row['propensity_treatment1'] if row['treatment'] == 1 else \n", - " (row['propensity_treatment2'] if row['treatment'] == 2 else \n", - " (row['propensity_treatment3'] if row['treatment'] == 3 else\n", - " (row['propensity_treatment4'] if row['treatment'] == 4 else None)))),\n", - " axis=1\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "379a507a-f85c-435a-8abf-ee1b27adb66d", - "metadata": {}, - "source": [ - "- Now we have `treatment` (0, 1, 2, 3, 4)\n", - "- Outcome `y_factual`\n", - "- Features `x1, x2, x3, x4, x5, x6, x7, x8`\n", - "- Propensities `control, treatment1, treatment2, treatment3, treatment4`\n", - "- selected treatment related propensity `propensity_selected_group`" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "c13377bd-0608-4ef7-b3a5-0a44e36f32f4", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
treatmenty_factualx1x2x3x4x5x6x7x8propensity_controlpropensity_treatment1propensity_treatment2propensity_treatment3propensity_treatment4propensity_selected_group
015.599916-0.528603-0.3434551.1285540.161703-0.3166031.295216100.0923360.4130070.0158410.2585680.2202480.413007
106.875856-1.736945-1.8020020.3838282.244320-0.6291891.295216000.0497680.3295090.1578640.2297020.2331570.049768
212.996273-0.807451-0.202946-0.360898-0.8796060.808706-0.526556000.1616290.1434180.1444130.3052260.2453140.143418
301.3662060.3900830.596582-1.850350-0.879606-0.004017-0.857787000.1888820.1215540.2107540.2173490.2614610.188882
411.963538-1.045229-0.6027100.0114650.1617030.683672-0.360940100.2513650.3219260.2152220.0080520.2034360.321926
\n", - "
" - ], - "text/plain": [ - " treatment y_factual x1 x2 x3 x4 x5 \\\n", - "0 1 5.599916 -0.528603 -0.343455 1.128554 0.161703 -0.316603 \n", - "1 0 6.875856 -1.736945 -1.802002 0.383828 2.244320 -0.629189 \n", - "2 1 2.996273 -0.807451 -0.202946 -0.360898 -0.879606 0.808706 \n", - "3 0 1.366206 0.390083 0.596582 -1.850350 -0.879606 -0.004017 \n", - "4 1 1.963538 -1.045229 -0.602710 0.011465 0.161703 0.683672 \n", - "\n", - " x6 x7 x8 propensity_control propensity_treatment1 \\\n", - "0 1.295216 1 0 0.092336 0.413007 \n", - "1 1.295216 0 0 0.049768 0.329509 \n", - "2 -0.526556 0 0 0.161629 0.143418 \n", - "3 -0.857787 0 0 0.188882 0.121554 \n", - "4 -0.360940 1 0 0.251365 0.321926 \n", - "\n", - " propensity_treatment2 propensity_treatment3 propensity_treatment4 \\\n", - "0 0.015841 0.258568 0.220248 \n", - "1 0.157864 0.229702 0.233157 \n", - "2 0.144413 0.305226 0.245314 \n", - "3 0.210754 0.217349 0.261461 \n", - "4 0.215222 0.008052 0.203436 \n", - "\n", - " propensity_selected_group \n", - "0 0.413007 \n", - "1 0.049768 \n", - "2 0.143418 \n", - "3 0.188882 \n", - "4 0.321926 " - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "data.head()" - ] - }, - { - "cell_type": "markdown", - "id": "98330541-4245-4790-84d3-0deb00aeb1bc", - "metadata": {}, - "source": [ - "Generally, at least four arguments have to be supplied to `CausalityDataset` if you want to train a model:\n", - "- `data`: input dataframe\n", - "- `treatment`: name of treatment column\n", - "- `outcomes`: list of names of outcome columns; provide as list even if there's just one outcome of interest\n", - "- `effect_modifiers`: list of names of feature columns;\n", - "\n", - "In addition, if the propensities to treat are known, then provide the corresponding column name(s) via `propensity_modifiers`." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "7b8011b6-1c23-43de-b76a-52baf74dc656", - "metadata": {}, - "outputs": [], - "source": [ - "features = [\n", - " 'x1',\n", - " 'x2',\n", - " 'x3',\n", - " 'x4',\n", - " 'x5',\n", - " 'x6',\n", - " 'x7',\n", - " 'x8'\n", - "]\n", - "\n", - "propensities = [\n", - " 'propensity_control',\n", - " 'propensity_treatment1',\n", - " 'propensity_treatment2',\n", - " 'propensity_treatment3',\n", - " 'propensity_treatment4'\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "1a894d9f-1b20-4f83-8425-f38c1bebf146", - "metadata": {}, - "outputs": [], - "source": [ - "cd = CausalityDataset(\n", - " data=data,\n", - " treatment='treatment',\n", - " outcomes=['y_factual'],\n", - " effect_modifiers = features,\n", - " propensity_modifiers = propensities\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "8df6ecc4-7758-4f99-be0d-a21b118b56d1", - "metadata": {}, - "source": [ - "- To transform categorical columns and do some manipulations" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "cbd3c8f9-38db-4458-9691-e6d80c448f08", - "metadata": {}, - "outputs": [], - "source": [ - "cd.preprocess_dataset()" - ] - }, - { - "cell_type": "markdown", - "id": "d0288aa2-e1b2-4bf8-877d-b45c52f3bc74", - "metadata": {}, - "source": [ - "### Train CausalTune with simple energy distance (multiple treatments)\n", - "- Here we fit a (selection of) model(s) to the data and score them with the energy distance metric" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "fd3239ff-6d8e-4433-b307-e58ff237d807", - "metadata": {}, - "outputs": [], - "source": [ - "# training configs\n", - "\n", - "# set evaluation metric\n", - "metric = \"energy_distance\"\n", - "\n", - "# it's best to specify either time_budget or components_time_budget, \n", - "# and let the other one be inferred; time in seconds\n", - "components_time_budget = 10\n", - "\n", - "# specify training set size\n", - "train_size = 0.7" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "79762873-547f-4c0a-8637-c7ea11e86ca4", - "metadata": {}, - "outputs": [], - "source": [ - "ct = CausalTune(\n", - " estimator_list=[\n", - " \"DomainAdaptationLearner\",\n", - " \"CausalForestDML\",\n", - " \"ForestDRLearner\",\n", - " ],\n", - " metric=metric,\n", - " verbose=1,\n", - " components_time_budget=components_time_budget,\n", - " train_size=train_size,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "6e54c819-d1c4-488e-89dd-37320362f561", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "[flaml.tune.tune: 04-04 21:11:06] {493} WARNING - Using CFO for search. To use BlendSearch, run: pip install flaml[blendsearch]\n", - "[flaml.tune.tune: 04-04 21:11:06] {636} INFO - trial 1 config: {'estimator': {'estimator_name': 'backdoor.econml.metalearners.DomainAdaptationLearner'}}\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Fitting a Propensity-Weighted scoring estimator to be used in scoring tasks\n", - "Initial configs: [{'estimator': {'estimator_name': 'backdoor.econml.metalearners.DomainAdaptationLearner'}}, {'estimator': {'estimator_name': 'backdoor.econml.dr.ForestDRLearner', 'min_propensity': 1e-06, 'n_estimators': 100, 'min_samples_split': 5, 'min_samples_leaf': 5, 'min_weight_fraction_leaf': 0.0, 'max_features': 'auto', 'min_impurity_decrease': 0.0, 'max_samples': 0.45, 'min_balancedness_tol': 0.45, 'honest': True, 'subforest_size': 4}}, {'estimator': {'estimator_name': 'backdoor.econml.dml.CausalForestDML', 'drate': True, 'n_estimators': 100, 'criterion': 'mse', 'min_samples_split': 10, 'min_samples_leaf': 5, 'min_weight_fraction_leaf': 0.0, 'max_features': 'auto', 'min_impurity_decrease': 0.0, 'max_samples': 0.45, 'min_balancedness_tol': 0.45, 'honest': True, 'fit_intercept': True, 'subforest_size': 4}}]\n", - "---------------------\n", - "Best estimator: backdoor.econml.metalearners.DomainAdaptationLearner\n", - "Best config: {'estimator': {'estimator_name': 'backdoor.econml.metalearners.DomainAdaptationLearner'}}\n", - "Best score: 0.17874868883720296\n" - ] - } - ], - "source": [ - "# run causaltune\n", - "ct.fit(data=cd, outcome=cd.outcomes[0])\n", - "\n", - "print('---------------------')\n", - "# return best estimator\n", - "print(f\"Best estimator: {ct.best_estimator}\")\n", - "# config of best estimator:\n", - "print(f\"Best config: {ct.best_config}\")\n", - "# best score:\n", - "print(f\"Best score: {ct.best_score}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "3c0969e0-60b2-48db-895a-e3045487c5d3", - "metadata": {}, - "outputs": [], - "source": [ - "preds = ct.effect(cd.data)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "9e68cb46-0d2c-49e5-9c4c-622038afd8db", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[-0.16751623, 0.10701928, 0.85091579, 0.77418554],\n", - " [-0.16751623, 0.10701928, 1.60185647, 0.30859345],\n", - " [ 0.7479797 , -2.05958891, -0.75960481, -0.05422062],\n", - " ...,\n", - " [ 0.44195521, 0.52434093, 0.19784707, 0.77418554],\n", - " [-0.35218936, 0.52434093, 0.85091579, 0.77418554],\n", - " [ 1.91686213, 0.10701928, 0.19784707, 0.77418554]])" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "preds" - ] - }, - { - "cell_type": "markdown", - "id": "9b9218e5-33ac-47c0-a3af-f264620e78be", - "metadata": {}, - "source": [ - "- Here we want to get results from the predictions\n", - "- We do naive argmax, but it is also recommended to use Thompson Sampling" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "2f437600-0161-4439-a30c-695dca858e6e", - "metadata": {}, - "outputs": [], - "source": [ - "predicted_treatments = np.argmax(preds, axis=1) + 1" - ] - }, - { - "cell_type": "markdown", - "id": "31cf24b5-013b-43a9-9db9-85f214f0dad7", - "metadata": {}, - "source": [ - "### Train CausalTune with custom multiple propensities\n", - "In some settings such as uplift modelling, the experiment / study is based on heterogeneous treatment propensities known to the researcher / experimenter. An array of treatment propensities can be directly supplied to CausalTune in the data instantiation of the `CausalityDataset`. This can, e.g. be done by \n", - "```\n", - "cd = CausalityDataset(\n", - " ...\n", - " propensity_modifiers=[]\n", - " ...\n", - ")\n", - "```\n", - "and then using the `passthrough_model` as follows" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "01347374-8524-4906-8a80-af02602fbfc1", - "metadata": {}, - "outputs": [], - "source": [ - "propensity_model=passthrough_model(\n", - " cd.propensity_modifiers, include_control=True\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "f0255a70-dd9d-45e6-ae6a-4b5bc6001714", - "metadata": {}, - "outputs": [], - "source": [ - "# set evaluation metric, if we want to use custom propensities, we should use \"psw_energy_distance\" metric\n", - "metric = \"psw_energy_distance\"" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "ef2b635b-c92f-45c2-9038-c69d4ddd5c62", - "metadata": {}, - "outputs": [], - "source": [ - "ct2 = CausalTune(\n", - " estimator_list=[\n", - " \"DomainAdaptationLearner\",\n", - " \"CausalForestDML\",\n", - " \"ForestDRLearner\",\n", - " ],\n", - " metric=metric,\n", - " verbose=1,\n", - " components_time_budget=components_time_budget,\n", - " train_size=train_size,\n", - " propensity_model=propensity_model\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "ed6ad9d8-efcd-4123-935e-ebac56b39143", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING:root:Using energy_distance metric as psw_energy_distance is not in the list of supported metrics for this usecase (['energy_distance'])\n", - "WARNING:flaml.tune.tune:Using CFO for search. To use BlendSearch, run: pip install flaml[blendsearch]\n", - "INFO:flaml.tune.searcher.blendsearch:No low-cost partial config given to the search algorithm. For cost-frugal search, consider providing low-cost values for cost-related hps via 'low_cost_partial_config'. More info can be found at https://microsoft.github.io/FLAML/docs/FAQ#about-low_cost_partial_config-in-tune\n", - "INFO:flaml.tune.tune:trial 1 config: {'estimator': {'estimator_name': 'backdoor.econml.metalearners.DomainAdaptationLearner'}}\n", - "WARNING:dowhy.causal_estimator:Concatenating common_causes and effect_modifiers and providing a single list of variables to metalearner estimator method, DomainAdaptationLearner. EconML metalearners accept a single X argument.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Fitting a Propensity-Weighted scoring estimator to be used in scoring tasks\n", - "Initial configs: [{'estimator': {'estimator_name': 'backdoor.econml.metalearners.DomainAdaptationLearner'}}, {'estimator': {'estimator_name': 'backdoor.econml.dr.ForestDRLearner', 'min_propensity': 1e-06, 'n_estimators': 100, 'min_samples_split': 5, 'min_samples_leaf': 5, 'min_weight_fraction_leaf': 0.0, 'max_features': 'auto', 'min_impurity_decrease': 0.0, 'max_samples': 0.45, 'min_balancedness_tol': 0.45, 'honest': True, 'subforest_size': 4}}, {'estimator': {'estimator_name': 'backdoor.econml.dml.CausalForestDML', 'drate': True, 'n_estimators': 100, 'criterion': 'mse', 'min_samples_split': 10, 'min_samples_leaf': 5, 'min_weight_fraction_leaf': 0.0, 'max_features': 'auto', 'min_impurity_decrease': 0.0, 'max_samples': 0.45, 'min_balancedness_tol': 0.45, 'honest': True, 'fit_intercept': True, 'subforest_size': 4}}]\n", - "---------------------\n", - "Best estimator: backdoor.econml.metalearners.DomainAdaptationLearner\n", - "Best config: {'estimator': {'estimator_name': 'backdoor.econml.metalearners.DomainAdaptationLearner'}}\n", - "Best score: 0.271265592878807\n" - ] - } - ], - "source": [ - "# run causaltune\n", - "ct2.fit(data=cd, outcome=cd.outcomes[0])\n", - "\n", - "print('---------------------')\n", - "# return best estimator\n", - "print(f\"Best estimator: {ct2.best_estimator}\")\n", - "# config of best estimator:\n", - "print(f\"Best config: {ct2.best_config}\")\n", - "# best score:\n", - "print(f\"Best score: {ct2.best_score}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "4116f254-1428-4283-9a44-095ac5de95d5", - "metadata": {}, - "outputs": [], - "source": [ - "preds2 = ct2.effect(cd.data)" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "1768aa4c-43c6-47d6-8cc7-2626469ce3f7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[-0.51886928, -0.58574743, 0.20972794, -0.83253706],\n", - " [-0.51886928, -0.12708488, 0.78949869, -0.83253706],\n", - " [ 1.60285747, 0.31716518, 0.20972794, 0.75203586],\n", - " ...,\n", - " [ 1.91001916, 0.1818637 , -1.19342971, 0.31739539],\n", - " [ 1.91001916, -0.06212608, 0.49456951, 1.64734221],\n", - " [ 1.60285747, 0.31716518, -1.19342971, 0.31739539]])" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "preds2" - ] - }, - { - "cell_type": "markdown", - "id": "196bd451-6663-4d59-84f7-d65eb2547015", - "metadata": {}, - "source": [ - "- Here we want to get results from the predictions\n", - "- We do naive argmax, but it is also recommended to use Thompson Sampling" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "e3265a9e-b58e-477e-a1a9-c4af38b8b422", - "metadata": {}, - "outputs": [], - "source": [ - "predicted_treatments2 = np.argmax(preds2, axis=1) + 1" - ] - }, - { - "cell_type": "markdown", - "id": "f1a6c03f-ce5a-4b7e-91d0-146bd0feba77", - "metadata": {}, - "source": [ - "### Run ERUPT with multiple propensities\n", - "Below we demonstrate how to use Estimated Response Under Proposed Treatment (ERUPT) to estimate the average treatment effect had the treatment been assigned randomly. Recall that the dataset used in this example is constructed in a way that the treatment propensity is a function of a unit's covariates." - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "ff674637-1136-46b6-ae6d-a0cdd3218b56", - "metadata": {}, - "outputs": [], - "source": [ - "np.random.seed(42)\n", - "test = synth_ihdp(return_df=True).iloc[:,:10]\n", - "N = 747\n", - "n_groups = 4\n", - "\n", - "treatments = generate_treatments(N, n_groups)\n", - "\n", - "test['treatment'] = treatments[0]\n", - "test['propensity_control'] = treatments[1]\n", - "test['propensity_treatment1'] = treatments[2]\n", - "test['propensity_treatment2'] = treatments[3]\n", - "test['propensity_treatment3'] = treatments[4]\n", - "test['propensity_treatment4'] = treatments[5]\n", - "\n", - "test['propensity_selected_group'] = data.apply(\n", - " lambda row: row['propensity_control'] if row['treatment'] == 0 else \n", - " (row['propensity_treatment1'] if row['treatment'] == 1 else \n", - " (row['propensity_treatment2'] if row['treatment'] == 2 else \n", - " (row['propensity_treatment3'] if row['treatment'] == 3 else\n", - " (row['propensity_treatment4'] if row['treatment'] == 4 else None)))),\n", - " axis=1\n", - ")\n", - "\n", - "def randomize(value):\n", - " return value + np.random.uniform(-1, 1)\n", - "\n", - "for col in features:\n", - " test[col] = test[col].apply(randomize)\n", - "\n", - "test['y_factual'] = test['y_factual'].apply(randomize)\n", - "test['treatment'] = test['treatment'].sample(len(test))" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "74e51a09-3a76-47c8-a7f4-7665d48873fa", - "metadata": {}, - "outputs": [], - "source": [ - "test = test[test['treatment'] != 0].reset_index(drop=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "345bfe6d-dbdd-4ac9-a8d1-d15860c691ac", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
treatmenty_factualx1x2x3x4x5x6x7x8propensity_controlpropensity_treatment1propensity_treatment2propensity_treatment3propensity_treatment4propensity_selected_group
014.699637-0.779523-0.2563491.335451-0.7689570.1203051.2371361.1069440.1956160.1386870.2812080.1216570.1888730.2695740.413007
136.175675-0.835516-0.9890580.7202542.4099330.0960921.6190430.1405740.3294780.2235280.1878950.1193540.2409130.2283090.049768
223.071435-0.3434630.045530-0.1219170.1112690.167218-0.024201-0.579786-0.1613310.1575340.0905920.2746810.3189410.1582520.143418
311.5177910.587400-0.169622-1.923362-0.1682140.595990-0.3500510.4845430.4021950.2520370.5922560.0128720.1177460.0250900.188882
412.253838-1.7331910.276954-0.2289630.2045940.789086-0.2051580.050398-0.1785370.0446870.4093170.0214720.0962610.4282620.321926
\n", - "
" - ], - "text/plain": [ - " treatment y_factual x1 x2 x3 x4 x5 \\\n", - "0 1 4.699637 -0.779523 -0.256349 1.335451 -0.768957 0.120305 \n", - "1 3 6.175675 -0.835516 -0.989058 0.720254 2.409933 0.096092 \n", - "2 2 3.071435 -0.343463 0.045530 -0.121917 0.111269 0.167218 \n", - "3 1 1.517791 0.587400 -0.169622 -1.923362 -0.168214 0.595990 \n", - "4 1 2.253838 -1.733191 0.276954 -0.228963 0.204594 0.789086 \n", - "\n", - " x6 x7 x8 propensity_control propensity_treatment1 \\\n", - "0 1.237136 1.106944 0.195616 0.138687 0.281208 \n", - "1 1.619043 0.140574 0.329478 0.223528 0.187895 \n", - "2 -0.024201 -0.579786 -0.161331 0.157534 0.090592 \n", - "3 -0.350051 0.484543 0.402195 0.252037 0.592256 \n", - "4 -0.205158 0.050398 -0.178537 0.044687 0.409317 \n", - "\n", - " propensity_treatment2 propensity_treatment3 propensity_treatment4 \\\n", - "0 0.121657 0.188873 0.269574 \n", - "1 0.119354 0.240913 0.228309 \n", - "2 0.274681 0.318941 0.158252 \n", - "3 0.012872 0.117746 0.025090 \n", - "4 0.021472 0.096261 0.428262 \n", - "\n", - " propensity_selected_group \n", - "0 0.413007 \n", - "1 0.049768 \n", - "2 0.143418 \n", - "3 0.188882 \n", - "4 0.321926 " - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "test.head()" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "edeff630-5d92-4f1a-9510-e9272c477294", - "metadata": {}, - "outputs": [], - "source": [ - "cd_test = CausalityDataset(\n", - " data=test,\n", - " treatment='treatment',\n", - " outcomes=['y_factual'],\n", - " effect_modifiers = features,\n", - " propensity_modifiers = propensities\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "151b9267-310b-4f6d-adaf-db2d44f63c6d", - "metadata": {}, - "outputs": [], - "source": [ - "cd_test.preprocess_dataset()" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "46659420-fa53-4c5b-891e-a3fc99bc84cf", - "metadata": {}, - "outputs": [], - "source": [ - "preds_test = ct2.effect(cd_test.data)" - ] - }, - { - "cell_type": "markdown", - "id": "0788bc9e-5b0e-4b86-b128-7c5f0b11770e", - "metadata": {}, - "source": [ - "- Here we want to get results from the predictions\n", - "- We do naive argmax, but it is also recommended to use Thompson Sampling" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "30d23496-c5d6-4702-be34-01d7a85e8d88", - "metadata": {}, - "outputs": [], - "source": [ - "treatments_test = np.argmax(preds_test, axis=1) + 1" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "4832a0d9-18e9-4a2f-9e72-ef207d1d8fb5", - "metadata": {}, - "outputs": [], - "source": [ - "test['predicted_treatment'] = treatments_test\n", - "use_df = test" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "470e4aae-a435-48f1-95bd-35d9d5d71c84", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████████████████████████████████████| 10/10 [00:00<00:00, 476.18it/s]\n" - ] - } - ], - "source": [ - "# computing mean ERUPT over 10 bootstrapped samples\n", - "from tqdm import tqdm\n", - "scores_list = []\n", - "\n", - "for i in tqdm(range(10)):\n", - "\n", - " bootstrap_df = use_df.sample(frac=1, replace=True)\n", - " propensities = bootstrap_df['propensity_selected_group']\n", - " actual_treatment = bootstrap_df['treatment']\n", - " outcome = bootstrap_df['y_factual']\n", - "\n", - " # define the random assignment policy\n", - " random_policy = bootstrap_df['predicted_treatment']\n", - "\n", - " # define a propensity model that will simply return the propensities when calling predict_proba\n", - " propensity_model = DummyPropensity(p=propensities, treatment=actual_treatment)\n", - "\n", - " # obtain ERUPT under random policy\n", - " e = ERUPT(treatment_name='treatment', propensity_model=propensity_model)\n", - " scores_list.append(e.score(df=use_df,outcome=outcome,policy=random_policy))\n", - "\n", - "erupt_mean = np.mean(scores_list)\n", - "erupt_sd = np.std(scores_list)" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "259f373d-691c-4178-921d-3bd1cfd04b07", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/latex": [ - "$\\displaystyle 3.66039178927153$" - ], - "text/plain": [ - "3.660391789271528" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "erupt_mean" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "id": "df132240-5a4b-46a7-a3bc-8ddc87464167", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/latex": [ - "$\\displaystyle 3.14724353956066$" - ], - "text/plain": [ - "3.1472435395606566" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "test['y_factual'].mean()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4fd63daa-8d09-42cf-a20d-971b773a4e73", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.18" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From b35fcc0c975947ee0a5664a5547c894d5c4a0003 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Tue, 10 Sep 2024 15:06:17 +0100 Subject: [PATCH 10/22] Add files via upload Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- notebooks/Multiple treatments examples.ipynb | 1291 ++++++++++++++++++ 1 file changed, 1291 insertions(+) create mode 100644 notebooks/Multiple treatments examples.ipynb diff --git a/notebooks/Multiple treatments examples.ipynb b/notebooks/Multiple treatments examples.ipynb new file mode 100644 index 00000000..69441483 --- /dev/null +++ b/notebooks/Multiple treatments examples.ipynb @@ -0,0 +1,1291 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "afbd11d5-c7d7-4467-9b80-fa73b58bae00", + "metadata": {}, + "source": [ + "# Multiple treatments examples\n", + "- In this notebook, we want to demonstrate common use cases where we have multiple treatments (ab testing is not covered, as you can just use another notebook for it)\n", + "- Simple CausalTune training with multiple treatments\n", + "- Applying custom propensities and train CausalTune (for example, in Uplift models)\n", + "- ERUPT for multiple treatments" + ] + }, + { + "cell_type": "markdown", + "id": "11352cfb-89b2-48be-adb5-e68cd95d2ce8", + "metadata": {}, + "source": [ + "### Setting up the data and causal model: CausalityDataset\n", + "- This notebook demonstrates how to train CausalTune with multiple custom propensities.\n", + "- The easiest example here is uplift modeling. Suppose we trained a model, sent messages, launched an experiment.\n", + "- And now we want to train more complex model using previous round model as propensities." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "fbcf1af0-3ad3-4666-b465-633f950409be", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2\n", + "import os, sys\n", + "import warnings\n", + "warnings.filterwarnings('ignore') # suppress sklearn deprecation warnings for now..\n", + "\n", + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "from typing import List, Union\n", + "import random\n", + "\n", + "# the below checks for whether we run dowhy, causaltune, and FLAML from source\n", + "root_path = root_path = os.path.realpath('../..')\n", + "try:\n", + " import causaltune\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"causaltune\"))\n", + "\n", + "try:\n", + " import dowhy\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"dowhy\"))\n", + "\n", + "try:\n", + " import flaml\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"FLAML\"))\n", + " \n", + " \n", + " \n", + "from causaltune import CausalTune\n", + "from causaltune.datasets import synth_ihdp\n", + "from causaltune.data_utils import CausalityDataset\n", + "from causaltune.erupt import DummyPropensity, ERUPT\n", + "from causaltune.models.passthrough import passthrough_model" + ] + }, + { + "cell_type": "markdown", + "id": "8c238be1-3759-40ba-90bd-ebe30a9c9e5e", + "metadata": {}, + "source": [ + "### Data and generating treatments\n", + "- We first illustrate the model setup with a subset of data from the Infant Health and Development Program (IHDP).\n", + "- Then we synthetically create multiple treatments" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "36870c05-351b-4550-9af9-1aef6b68664d", + "metadata": {}, + "outputs": [], + "source": [ + "data = synth_ihdp(return_df=True).iloc[:,:10]" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "e2bf1659-9e49-4e5a-b3c2-767b04e4af57", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
treatmenty_factualx1x2x3x4x5x6x7x8
015.599916-0.528603-0.3434551.1285540.161703-0.3166031.29521610
106.875856-1.736945-1.8020020.3838282.244320-0.6291891.29521600
202.996273-0.807451-0.202946-0.360898-0.8796060.808706-0.52655600
301.3662060.3900830.596582-1.850350-0.879606-0.004017-0.85778700
401.963538-1.045229-0.6027100.0114650.1617030.683672-0.36094010
\n", + "
" + ], + "text/plain": [ + " treatment y_factual x1 x2 x3 x4 x5 \\\n", + "0 1 5.599916 -0.528603 -0.343455 1.128554 0.161703 -0.316603 \n", + "1 0 6.875856 -1.736945 -1.802002 0.383828 2.244320 -0.629189 \n", + "2 0 2.996273 -0.807451 -0.202946 -0.360898 -0.879606 0.808706 \n", + "3 0 1.366206 0.390083 0.596582 -1.850350 -0.879606 -0.004017 \n", + "4 0 1.963538 -1.045229 -0.602710 0.011465 0.161703 0.683672 \n", + "\n", + " x6 x7 x8 \n", + "0 1.295216 1 0 \n", + "1 1.295216 0 0 \n", + "2 -0.526556 0 0 \n", + "3 -0.857787 0 0 \n", + "4 -0.360940 1 0 " + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "9015a4f3-7df9-4b8d-ade5-6fa022dbb6ea", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAACYAAAAPCAYAAACInr1QAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAABJ0AAASdAHeZh94AAABhUlEQVR4nM2Vvy8EQRTHP8cWJFfwB2glIgoaIqfxP1CdhASlKFQSntdpFBINdxdBr3L0Irn2Wko/Sh1BcU4xc3JZ83ZvL1d4zc7u9818vvvm7Wyu2WzyHyNqDVR1GThNyf8WkX5LVNUicOFv10SkHNM7ZkRtD+qAGslzwDxwk2BqBDgC3oC8kdYx49eYiNT9xBC05ocnhp7DVeIVuAS2QnlZGH2G+/YJE8AM8AJUjbQN3NuuAO9pa3bCSDUGrPtrRUQagUXHgH3gUERus5qyGInGVHUQKAINoBzQI1yzPwLb3TiyGJE5w8UiMARUReQpoO8Ck0BBRD66MWYx0rayVeLjuKCq07gqHYhILa5niCDDNKaq48As8Axcx7QIOAcegJ1uHSUxkrYyqenzwKgff6oGj6aSqpZwH8VmVkbQmKoOAEu4hqwEUr6M5wBTuL67A+6B4DanMayKLQDDwFWo6X2jrxrAPW/sLP5LysKweqxV4uBJ36NIZPwx5g/MAoGG7FV0wvgBj4OYCC1tHJMAAAAASUVORK5CYII=", + "text/latex": [ + "$\\displaystyle 747$" + ], + "text/plain": [ + "747" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(data)" + ] + }, + { + "cell_type": "markdown", + "id": "1051b3de-cc27-41df-8fe1-56aac7627dd4", + "metadata": {}, + "source": [ + "- Here we just randomly create multiple treatments" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "69cc5159-d305-44c1-9900-b6f57233e6ba", + "metadata": {}, + "outputs": [], + "source": [ + "np.random.seed(42)\n", + "def generate_treatments(N: int, n_groups: int) -> List[List[Union[int, float]]]:\n", + " treatments = [random.randint(0, n_groups) for _ in range(N)]\n", + " values = [[random.random() for _ in range(N)] for _ in range(n_groups+1)]\n", + " row_sums = [sum(row) for row in values]\n", + " probabilities = [[prob / row_sum for prob in row] for row, row_sum in zip(values, row_sums)]\n", + " for i in range(N):\n", + " sum_probs = sum(row[i] for row in probabilities)\n", + " for row in probabilities:\n", + " row[i] /= sum_probs\n", + "\n", + " return [treatments] + probabilities\n", + "\n", + "N = 747\n", + "n_groups = 4\n", + "\n", + "treatments = generate_treatments(N, n_groups)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "09159be8-9f68-45fc-9e2a-e843ce975f0a", + "metadata": {}, + "outputs": [], + "source": [ + "data['treatment'] = treatments[0]\n", + "data['propensity_control'] = treatments[1]\n", + "data['propensity_treatment1'] = treatments[2]\n", + "data['propensity_treatment2'] = treatments[3]\n", + "data['propensity_treatment3'] = treatments[4]\n", + "data['propensity_treatment4'] = treatments[5]\n", + "\n", + "data['propensity_selected_group'] = data.apply(\n", + " lambda row: row['propensity_control'] if row['treatment'] == 0 else \n", + " (row['propensity_treatment1'] if row['treatment'] == 1 else \n", + " (row['propensity_treatment2'] if row['treatment'] == 2 else \n", + " (row['propensity_treatment3'] if row['treatment'] == 3 else\n", + " (row['propensity_treatment4'] if row['treatment'] == 4 else None)))),\n", + " axis=1\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "379a507a-f85c-435a-8abf-ee1b27adb66d", + "metadata": {}, + "source": [ + "- Now we have `treatment` (0, 1, 2, 3, 4)\n", + "- Outcome `y_factual`\n", + "- Features `x1, x2, x3, x4, x5, x6, x7, x8`\n", + "- Propensities `control, treatment1, treatment2, treatment3, treatment4`\n", + "- selected treatment related propensity `propensity_selected_group`" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "c13377bd-0608-4ef7-b3a5-0a44e36f32f4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
treatmenty_factualx1x2x3x4x5x6x7x8propensity_controlpropensity_treatment1propensity_treatment2propensity_treatment3propensity_treatment4propensity_selected_group
025.599916-0.528603-0.3434551.1285540.161703-0.3166031.295216100.1079490.3415070.0298070.2579140.2628230.029807
136.875856-1.736945-1.8020020.3838282.244320-0.6291891.295216000.3298600.0038110.2709320.2633060.1320910.263306
212.996273-0.807451-0.202946-0.360898-0.8796060.808706-0.526556000.2952830.0829310.2196730.2000070.2021050.082931
341.3662060.3900830.596582-1.850350-0.879606-0.004017-0.857787000.3431190.1912040.0410450.2271610.1974710.197471
441.963538-1.045229-0.6027100.0114650.1617030.683672-0.360940100.2699940.0572990.4029250.0362410.2335410.233541
\n", + "
" + ], + "text/plain": [ + " treatment y_factual x1 x2 x3 x4 x5 \\\n", + "0 2 5.599916 -0.528603 -0.343455 1.128554 0.161703 -0.316603 \n", + "1 3 6.875856 -1.736945 -1.802002 0.383828 2.244320 -0.629189 \n", + "2 1 2.996273 -0.807451 -0.202946 -0.360898 -0.879606 0.808706 \n", + "3 4 1.366206 0.390083 0.596582 -1.850350 -0.879606 -0.004017 \n", + "4 4 1.963538 -1.045229 -0.602710 0.011465 0.161703 0.683672 \n", + "\n", + " x6 x7 x8 propensity_control propensity_treatment1 \\\n", + "0 1.295216 1 0 0.107949 0.341507 \n", + "1 1.295216 0 0 0.329860 0.003811 \n", + "2 -0.526556 0 0 0.295283 0.082931 \n", + "3 -0.857787 0 0 0.343119 0.191204 \n", + "4 -0.360940 1 0 0.269994 0.057299 \n", + "\n", + " propensity_treatment2 propensity_treatment3 propensity_treatment4 \\\n", + "0 0.029807 0.257914 0.262823 \n", + "1 0.270932 0.263306 0.132091 \n", + "2 0.219673 0.200007 0.202105 \n", + "3 0.041045 0.227161 0.197471 \n", + "4 0.402925 0.036241 0.233541 \n", + "\n", + " propensity_selected_group \n", + "0 0.029807 \n", + "1 0.263306 \n", + "2 0.082931 \n", + "3 0.197471 \n", + "4 0.233541 " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.head()" + ] + }, + { + "cell_type": "markdown", + "id": "98330541-4245-4790-84d3-0deb00aeb1bc", + "metadata": {}, + "source": [ + "Generally, at least four arguments have to be supplied to `CausalityDataset` if you want to train a model:\n", + "- `data`: input dataframe\n", + "- `treatment`: name of treatment column\n", + "- `outcomes`: list of names of outcome columns; provide as list even if there's just one outcome of interest\n", + "- `effect_modifiers`: list of names of feature columns;\n", + "\n", + "In addition, if the propensities to treat are known, then provide the corresponding column name(s) via `propensity_modifiers`." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "7b8011b6-1c23-43de-b76a-52baf74dc656", + "metadata": {}, + "outputs": [], + "source": [ + "features = [\n", + " 'x1',\n", + " 'x2',\n", + " 'x3',\n", + " 'x4',\n", + " 'x5',\n", + " 'x6',\n", + " 'x7',\n", + " 'x8'\n", + "]\n", + "\n", + "propensities = [\n", + " 'propensity_control',\n", + " 'propensity_treatment1',\n", + " 'propensity_treatment2',\n", + " 'propensity_treatment3',\n", + " 'propensity_treatment4'\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "1a894d9f-1b20-4f83-8425-f38c1bebf146", + "metadata": {}, + "outputs": [], + "source": [ + "cd = CausalityDataset(\n", + " data=data,\n", + " treatment='treatment',\n", + " outcomes=['y_factual'],\n", + " effect_modifiers = features,\n", + " propensity_modifiers = propensities\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "8df6ecc4-7758-4f99-be0d-a21b118b56d1", + "metadata": {}, + "source": [ + "- To transform categorical columns and do some manipulations" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "cbd3c8f9-38db-4458-9691-e6d80c448f08", + "metadata": {}, + "outputs": [], + "source": [ + "cd.preprocess_dataset()" + ] + }, + { + "cell_type": "markdown", + "id": "d0288aa2-e1b2-4bf8-877d-b45c52f3bc74", + "metadata": {}, + "source": [ + "### Train CausalTune with simple energy distance (multiple treatments)\n", + "- Here we fit a (selection of) model(s) to the data and score them with the energy distance metric" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "fd3239ff-6d8e-4433-b307-e58ff237d807", + "metadata": {}, + "outputs": [], + "source": [ + "# training configs\n", + "\n", + "# set evaluation metric\n", + "metric = \"energy_distance\"\n", + "\n", + "# it's best to specify either time_budget or components_time_budget, \n", + "# and let the other one be inferred; time in seconds\n", + "components_time_budget = 10\n", + "\n", + "# specify training set size\n", + "train_size = 0.7" + ] + }, + { + "cell_type": "markdown", + "id": "088b75a1-c390-495f-be80-b253bcbc2a38", + "metadata": {}, + "source": [ + "Now if `outcome_model=\"auto\"` in the CausalTune constructor, we search over a simultaneous search space for the EconML estimators and for FLAML wrappers for common regressors. The old behavior is now achieved by `outcome_model=\"nested\"` (Refitting AutoML for each estimator).\n", + "\n", + "You can also preprocess the data in the CausalityDataset using one of the popular category encoders: OneHot, WoE, Label, Target." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "79762873-547f-4c0a-8637-c7ea11e86ca4", + "metadata": {}, + "outputs": [], + "source": [ + "ct = CausalTune(\n", + " estimator_list=[\n", + " \"DomainAdaptationLearner\",\n", + " \"CausalForestDML\",\n", + " \"ForestDRLearner\",\n", + " ],\n", + " metric=metric,\n", + " verbose=1,\n", + " components_time_budget=components_time_budget,\n", + " train_size=train_size,\n", + " outcome_model=\"auto\",\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "6e54c819-d1c4-488e-89dd-37320362f561", + "metadata": {}, + "outputs": [], + "source": [ + "# run causaltune\n", + "ct.fit(data=cd, outcome=cd.outcomes[0])\n", + "\n", + "print('---------------------')\n", + "# return best estimator\n", + "print(f\"Best estimator: {ct.best_estimator}\")\n", + "# config of best estimator:\n", + "print(f\"Best config: {ct.best_config}\")\n", + "# best score:\n", + "print(f\"Best score: {ct.best_score}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "3c0969e0-60b2-48db-895a-e3045487c5d3", + "metadata": {}, + "outputs": [], + "source": [ + "preds = ct.effect(cd.data)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "9e68cb46-0d2c-49e5-9c4c-622038afd8db", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[-0.17528909, -0.10834053, -0.27350324, -0.27354165],\n", + " [ 0.19621234, 0.30247269, -0.1484149 , -0.25184741],\n", + " [ 0.11457749, 0.02436523, -0.04183348, 0.23708047],\n", + " ...,\n", + " [-0.96454594, -0.57960515, 0.08710834, -0.38235969],\n", + " [-0.69400728, -0.03214504, -0.0508105 , 0.27500816],\n", + " [-0.02277706, -0.39042558, 0.05169252, -0.22645511]])" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "preds" + ] + }, + { + "cell_type": "markdown", + "id": "9b9218e5-33ac-47c0-a3af-f264620e78be", + "metadata": {}, + "source": [ + "- Here we want to get results from the predictions\n", + "- We do naive argmax, but it is also recommended to use Thompson Sampling" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "2f437600-0161-4439-a30c-695dca858e6e", + "metadata": {}, + "outputs": [], + "source": [ + "predicted_treatments = np.argmax(preds, axis=1) + 1" + ] + }, + { + "cell_type": "markdown", + "id": "31cf24b5-013b-43a9-9db9-85f214f0dad7", + "metadata": {}, + "source": [ + "### Train CausalTune with custom multiple propensities\n", + "In some settings such as uplift modelling, the experiment / study is based on heterogeneous treatment propensities known to the researcher / experimenter. An array of treatment propensities can be directly supplied to CausalTune in the data instantiation of the `CausalityDataset`. This can, e.g. be done by \n", + "```\n", + "cd = CausalityDataset(\n", + " ...\n", + " propensity_modifiers=[]\n", + " ...\n", + ")\n", + "```\n", + "and then using the `passthrough_model` as follows" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "01347374-8524-4906-8a80-af02602fbfc1", + "metadata": {}, + "outputs": [], + "source": [ + "propensity_model=passthrough_model(\n", + " cd.propensity_modifiers, include_control=True\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "f0255a70-dd9d-45e6-ae6a-4b5bc6001714", + "metadata": {}, + "outputs": [], + "source": [ + "# set evaluation metric, if we want to use custom propensities, we should use \"psw_energy_distance\" metric\n", + "metric = \"psw_energy_distance\"" + ] + }, + { + "cell_type": "markdown", + "id": "c1efc7ac-9530-4dfe-9e7b-0797ff9529a4", + "metadata": {}, + "source": [ + "Now if `outcome_model=\"auto\"` in the CausalTune constructor, we search over a simultaneous search space for the EconML estimators and for FLAML wrappers for common regressors. The old behavior is now achieved by `outcome_model=\"nested\"` (Refitting AutoML for each estimator).\n", + "\n", + "You can also preprocess the data in the CausalityDataset using one of the popular category encoders: OneHot, WoE, Label, Target." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "ef2b635b-c92f-45c2-9038-c69d4ddd5c62", + "metadata": {}, + "outputs": [], + "source": [ + "ct2 = CausalTune(\n", + " estimator_list=[\n", + " \"DomainAdaptationLearner\",\n", + " \"CausalForestDML\",\n", + " \"ForestDRLearner\",\n", + " ],\n", + " metric=metric,\n", + " verbose=1,\n", + " components_time_budget=components_time_budget,\n", + " train_size=train_size,\n", + " propensity_model=propensity_model,\n", + " outcome_model=\"auto\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "ed6ad9d8-efcd-4123-935e-ebac56b39143", + "metadata": {}, + "outputs": [], + "source": [ + "# run causaltune\n", + "ct2.fit(data=cd, outcome=cd.outcomes[0])\n", + "\n", + "print('---------------------')\n", + "# return best estimator\n", + "print(f\"Best estimator: {ct2.best_estimator}\")\n", + "# config of best estimator:\n", + "print(f\"Best config: {ct2.best_config}\")\n", + "# best score:\n", + "print(f\"Best score: {ct2.best_score}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "4116f254-1428-4283-9a44-095ac5de95d5", + "metadata": {}, + "outputs": [], + "source": [ + "preds2 = ct2.effect(cd.data)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "1768aa4c-43c6-47d6-8cc7-2626469ce3f7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[-0.82748584, -0.38301612, -0.28167136, 0.59362769],\n", + " [-0.47553063, -1.32764429, -0.78241589, -0.11771117],\n", + " [-0.56505201, -2.38952635, -1.25667425, -1.26012244],\n", + " ...,\n", + " [ 0.35639461, 0.81618186, -0.33151397, -0.45705827],\n", + " [ 0.23314607, 0.54855842, 0.42367241, 2.13179076],\n", + " [ 0.52856153, 0.5723138 , 0.21125856, 0.57083639]])" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "preds2" + ] + }, + { + "cell_type": "markdown", + "id": "196bd451-6663-4d59-84f7-d65eb2547015", + "metadata": {}, + "source": [ + "- Here we want to get results from the predictions\n", + "- We do naive argmax, but it is also recommended to use Thompson Sampling" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "e3265a9e-b58e-477e-a1a9-c4af38b8b422", + "metadata": {}, + "outputs": [], + "source": [ + "predicted_treatments2 = np.argmax(preds2, axis=1) + 1" + ] + }, + { + "cell_type": "markdown", + "id": "f1a6c03f-ce5a-4b7e-91d0-146bd0feba77", + "metadata": {}, + "source": [ + "### Run ERUPT with multiple propensities\n", + "Below we demonstrate how to use Estimated Response Under Proposed Treatment (ERUPT) to estimate the average treatment effect had the treatment been assigned randomly. Recall that the dataset used in this example is constructed in a way that the treatment propensity is a function of a unit's covariates." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "ff674637-1136-46b6-ae6d-a0cdd3218b56", + "metadata": {}, + "outputs": [], + "source": [ + "np.random.seed(42)\n", + "test = synth_ihdp(return_df=True).iloc[:,:10]\n", + "N = 747\n", + "n_groups = 4\n", + "\n", + "treatments = generate_treatments(N, n_groups)\n", + "\n", + "test['treatment'] = treatments[0]\n", + "test['propensity_control'] = treatments[1]\n", + "test['propensity_treatment1'] = treatments[2]\n", + "test['propensity_treatment2'] = treatments[3]\n", + "test['propensity_treatment3'] = treatments[4]\n", + "test['propensity_treatment4'] = treatments[5]\n", + "\n", + "test['propensity_selected_group'] = data.apply(\n", + " lambda row: row['propensity_control'] if row['treatment'] == 0 else \n", + " (row['propensity_treatment1'] if row['treatment'] == 1 else \n", + " (row['propensity_treatment2'] if row['treatment'] == 2 else \n", + " (row['propensity_treatment3'] if row['treatment'] == 3 else\n", + " (row['propensity_treatment4'] if row['treatment'] == 4 else None)))),\n", + " axis=1\n", + ")\n", + "\n", + "def randomize(value):\n", + " return value + np.random.uniform(-1, 1)\n", + "\n", + "for col in features:\n", + " test[col] = test[col].apply(randomize)\n", + "\n", + "test['y_factual'] = test['y_factual'].apply(randomize)\n", + "test['treatment'] = test['treatment'].sample(len(test))" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "74e51a09-3a76-47c8-a7f4-7665d48873fa", + "metadata": {}, + "outputs": [], + "source": [ + "test = test[test['treatment'] != 0].reset_index(drop=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "345bfe6d-dbdd-4ac9-a8d1-d15860c691ac", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
treatmenty_factualx1x2x3x4x5x6x7x8propensity_controlpropensity_treatment1propensity_treatment2propensity_treatment3propensity_treatment4propensity_selected_group
046.175675-0.835516-0.9890580.7202542.4099330.0960921.6190430.1405740.3294780.1435080.0096680.2491500.3400220.2576520.263306
122.253838-1.7331910.276954-0.2289630.2045940.789086-0.2051580.050398-0.1785370.2198510.3954940.2719650.0403870.0723040.233541
213.796029-0.2201100.052470-0.006594-0.711016-0.1483932.7663980.7096640.0092750.2735720.1694010.0309700.2473430.2787140.151098
331.4174700.9511411.584397-0.9372510.432877-1.439677-0.0904200.5223250.3226850.3729680.0986400.1808420.3075480.0400020.059175
441.6303520.019401-0.3625640.066324-0.6505830.240731-1.5128000.389906-0.9231980.0211480.0210580.3617840.5504610.0455500.073713
\n", + "
" + ], + "text/plain": [ + " treatment y_factual x1 x2 x3 x4 x5 \\\n", + "0 4 6.175675 -0.835516 -0.989058 0.720254 2.409933 0.096092 \n", + "1 2 2.253838 -1.733191 0.276954 -0.228963 0.204594 0.789086 \n", + "2 1 3.796029 -0.220110 0.052470 -0.006594 -0.711016 -0.148393 \n", + "3 3 1.417470 0.951141 1.584397 -0.937251 0.432877 -1.439677 \n", + "4 4 1.630352 0.019401 -0.362564 0.066324 -0.650583 0.240731 \n", + "\n", + " x6 x7 x8 propensity_control propensity_treatment1 \\\n", + "0 1.619043 0.140574 0.329478 0.143508 0.009668 \n", + "1 -0.205158 0.050398 -0.178537 0.219851 0.395494 \n", + "2 2.766398 0.709664 0.009275 0.273572 0.169401 \n", + "3 -0.090420 0.522325 0.322685 0.372968 0.098640 \n", + "4 -1.512800 0.389906 -0.923198 0.021148 0.021058 \n", + "\n", + " propensity_treatment2 propensity_treatment3 propensity_treatment4 \\\n", + "0 0.249150 0.340022 0.257652 \n", + "1 0.271965 0.040387 0.072304 \n", + "2 0.030970 0.247343 0.278714 \n", + "3 0.180842 0.307548 0.040002 \n", + "4 0.361784 0.550461 0.045550 \n", + "\n", + " propensity_selected_group \n", + "0 0.263306 \n", + "1 0.233541 \n", + "2 0.151098 \n", + "3 0.059175 \n", + "4 0.073713 " + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "edeff630-5d92-4f1a-9510-e9272c477294", + "metadata": {}, + "outputs": [], + "source": [ + "cd_test = CausalityDataset(\n", + " data=test,\n", + " treatment='treatment',\n", + " outcomes=['y_factual'],\n", + " effect_modifiers = features,\n", + " propensity_modifiers = propensities\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "151b9267-310b-4f6d-adaf-db2d44f63c6d", + "metadata": {}, + "outputs": [], + "source": [ + "cd_test.preprocess_dataset()" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "46659420-fa53-4c5b-891e-a3fc99bc84cf", + "metadata": {}, + "outputs": [], + "source": [ + "preds_test = ct2.effect(cd_test.data)" + ] + }, + { + "cell_type": "markdown", + "id": "0788bc9e-5b0e-4b86-b128-7c5f0b11770e", + "metadata": {}, + "source": [ + "- Here we want to get results from the predictions\n", + "- We do naive argmax, but it is also recommended to use Thompson Sampling" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "30d23496-c5d6-4702-be34-01d7a85e8d88", + "metadata": {}, + "outputs": [], + "source": [ + "treatments_test = np.argmax(preds_test, axis=1) + 1" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "4832a0d9-18e9-4a2f-9e72-ef207d1d8fb5", + "metadata": {}, + "outputs": [], + "source": [ + "test['predicted_treatment'] = treatments_test\n", + "use_df = test" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "470e4aae-a435-48f1-95bd-35d9d5d71c84", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████████████████████████████████████| 10/10 [00:00<00:00, 528.26it/s]\n" + ] + } + ], + "source": [ + "# computing mean ERUPT over 10 bootstrapped samples\n", + "from tqdm import tqdm\n", + "scores_list = []\n", + "\n", + "for i in tqdm(range(10)):\n", + "\n", + " bootstrap_df = use_df.sample(frac=1, replace=True)\n", + " propensities = bootstrap_df['propensity_selected_group']\n", + " actual_treatment = bootstrap_df['treatment']\n", + " outcome = bootstrap_df['y_factual']\n", + "\n", + " # define the random assignment policy\n", + " random_policy = bootstrap_df['predicted_treatment']\n", + "\n", + " # define a propensity model that will simply return the propensities when calling predict_proba\n", + " propensity_model = DummyPropensity(p=propensities, treatment=actual_treatment)\n", + "\n", + " # obtain ERUPT under random policy\n", + " e = ERUPT(treatment_name='treatment', propensity_model=propensity_model)\n", + " scores_list.append(e.score(df=use_df,outcome=outcome,policy=random_policy))\n", + "\n", + "erupt_mean = np.mean(scores_list)\n", + "erupt_sd = np.std(scores_list)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "259f373d-691c-4178-921d-3bd1cfd04b07", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle 2.87505182773168$" + ], + "text/plain": [ + "2.87505182773168" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "erupt_mean" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "df132240-5a4b-46a7-a3bc-8ddc87464167", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/latex": [ + "$\\displaystyle 3.09562750665942$" + ], + "text/plain": [ + "3.095627506659421" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test['y_factual'].mean()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4fd63daa-8d09-42cf-a20d-971b773a4e73", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From ebbff47208cd5ee33c64511b85a959612295fb19 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Tue, 10 Sep 2024 15:07:48 +0100 Subject: [PATCH 11/22] Delete notebooks/AB testing.ipynb Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- notebooks/AB testing.ipynb | 461 ------------------------------------- 1 file changed, 461 deletions(-) delete mode 100644 notebooks/AB testing.ipynb diff --git a/notebooks/AB testing.ipynb b/notebooks/AB testing.ipynb deleted file mode 100644 index 53080e1b..00000000 --- a/notebooks/AB testing.ipynb +++ /dev/null @@ -1,461 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# AB Testing with CausalTune" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "import sys\n", - "import pandas as pd\n", - "import numpy as np\n", - "import warnings\n", - "\n", - "from sklearn.ensemble import RandomForestRegressor\n", - "from sklearn.metrics import mean_squared_error\n", - "\n", - "import gc\n", - "\n", - "root_path = root_path = os.path.realpath('../..')\n", - "try:\n", - " import causaltune\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"causaltune\"))\n", - "\n", - "from causaltune import CausalTune\n", - "from causaltune.data_utils import CausalityDataset\n", - "from causaltune.datasets import generate_synth_data_with_categories\n", - "\n", - "from flaml import AutoML\n", - "import matplotlib.pyplot as plt\n", - "%pip install seaborn as sns\n", - "import seaborn as sns\n", - "%matplotlib inline\n", - "\n", - "warnings.filterwarnings(\"ignore\")\n", - "\n", - "%pip install plotly\n", - "import plotly.io as pio\n", - "pio.renderers.default = \"png\"" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "*Note*: This notebook uses the the package *wise-pizza* which is not listed as a requirement to run CausalTune. It is merely used to showcase what is possible as an AB testing workflow.\n", - "\n", - "Install via\n", - "`pip install wise-pizza`" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "%pip install wise_pizza" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "import wise_pizza as wp" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## CausalTune for AB Testing \n", - "\n", - "CausalTune can be used for AB Testing in two ways:\n", - "1. Variance Reduction\n", - "2. Segmentation analysis\n", - "\n", - "#### 1. Variance Reduction\n", - "A standard variance reduction technique is to control for natural variation in the experiment's outcome metric. The simplest way to do so is by running a simple regression with a selection of controls. A potentially more powerful and automated approach is to run CausalTune. \n", - "\n", - "#### 2. Segmentation Analysis\n", - "\n", - "We use the heterogeneous treatment effect estimates from CausalTune to feed them into the segmentation analytics tool Wise-Pizza." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Data Generating Process" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We first create synthetic data from a DGP with perfect randomisation of the treatment as we are replicating an AB test environment" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There is substantial variation within the outcome metric per variant which can be seen from the cdf per variant:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "TRUE_EFFECT = 0.1\n", - "cd = generate_synth_data_with_categories(n_samples=8000, n_x=3, true_effect=TRUE_EFFECT)\n", - "cd.preprocess_dataset()\n", - "sns.ecdfplot(data=cd.data, x=cd.outcomes[0], hue=cd.treatment)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 1. ATE estimation: Running CausalTune\n" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "# CausalTune configuration\n", - "num_samples = 5\n", - "components_time_budget = 10\n", - "train_size = 0.7\n", - "\n", - "target = cd.outcomes[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now if outcome_model=\"auto\" in the CausalTune constructor, we search over a simultaneous search space for the EconML estimators and for FLAML wrappers for common regressors. The old behavior is now achieved by outcome_model=\"nested\" (the default for now)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [], - "source": [ - "ct_ab = CausalTune(\n", - " num_samples=num_samples,\n", - " components_time_budget=components_time_budget,\n", - " metric=\"energy_distance\",\n", - " verbose=3,\n", - " components_verbose=3,\n", - " train_size=train_size,\n", - " outcome_model=\"auto\"\n", - ") \n", - "ct_ab.fit(data=cd, outcome=target)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The point estimates compare as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Difference in means estimate (naive ATE): 0.121874\n", - "CausalTune ATE estimate:: 0.086094\n", - "True ATE: 0.1\n" - ] - } - ], - "source": [ - "print(f'Difference in means estimate (naive ATE): {ct_ab.scorer.naive_ate(ct_ab.test_df[cd.treatment], ct_ab.test_df[target])[0]:5f}')\n", - "print(f'CausalTune ATE estimate:: {ct_ab.effect(ct_ab.test_df).mean():5f}')\n", - "print(f'True ATE: {TRUE_EFFECT}')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Explainable variation\n", - "\n", - "As a first performance check of this approach we test how much of the variation in the outcome metric remains unexplained with our outcome model prediction approach. \n", - "\n", - "For this, we use AutoML to predict outcomes as is done under the hood of CausalTune.\n", - "The lower the unexplained variation, the more promising it is to use CausalTune for AB Testing." - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "automl = AutoML()\n", - "automl.fit(ct_ab.train_df[ct_ab.train_df.columns.drop([target])], ct_ab.train_df[target], task='regression', time_budget=30)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Variation unexplained: 0.15%\n" - ] - } - ], - "source": [ - "# Fraction of variation unexplained\n", - "mse = mean_squared_error(automl.predict(ct_ab.test_df[ct_ab.test_df.columns.drop([target])]), ct_ab.test_df[target])\n", - "var_y = ct_ab.test_df[target].var()\n", - "fvu = mse / var_y\n", - "print(f'Variation unexplained: {100*fvu:.2f}%')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Bootstrapping with simple component models for inference\n" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "# bootstrap configuration\n", - "\n", - "n_samples = 30\n", - "n_sample_size = cd.data.shape[0]\n", - "\n", - "components_time_budget = 5\n", - "train_size = .7\n", - "num_samples= 10\n", - "\n", - "ct_ate = []\n", - "scores = []\n", - "naive_ate = []" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [], - "source": [ - "for _ in range(n_samples):\n", - " cd_bt = generate_synth_data_with_categories(n_samples=5000, n_x=3, true_effect=TRUE_EFFECT)\n", - " cd_bt.preprocess_dataset()\n", - " outcome_regressor = RandomForestRegressor()\n", - " \n", - " ct = CausalTune(\n", - " num_samples=num_samples,\n", - " components_time_budget=components_time_budget,\n", - " metric=\"energy_distance\",\n", - " train_size=train_size,\n", - " propensity_model='dummy',\n", - " outcome_model=outcome_regressor\n", - " ) \n", - "\n", - " ct.fit(data=cd, outcome=target)\n", - "\n", - " ct_ate.append(ct.effect(ct.test_df).mean())\n", - " scores.append(ct.best_score)\n", - " naive_ate.append(ct.scorer.naive_ate(cd_bt.data[cd_bt.treatment], cd_bt.data[target])[0])\n", - " del ct, cd_bt, outcome_regressor\n", - " gc.collect()" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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f33gRtaTddtms+mVV15xrFe33XabY936u7/7Oz333HOS2tfFEydO6NChQ/rHf/xHx/3nn39eNptNY8aM6bYXm82mhIQEHT16VJJ04sQJFRcXa/jw4Ro0aJDnFhrGI7CgV1pbW2Wz2a74FFZaWurYqJ0/f14vvPCCtmzZooiICEnS4MGD9ZOf/ESbNm3ShAkTlJCQoOnTp6ulpUWSlJSU5PjUdPDgQWVlZTnGfv3115WUlKQxY8Y4prsa57PPPtPdd98tSSovL9ddd93l1Ker1/nhD3+oZcuWafLkyRo1apRsNpskqaqqStOnT1dycrLuvfde1dXVeeYPCRimJ+u21B4kOtYrX19fPf/889q1a5ck6YEHHtDhw4d15MgR3X///bLZbLrtttsc9ydNmuQYoyOwuFr3bDabHn74YUdgeemll/Tggw86XtvVuulq2+DqdbravsAsBBb0ytGjR/XNN99o6NChjmnFxcU6deqUY6O2Y8cOTZs2zammw/3336+SkhIdPnxYQ4cO1b59+/Ttt9+qvr7e8anp8OHDSkhIkNQeftauXau//OUvstlsWr9+vctxpPaQ0rEhvHzDKqnb17HZbPr+97+vjz76SE8//bTeeecdtbS06KmnntL69etltVr16KOPasOGDR78awLm6Mm63dbWpqqqKt1xxx2OmsDAQDU2Nurbb79VZWWlYmNjFR8fr0ceeUQFBQX68ssvHfcPHjzoGCM2NlZS1+teW1ubqqur9aMf/UiVlZX6/PPP9fnnn2vIkCEaM2ZMt+umq21DV6/javsCsxBY0CtlZWWSpNdee01VVVV6//33lZ2dLUm6ePGipPYNw3d3K0vtG7vXX39d48eP19ixY/WnP/1JQUFBOnbsmEaPHu2ou/zTl7+/v86fP6+f//znKi8v18CBA12O09zcLEkKDg6W5BxeJLl8nYaGBvn4+OiJJ56QJF26dEkDBw5UYWGhysvL9aMf/UiJiYl69dVXNWDAAA/9JQGz9GTdPn78uIYMGeK0HlRXV2vEiBFqbm5WUFCQ47nDhw871r/L73eMERAQ4HLdO378uKKjoxUXF6e//vWveumll/TLX/7S8SHD1brpatvg6nW62r7APAQW9EpZWZkyMjL0+eefKyEhQc8//7xefPFFhYWF6be//a0k6ZZbbpHdbr9i3jfffFOVlZX68MMP9emnn2rQoEGKj4+/4nj2J5984tjzERoa6ghADz/8sAoLC7sd5/I9Kl097up1bDabxo8f75h++PBh3XXXXTp8+LBWrVrlOFZfUVGhX/ziF577YwIG6cm6/d11SpI2btyomTNnXnEItqqqyvEB4fL7l6+Hrta9jpqOvTenTp3S1KlTHdNdrZvdbRu6ep2uti8wD4EFvfLpp58qJSVFu3bt0jfffKPS0lI9+uijqq+v1x/+8AdJ7btkN2/erL/97W+SpIaGBm3atEnl5eWaPHmygoODtXbtWjU1Nel73/uevvzyS8cnm48++kjl5eUaNWqUpPYNXWhoqObMmaO0tDS1tLS4HOfy81eam5t1/vx5DR8+3NG7q9ex2WxOV0F0fIqLiorSBx984Jj+2WefXbO/K+BtPVm3bTab4uPjJbXvMf2v//ovFRYWasmSJU6HWM+dO6eBAwfKz8/P6X7HGJcHlq7WvctrlixZotWrV0uSjhw5ovj4eJfrpqttg6vX6Wr7AvMQWNArn376qWOj5MqkSZOUm5uradOmKSEhQffcc48uXbqkOXPm6Ne//rV+8IMf6Pjx445x7r//fm3btk3Z2dnavXu34uLi5OPjI0n6t3/7N915550aN26cfHx8NGvWLJfjXB5YKioqHMfIO7h6HZvN5pjv22+/1VdffaXBgwdr3rx5+uqrrxQbG6uxY8dq06ZNHv1bAibpybpts9m0ceNGJScnKzk5WXv37tXevXt12223uTwEdPn9jjEuDyxdrXuX12RlZWnMmDGqq6tTaGiogoODXa6brrYNrl6nq+0LzMOPH8JtNTU1GjJkiMrLyx2fsgDc+Fi3YTICCwAAMB6HhAAAgPEILAAAwHgEFgAAYDwCCwAAMB6BBQAAGI/AAgAAjEdgAQAAxiOwAAAA4xFYAACA8QgsAADAeAQWAABgPAILAAAw3v8DwILJt/yOfgAAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, ax = plt.subplots()\n", - "\n", - "ax.boxplot([ct_ate, naive_ate])\n", - "ax.set_xticklabels(['$\\hat{\\mu}_{CausalTune}$', '$\\hat{\\mu}_{DiffInMeans}$'])\n", - "plt.axhline(y = TRUE_EFFECT, color = 'b', linestyle = '--')\n", - "plt.show()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2. Segmentation with Wise Pizza" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The underlying estimators of CausalTune provide heterogeneous treatment effect estimates. Apart from simply predicting treatment effects for customers with certain characteristics, one can also perform an automatic segmentation of customers by treatment impact via [wise-pizza](https://github.com/transferwise/wise-pizza/tree/main) as we demonstrate here.\n", - "\n", - "In the synthetic dataset at hand, there are heterogeneous treatment effects by category, e.g. $.5*$TRUE_EFFECT if $X_1=1$ or $-.5*$TRUE_EFFECT if $X_1=2$\n", - "\n", - "The plot below displays an automated selection of relevant segments by CATE." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "segments = list(set(cd.data.columns) - set([cd.treatment]) - set(cd.outcomes) - set(['random']) - set(['X_continuous']))\n", - "\n", - "df_effects = ct_ab.test_df[segments + [cd.treatment]]\n", - "df_effects['CATE'] = ct_ab.effect(ct_ab.test_df)\n", - "df_eff_by_seg = df_effects.groupby(by=segments, as_index=False).agg({'CATE':'sum', 'variant': len}).rename(columns={'variant': 'size'})" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING:root:min_segments parameter is deprecated, please use max_segments instead.\n", - "WARNING:root:min_segments parameter is deprecated, please use max_segments instead.\n" - ] - }, - { - "data": { - "image/png": "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IECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1AooK1frbOwECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1AooK1frbOwECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1AooK1frbOwECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1AooK1frbOwECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1AooK1frbOwECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1AooK1frbOwECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1AooK1frbOwECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1Av8flvxAw6CXgQQAAAAASUVORK5CYII=" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "max_depth = 3\n", - "min_segments = 3\n", - "\n", - "sf = wp.explain_levels(\n", - " df=df_eff_by_seg,\n", - " dims=segments,\n", - " total_name='CATE',\n", - " size_name='size',\n", - " max_depth=max_depth,\n", - " min_segments=min_segments,\n", - ")\n", - "sf.plot(plot_is_static=False)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.14" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} From 30242e79d3174b6f96eb71e674b4709efedf9a7f Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Tue, 10 Sep 2024 15:07:59 +0100 Subject: [PATCH 12/22] Add files via upload Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- notebooks/AB testing.ipynb | 449 +++++++++++++++++++++++++++++++++++++ 1 file changed, 449 insertions(+) create mode 100644 notebooks/AB testing.ipynb diff --git a/notebooks/AB testing.ipynb b/notebooks/AB testing.ipynb new file mode 100644 index 00000000..c9f422d9 --- /dev/null +++ b/notebooks/AB testing.ipynb @@ -0,0 +1,449 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# AB Testing with CausalTune" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import sys\n", + "import pandas as pd\n", + "import numpy as np\n", + "import warnings\n", + "\n", + "from sklearn.ensemble import RandomForestRegressor\n", + "from sklearn.metrics import mean_squared_error\n", + "\n", + "import gc\n", + "\n", + "root_path = root_path = os.path.realpath('../..')\n", + "try:\n", + " import causaltune\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"causaltune\"))\n", + "\n", + "from causaltune import CausalTune\n", + "from causaltune.data_utils import CausalityDataset\n", + "from causaltune.datasets import generate_synth_data_with_categories\n", + "\n", + "from flaml import AutoML\n", + "import matplotlib.pyplot as plt\n", + "%pip install seaborn as sns\n", + "import seaborn as sns\n", + "%matplotlib inline\n", + "\n", + "warnings.filterwarnings(\"ignore\")\n", + "\n", + "%pip install plotly\n", + "import plotly.io as pio\n", + "pio.renderers.default = \"png\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Note*: This notebook uses the the package *wise-pizza* which is not listed as a requirement to run CausalTune. It is merely used to showcase what is possible as an AB testing workflow.\n", + "\n", + "Install via\n", + "`pip install wise-pizza`" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "%pip install wise_pizza" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import wise_pizza as wp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## CausalTune for AB Testing \n", + "\n", + "CausalTune can be used for AB Testing in two ways:\n", + "1. Variance Reduction\n", + "2. Segmentation analysis\n", + "\n", + "#### 1. Variance Reduction\n", + "A standard variance reduction technique is to control for natural variation in the experiment's outcome metric. The simplest way to do so is by running a simple regression with a selection of controls. A potentially more powerful and automated approach is to run CausalTune. \n", + "\n", + "#### 2. Segmentation Analysis\n", + "\n", + "We use the heterogeneous treatment effect estimates from CausalTune to feed them into the segmentation analytics tool Wise-Pizza." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Data Generating Process" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We first create synthetic data from a DGP with perfect randomisation of the treatment as we are replicating an AB test environment" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There is substantial variation within the outcome metric per variant which can be seen from the cdf per variant:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "TRUE_EFFECT = 0.1\n", + "cd = generate_synth_data_with_categories(n_samples=8000, n_x=3, true_effect=TRUE_EFFECT)\n", + "cd.preprocess_dataset()\n", + "sns.ecdfplot(data=cd.data, x=cd.outcomes[0], hue=cd.treatment)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. ATE estimation: Running CausalTune\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# CausalTune configuration\n", + "num_samples = 5\n", + "components_time_budget = 10\n", + "train_size = 0.7\n", + "\n", + "target = cd.outcomes[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now if `outcome_model=\"auto\"` in the CausalTune constructor, we search over a simultaneous search space for the EconML estimators and for FLAML wrappers for common regressors. The old behavior is now achieved by `outcome_model=\"nested\"` (Refitting AutoML for each estimator).\n", + "\n", + "You can also preprocess the data in the CausalityDataset using one of the popular category encoders: OneHot, WoE, Label, Target." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "ct_ab = CausalTune(\n", + " num_samples=num_samples,\n", + " components_time_budget=components_time_budget,\n", + " metric=\"energy_distance\",\n", + " verbose=3,\n", + " components_verbose=3,\n", + " train_size=train_size,\n", + " outcome_model=\"auto\"\n", + ") \n", + "ct_ab.fit(data=cd, outcome=target)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The point estimates compare as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Difference in means estimate (naive ATE): 0.121874\n", + "CausalTune ATE estimate:: 0.086094\n", + "True ATE: 0.1\n" + ] + } + ], + "source": [ + "print(f'Difference in means estimate (naive ATE): {ct_ab.scorer.naive_ate(ct_ab.test_df[cd.treatment], ct_ab.test_df[target])[0]:5f}')\n", + "print(f'CausalTune ATE estimate:: {ct_ab.effect(ct_ab.test_df).mean():5f}')\n", + "print(f'True ATE: {TRUE_EFFECT}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Explainable variation\n", + "\n", + "As a first performance check of this approach we test how much of the variation in the outcome metric remains unexplained with our outcome model prediction approach. \n", + "\n", + "For this, we use AutoML to predict outcomes as is done under the hood of CausalTune.\n", + "The lower the unexplained variation, the more promising it is to use CausalTune for AB Testing." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "automl = AutoML()\n", + "automl.fit(ct_ab.train_df[ct_ab.train_df.columns.drop([target])], ct_ab.train_df[target], task='regression', time_budget=30)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Variation unexplained: 0.15%\n" + ] + } + ], + "source": [ + "# Fraction of variation unexplained\n", + "mse = mean_squared_error(automl.predict(ct_ab.test_df[ct_ab.test_df.columns.drop([target])]), ct_ab.test_df[target])\n", + "var_y = ct_ab.test_df[target].var()\n", + "fvu = mse / var_y\n", + "print(f'Variation unexplained: {100*fvu:.2f}%')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Bootstrapping with simple component models for inference\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# bootstrap configuration\n", + "\n", + "n_samples = 30\n", + "n_sample_size = cd.data.shape[0]\n", + "\n", + "components_time_budget = 5\n", + "train_size = .7\n", + "num_samples= 10\n", + "\n", + "ct_ate = []\n", + "scores = []\n", + "naive_ate = []" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "for _ in range(n_samples):\n", + " cd_bt = generate_synth_data_with_categories(n_samples=5000, n_x=3, true_effect=TRUE_EFFECT)\n", + " cd_bt.preprocess_dataset()\n", + " outcome_regressor = RandomForestRegressor()\n", + " \n", + " ct = CausalTune(\n", + " num_samples=num_samples,\n", + " components_time_budget=components_time_budget,\n", + " metric=\"energy_distance\",\n", + " train_size=train_size,\n", + " propensity_model='dummy',\n", + " outcome_model=outcome_regressor\n", + " ) \n", + "\n", + " ct.fit(data=cd, outcome=target)\n", + "\n", + " ct_ate.append(ct.effect(ct.test_df).mean())\n", + " scores.append(ct.best_score)\n", + " naive_ate.append(ct.scorer.naive_ate(cd_bt.data[cd_bt.treatment], cd_bt.data[target])[0])\n", + " del ct, cd_bt, outcome_regressor\n", + " gc.collect()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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f33gRtaTddtms+mVV15xrFe33XabY936u7/7Oz333HOS2tfFEydO6NChQ/rHf/xHx/3nn39eNptNY8aM6bYXm82mhIQEHT16VJJ04sQJFRcXa/jw4Ro0aJDnFhrGI7CgV1pbW2Wz2a74FFZaWurYqJ0/f14vvPCCtmzZooiICEnS4MGD9ZOf/ESbNm3ShAkTlJCQoOnTp6ulpUWSlJSU5PjUdPDgQWVlZTnGfv3115WUlKQxY8Y4prsa57PPPtPdd98tSSovL9ddd93l1Ker1/nhD3+oZcuWafLkyRo1apRsNpskqaqqStOnT1dycrLuvfde1dXVeeYPCRimJ+u21B4kOtYrX19fPf/889q1a5ck6YEHHtDhw4d15MgR3X///bLZbLrtttsc9ydNmuQYoyOwuFr3bDabHn74YUdgeemll/Tggw86XtvVuulq2+DqdbravsAsBBb0ytGjR/XNN99o6NChjmnFxcU6deqUY6O2Y8cOTZs2zammw/3336+SkhIdPnxYQ4cO1b59+/Ttt9+qvr7e8anp8OHDSkhIkNQeftauXau//OUvstlsWr9+vctxpPaQ0rEhvHzDKqnb17HZbPr+97+vjz76SE8//bTeeecdtbS06KmnntL69etltVr16KOPasOGDR78awLm6Mm63dbWpqqqKt1xxx2OmsDAQDU2Nurbb79VZWWlYmNjFR8fr0ceeUQFBQX68ssvHfcPHjzoGCM2NlZS1+teW1ubqqur9aMf/UiVlZX6/PPP9fnnn2vIkCEaM2ZMt+umq21DV6/javsCsxBY0CtlZWWSpNdee01VVVV6//33lZ2dLUm6ePGipPYNw3d3K0vtG7vXX39d48eP19ixY/WnP/1JQUFBOnbsmEaPHu2ou/zTl7+/v86fP6+f//znKi8v18CBA12O09zcLEkKDg6W5BxeJLl8nYaGBvn4+OiJJ56QJF26dEkDBw5UYWGhysvL9aMf/UiJiYl69dVXNWDAAA/9JQGz9GTdPn78uIYMGeK0HlRXV2vEiBFqbm5WUFCQ47nDhw871r/L73eMERAQ4HLdO378uKKjoxUXF6e//vWveumll/TLX/7S8SHD1brpatvg6nW62r7APAQW9EpZWZkyMjL0+eefKyEhQc8//7xefPFFhYWF6be//a0k6ZZbbpHdbr9i3jfffFOVlZX68MMP9emnn2rQoEGKj4+/4nj2J5984tjzERoa6ghADz/8sAoLC7sd5/I9Kl097up1bDabxo8f75h++PBh3XXXXTp8+LBWrVrlOFZfUVGhX/ziF577YwIG6cm6/d11SpI2btyomTNnXnEItqqqyvEB4fL7l6+Hrta9jpqOvTenTp3S1KlTHdNdrZvdbRu6ep2uti8wD4EFvfLpp58qJSVFu3bt0jfffKPS0lI9+uijqq+v1x/+8AdJ7btkN2/erL/97W+SpIaGBm3atEnl5eWaPHmygoODtXbtWjU1Nel73/uevvzyS8cnm48++kjl5eUaNWqUpPYNXWhoqObMmaO0tDS1tLS4HOfy81eam5t1/vx5DR8+3NG7q9ex2WxOV0F0fIqLiorSBx984Jj+2WefXbO/K+BtPVm3bTab4uPjJbXvMf2v//ovFRYWasmSJU6HWM+dO6eBAwfKz8/P6X7HGJcHlq7WvctrlixZotWrV0uSjhw5ovj4eJfrpqttg6vX6Wr7AvMQWNArn376qWOj5MqkSZOUm5uradOmKSEhQffcc48uXbqkOXPm6Ne//rV+8IMf6Pjx445x7r//fm3btk3Z2dnavXu34uLi5OPjI0n6t3/7N915550aN26cfHx8NGvWLJfjXB5YKioqHMfIO7h6HZvN5pjv22+/1VdffaXBgwdr3rx5+uqrrxQbG6uxY8dq06ZNHv1bAibpybpts9m0ceNGJScnKzk5WXv37tXevXt12223uTwEdPn9jjEuDyxdrXuX12RlZWnMmDGqq6tTaGiogoODXa6brrYNrl6nq+0LzMOPH8JtNTU1GjJkiMrLyx2fsgDc+Fi3YTICCwAAMB6HhAAAgPEILAAAwHgEFgAAYDwCCwAAMB6BBQAAGI/AAgAAjEdgAQAAxiOwAAAA4xFYAACA8QgsAADAeAQWAABgPAILAAAw3v8DwILJt/yOfgAAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "ax.boxplot([ct_ate, naive_ate])\n", + "ax.set_xticklabels(['$\\hat{\\mu}_{CausalTune}$', '$\\hat{\\mu}_{DiffInMeans}$'])\n", + "plt.axhline(y = TRUE_EFFECT, color = 'b', linestyle = '--')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. Segmentation with Wise Pizza" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The underlying estimators of CausalTune provide heterogeneous treatment effect estimates. Apart from simply predicting treatment effects for customers with certain characteristics, one can also perform an automatic segmentation of customers by treatment impact via [wise-pizza](https://github.com/transferwise/wise-pizza/tree/main) as we demonstrate here.\n", + "\n", + "In the synthetic dataset at hand, there are heterogeneous treatment effects by category, e.g. $.5*$TRUE_EFFECT if $X_1=1$ or $-.5*$TRUE_EFFECT if $X_1=2$\n", + "\n", + "The plot below displays an automated selection of relevant segments by CATE." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "segments = list(set(cd.data.columns) - set([cd.treatment]) - set(cd.outcomes) - set(['random']) - set(['X_continuous']))\n", + "\n", + "df_effects = ct_ab.test_df[segments + [cd.treatment]]\n", + "df_effects['CATE'] = ct_ab.effect(ct_ab.test_df)\n", + "df_eff_by_seg = df_effects.groupby(by=segments, as_index=False).agg({'CATE':'sum', 'variant': len}).rename(columns={'variant': 'size'})" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING:root:min_segments parameter is deprecated, please use max_segments instead.\n", + "WARNING:root:min_segments parameter is deprecated, please use max_segments instead.\n" + ] + }, + { + "data": { + "image/png": "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IECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1AooK1frbOwECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1AooK1frbOwECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1AooK1frbOwECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1AooK1frbOwECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1AooK1frbOwECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1AooK1frbOwECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1AooK1frbOwECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQaJWAokKr4rZYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQrYCiQrX+9k6AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFoloKjQqrgtlgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIVCugqFCtv70TIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIFWCSgqtCpuiyVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAtUKKCpU62/vBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgVQKKCq2K22IJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEC1Av8flvxAw6CXgQQAAAAASUVORK5CYII=" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "max_depth = 3\n", + "min_segments = 3\n", + "\n", + "sf = wp.explain_levels(\n", + " df=df_eff_by_seg,\n", + " dims=segments,\n", + " total_name='CATE',\n", + " size_name='size',\n", + " max_depth=max_depth,\n", + " min_segments=min_segments,\n", + ")\n", + "sf.plot(plot_is_static=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 2a6385bd1eb1d6cd720110cca63cfcd707bafeea Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:04:04 +0100 Subject: [PATCH 13/22] Delete notebooks/CausalityDataset setup.ipynb Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- notebooks/CausalityDataset setup.ipynb | 657 ------------------------- 1 file changed, 657 deletions(-) delete mode 100644 notebooks/CausalityDataset setup.ipynb diff --git a/notebooks/CausalityDataset setup.ipynb b/notebooks/CausalityDataset setup.ipynb deleted file mode 100644 index 4ca160f3..00000000 --- a/notebooks/CausalityDataset setup.ipynb +++ /dev/null @@ -1,657 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "f3a2f126", - "metadata": { - "pycharm": { - "name": "#%% md\n" - } - }, - "source": [ - "# Setting up the data and causal model: CausalityDataset\n", - "\n", - "This notebook demonstrates how to use and configure `CausalityDataset` using an arbitrary `pd.DataFrame`.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "d43137b0", - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The autoreload extension is already loaded. To reload it, use:\n", - " %reload_ext autoreload\n" - ] - } - ], - "source": [ - "%load_ext autoreload\n", - "%autoreload 2\n", - "import os, sys\n", - "import warnings\n", - "warnings.filterwarnings('ignore') # suppress sklearn deprecation warnings for now..\n", - "\n", - "import pandas as pd\n", - "import numpy as np\n", - "from sklearn.model_selection import train_test_split\n", - "\n", - "# the below checks for whether we run dowhy, causaltune, and FLAML from source\n", - "root_path = root_path = os.path.realpath('../..')\n", - "try:\n", - " import causaltune\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"causaltune\"))\n", - "\n", - "try:\n", - " import dowhy\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"dowhy\"))\n", - "\n", - "try:\n", - " import flaml\n", - "except ModuleNotFoundError:\n", - " sys.path.append(os.path.join(root_path, \"FLAML\"))\n", - " \n", - " \n", - " \n", - "from causaltune import CausalTune\n", - "from causaltune.datasets import synth_ihdp, iv_dgp_econml, generate_non_random_dataset\n", - "from causaltune.data_utils import CausalityDataset\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "e072c202", - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# this makes the notebook expand to full width of the browser window\n", - "from IPython.core.display import display, HTML\n", - "display(HTML(\"\"))" - ] - }, - { - "cell_type": "markdown", - "id": "c2a0429f", - "metadata": {}, - "source": [ - "### Random assignment \n", - "We first illustrate the model setup with a subset of data from the Infant Health and Development Program (IHDP)." - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "id": "0efc918c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
treatmenty_factualx1x2x3
015.599916-0.528603-0.3434551.128554
106.875856-1.736945-1.8020020.383828
202.996273-0.807451-0.202946-0.360898
301.3662060.3900830.596582-1.850350
401.963538-1.045229-0.6027100.011465
\n", - "
" - ], - "text/plain": [ - " treatment y_factual x1 x2 x3\n", - "0 1 5.599916 -0.528603 -0.343455 1.128554\n", - "1 0 6.875856 -1.736945 -1.802002 0.383828\n", - "2 0 2.996273 -0.807451 -0.202946 -0.360898\n", - "3 0 1.366206 0.390083 0.596582 -1.850350\n", - "4 0 1.963538 -1.045229 -0.602710 0.011465" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "df = synth_ihdp(return_df=True).iloc[:,:5]\n", - "display(df.head())" - ] - }, - { - "cell_type": "markdown", - "id": "c5bce66b", - "metadata": {}, - "source": [ - "Generally, at least three arguments have to be supplied to `CausalityDataset`:\n", - "- `data`: input dataframe\n", - "- `treatment`: name of treatment column\n", - "- `outcomes`: list of names of outcome columns; provide as list even if there's just one outcome of interest\n", - "\n", - "In addition, if the propensities to treat are known, then provide the corresponding column name(s) via `propensity_modifiers`." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "bb50909e", - "metadata": {}, - "outputs": [], - "source": [ - "cd = CausalityDataset(data=df, treatment='treatment', outcomes=['y_factual'])" - ] - }, - { - "cell_type": "markdown", - "id": "73b6395a", - "metadata": {}, - "source": [ - "The next step is to use `cd.preprocess_dataset()` to deal with missing values, remove outliers etc." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "8803d695", - "metadata": {}, - "outputs": [], - "source": [ - "cd.preprocess_dataset()" - ] - }, - { - "cell_type": "markdown", - "id": "dafa93e0", - "metadata": {}, - "source": [ - "The causal model is built by assuming that all remaining features are `effect_modifiers`" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "6695f65f", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['x1', 'x2', 'x3']\n" - ] - } - ], - "source": [ - "print(cd.effect_modifiers)" - ] - }, - { - "cell_type": "markdown", - "id": "50447729", - "metadata": {}, - "source": [ - "Subsequently, use the preprocessed `CausalityDataset` object for training as follow: `CausalTune.fit(cd, outcome='y_factual')`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eb9ebea5", - "metadata": {}, - "outputs": [], - "source": [ - "ct = CausalTune(components_time_budget=5,) \n", - "ct.fit(data=cd, outcome='y_factual')" - ] - }, - { - "cell_type": "markdown", - "id": "e8cf75fb", - "metadata": {}, - "source": [ - "The causal graph that CausalTune uses is " - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "6b9a1ad6", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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MV3v3r05evQov//+O66urmbHEbF7KoAiImKq3377jaFDh9KvXz98fHzMjiPiEDQFLCIiprlz5w6+vr4ULlyYTp06mR1HxGFoBFBEREzTq1cvwsPD2blzJy4uekkSSSza20RExBSbN28mKCiIQYMG4e3tbXYcEYeiKWAREUl0t2/fxs/Pj7fffpuAgACz44g4HI0AiohIouvRowcnTpzgxx9/1NSviAm014mISKLauHEjI0aMYNiwYbz11ltmxxFxSJoCFhGRRHPr1i38/f0pWbIkbdu2NTuOiMPSCKCIiCSabt268eeff7J06VKcnZ3NjiPisFQARUQkUaxbt45Ro0YxYsQIcufObXYcEYemKWAREUlwN27coH79+pQuXZrWrVubHUfE4WkEUEREElyXLl04e/Ysy5Ytw8lJYw8iZlMBFBGRBLV69WrGjRvH6NGjyZkzp9lxRARNAYuISAK6fv06DRo04L333qNFixZmxxGRBzQCKCIiCaZTp06cP3+eVatWaepXxIaoAIqISIJYsWIFEydOZPz48Xh6epodR0QeobdjIiIS765du0aDBg14//33adKkidlxROQfVABFRCTedejQgcuXLzNt2jRN/YrYIE0Bi4hIvFq2bBlTpkxh0qRJuLu7mx1HRJ5Ab8tERCTeXLlyhQYNGvDBBx/QqFEjs+OIyFOoAIqISLxp3749169fZ9q0aVgsFrPjiMhTaApYRETixdKlSwkJCWHq1Km88cYbZscRkWfQCKCIiLy0y5cv07hxYz766CPq169vdhwR+Q8qgCIi8tLatm3LzZs3mTJliqZ+RZIATQGLiMhLWbRoETNmzCA0NJTXX3/d7Dgi8hw0AigiIi/s0qVLNGnShCpVqlCvXj2z44jIc1IBFBGRF9a6dWvu3LnD5MmTNfUrkoRoClhERF7IwoULmT17NjNnziRbtmxmxxGRONAIoIiIxNmFCxdo2rQp1atXp06dOmbHEZE4UgEUEZE4a9myJVFRUUycOFFTvyJJkKaARUQkTubPn8+3337LnDlzyJIli9lxROQFaARQRESe219//UWzZs347LPPqFWrltlxROQFqQCKiMhzMQyD5s2bAzBhwgRN/YokYZoCFhGR5zJv3jwWLFjAvHnzePXVV82OIyIvQSOAIiLyn86dO0eLFi2oWbMmNWvWNDuOiLwkFUAREXkm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aylXrtwzlwkJCYk9c/bflgJVn/K9+LQU3QxexNZo/xeJCxVAsRnXr1/n8OHDz1zGw8ODjP+8autjvgLmAdHxGe0BZ+BLYHYCrFtEXp72f5HnpQIoduYi4P3gc3y+CDgDGYGDQIb/WFZEzKH9X+R56RhAsTMZgZVAKqxP2vHB+cH6VqInfxFbpv1f5HmpAIod8gE2Yn0xeNkXgYfv/DeSuGcZisiL0f4v8jxUAMVO+WCdrvnywddxfSF4uHytB+vRk79I0qH9X+S/qACKHcuA9YDtpUDJB4+58PQr+Fv4++6IJR/83Cw07SOSFGn/F3kWnQQiDmQ/MAfYCmwDrj3yvbRYb+9UHOuZhLrOl4h90f4v8igVQHFQBnADuAckw3pjd93bU8QxaP8XUQEUERERcTA6BlBERETEwagAioiIiDgYFUARERERB6MCKCIiIuJgVABFREREHIwKoIiIiIiDUQEUERERcTAqgCIiIiIORgVQRERExMGoAIqIiIg4GBVAEREREQejAigiIiLiYFQARURERByMCqCIiIiIg1EBFBEREXEwKoAiIiIiDkYFUERERMTBqACKiIiIOBgVQBEREREHowIoIiIi4mBUAEVEREQcjAqgiIiIiINRARQRERFxMCqAIiIiIg5GBVBERETEwagAioiIiDgYFUARERERB6MCKCIiIuJgVABFREREHIwKoIiIiIiDUQEUERERcTAqgCIiIiIORgVQRERExMH8HxeJVAt71vhGAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%matplotlib inline\n", - "ct.causal_model.view_model()" - ] - }, - { - "cell_type": "markdown", - "id": "f0ec03d0", - "metadata": {}, - "source": [ - "*Note that the variable `random` can be ignored and has no real meaning for the causal model.*" - ] - }, - { - "cell_type": "markdown", - "id": "80318c33", - "metadata": {}, - "source": [ - "#### Adding common causes\n", - "\n", - "If we had reason to assume that for instance `x1` and `x2` are `common causes` instead of `effect modifiers`, this can be made explicit:\n" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "id": "6babd054", - "metadata": {}, - "outputs": [], - "source": [ - "cd = CausalityDataset(data=df, treatment='treatment', outcomes=['y_factual'], common_causes=['x1', 'x2'])" - ] - }, - { - "cell_type": "markdown", - "id": "256f2054", - "metadata": {}, - "source": [ - "The causal graph becomes" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "id": "510157f0", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Fitting a Propensity-Weighted scoring estimator to be used in scoring tasks\n", - "Initial configs: [{'estimator': {'estimator_name': 'backdoor.causaltune.models.NaiveDummy'}}, {'estimator': {'estimator_name': 'backdoor.causaltune.models.Dummy'}}, {'estimator': {'estimator_name': 'backdoor.econml.metalearners.SLearner'}}, {'estimator': {'estimator_name': 'backdoor.econml.metalearners.DomainAdaptationLearner'}}, {'estimator': {'estimator_name': 'backdoor.econml.dr.ForestDRLearner', 'min_propensity': 1e-06, 'n_estimators': 100, 'min_samples_split': 5, 'min_samples_leaf': 5, 'min_weight_fraction_leaf': 0.0, 'max_features': 'auto', 'min_impurity_decrease': 0.0, 'max_samples': 0.45, 'min_balancedness_tol': 0.45, 'honest': True, 'subforest_size': 4}}, {'estimator': {'estimator_name': 'backdoor.econml.dml.CausalForestDML', 'drate': True, 'n_estimators': 100, 'criterion': 'mse', 'min_samples_split': 10, 'min_samples_leaf': 5, 'min_weight_fraction_leaf': 0.0, 'max_features': 'auto', 'min_impurity_decrease': 0.0, 'max_samples': 0.45, 'min_balancedness_tol': 0.45, 'honest': True, 'fit_intercept': True, 'subforest_size': 4}}, {'estimator': {'estimator_name': 'backdoor.causaltune.models.TransformedOutcome'}}]\n" - ] - }, - { - "data": { - "image/png": "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nnv44osv9EOBG1ABFBHxMgcPHnRZ3Vu7di2ZmZkULlyYyMhIhg8f7hznatsO+TefffYZgwcPZtCgQXz88cf4+PhYHUmugwqgiIgHy8zMvGKcu3v3bgCqVKmCYRgMGjQIwzCoU6eO/vGWG/LBBx/wyCOP8PDDD/Puu+/q/x83ogIoIuJBkpOTWbFihXOj5YSEBM6cOYOfnx+NGjWia9euGIZBVFQUZcqUsTquuLG3336bJ554gscff5y33npL12F2MyqAIiJubP/+/S6re+vXryczM5MiRYoQFRXFiBEjMAyDsLAwbcQr2eb111/nmWeeYcSIEbz66qsqf25IBVBExE1kZmayceNGl8K3d+9eAKpWrYphGAwePBjDMKhdu7bGcZIjXnzxRcaOHcvYsWN5/vnnVf7clAqgiEgedfbsWec4Nz4+nsTERM6ePYu/vz+NGzeme/fuznHuLbfcYnVc8XCmaTJ27FheeuklXnzxRcaMGWN1JMkCFUARkTxi7969LF++3GWca7fbKVasGFFRUYwaNQrDMGjSpAnBwcFWxxUvYpomzzzzDP/3f//H66+/ztNPP211JMkiFUAREQtkZGSwYcMGl3Hu/v37AahevTqGYfDQQw9hGAY1a9bUOFcsY5omTzzxBP/97395++23eeyxx6yOJNlABVBEJBecOXOGxMREZ9lbsWIFycnJBAQE0LhxY3r16uUc55YqVcrquCKA46owQ4cO5cMPP+SDDz7goYcesjqSZBMVQBGRbGaaJnv37nVZ3du4cSN2u53ixYtjGAZjxoxxjnODgoKsjixyBbvdzuDBg/niiy/47LPPGDRokNWRJBupAIqIZFFGRgbr1693KXwHDhwAoGbNmhiGwbBhwzAMgxo1auisScnzMjMzue+++/jmm2/48ssvueeee6yOJNlMBVBE5AadPn2ahIQEl3Hu+fPnCQgIICwsjL59+zrHuSVKlLA6rsgNycjI4J577mHq1KlMnDiR3r17Wx1JcoAKoIjIPzBNk927d7us7m3atAnTNClRogSGYfD8889jGAaNGzcmMDDQ6sgiNy09PZ0+ffowc+ZMvvvuO+666y6rI0kOUQEUEblMeno669atcyl8f/75JwC1atXCMAwef/xxDMOgevXqGueKx0hNTaVnz57MnTuX77//ns6dO1sdSXKQCqCIeLVTp065jHNX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cybBwcFWRxIRAq55z5AhsHcv/PADfPEF/PQTvP12zj+vu1ABFI/m7+/P5MmT6dGjB7169eLbb7+1OpK4oR9++IFu3brRoUMHvv/+ewIDA62OJOL19u3bx3ffzeHChSvL2Oefw8SJ8MEHEBICd94JjzwCI0bAypV/Pe777x0fcXGOz1et+uu2aysEuP9bP7QRtHiFzMxM7rvvPr755hvGjx9P//79rY6Up2gj6GubMmUKffv25a677uKbb77B39/f6kgiXiczM5MNGza4XD1k3759ACxfHkxExAVsF3eC2bgRwsMdJ4F8+eVfx0hNBcOA48cdl38rUgTn11zN1duRDYgGFmXL67KStoERr+Dr68v48eMJCAhgwIABpKenMyh73xAiHmjixIn079+fvn37Mn78ePz89C1TJDecPXuWxMREZ9lLTEwkOTkZf39/GjduTI8ePTAMg6ioKG655R3gDSADgNBQOH/+ymMGBjpW+C5340tgvoBn/JCs72biNXx8fPj4448JCAjg/vvvJy0tjYceesjqWJJHjR8/nkGDBjFgwAA+/fTT67weqYjcjL1797qs7m3YsAG73U7x4sWJiopizJgxREVF0aRJk6u8/7YP8GouJc24+HzuTwVQvIqPjw/vvfceAQEBPPzww6SlpfHYY49ZHUvymE8++YQhQ4YwZMgQPvjgA3xu/JpRInINGRkZrF+/3ln2li9ffvGSblCjRg0Mw+CRRx7BMAxq1qyJ7Z/mtADUBQxu9FrAN+7StYBDcvA5co8KoHgdm83GW2+9RUBAAI8//jhpaWk8/fTTVseSPOK9995j2LBhDBs2jP/+97/X8Y+PiPyT06dPu4xzV6xYwblz5wgICKBJkyb07t3bOc69+WtpjwQ6ZGfsq8i8+DyeQQVQvJLNZuPVV18lICCAESNGkJaWxpgxY6yOJRZ76623GD58OMOHD+f//u//VP5EbpBpmuzZs8dlnLtx40ZM06REiRJERUUxduxYDMOgcePGBAUFZdMztwd6A1NxFLXs5gv0BNrlwLGtoQIoXstms/HCCy8QEBDAs88+S1paGuPGjdM/+l7q1VdfZdSoUYwaNYqXXnpJ/x+IXIf09HSXcW58fDwHDx4EoFatWkRFRfHoo49iGAY1atTI4b9X7wGLgeNkbwn0BYpfPL7nUAEUrzdmzBiXlcBXX31V//h7EdM0eeGFF3j++ed5/vnnGTt2rP77i1zDqVOnSEhIYPny5c5x7vnz5wkMDCQsLIx+/fphGAaRkZGUKFEil9MVx7E9y23AObKnBPoC+S8et1g2HC/vUAEUAZ5++mnnewJTU1P5z3/+oxLgBUzTZMyYMbzyyiu88sorjBzpOe/vEckq0zTZtWuXy+re5s2bMU2TkiVLYhgG48aNwzAMGjVqlEc2SA8FfgVakfWVwEsrf4suHtezqACKXPTYY4+5nB383nvv6exPD2aaJk899RRvvfUWb775Jk8++aTVkUQslZ6eztq1a10K36FDhwCoXbs2hmHw5JNPYhgG1apVy8M/JIcCW4GhwGQcRe5GiuClx/cC3sXTVv4uUQEUucxDDz1EQEAADzzwAOnp6Xz88ccqgR7INE0effRR3nvvPd59912GDh1qdSSRXHfy5EkSEhKcZW/lypVcuHCBoKAgwsLCuPfee53j3OLFi1sd9wYVAyYBfXHsEfgrjsqTCVxt92cbjuKXgWOrl5F40gkfV6MCKPI3gwYNcl4xJC0tjS+++EKbAHsQu93OQw89xCeffMLHH3/M4MGDrY4kkuNM02THjh0uq3tbtmwBoFSpUhiGwYsvvugc5wYEXHl9XffU7uLHZhyrgSuAJODMZY8pBIThuMJHHzxln79/owIochX33HMP/v7+9OvXj/T0dL766itdBswDZGZmcv/99/Pll18yfvx4BgwYYHUkkRyRlpbGmjVrXDZbPnz4MAAhISHcdtttjBgxAsMwqFKlSh4e52aXEODli783gWQgDQgACuBYAfQu+hdN5Bp69+6Nv78/vXv3Jj09nUmTJuHv7291LLlJGRkZDBgwgMmTJ/P1119z9913Wx1JJNucOHHCeWZufHw8SUlJpKSkEBwcTNOmTbnvvvuc49yiRYtaHddiNqCg1SEspwIo8g/uuusu/P396d69O927d2fKlCl55Ew3uRHp6en069eP77//nsmTJ9OzZ0+rI4ncNNM0+eOPP1zGuVu3bgWgdOnSGIbBK6+8gmEYNGzYUD+4ylWpAIr8i86dOzNz5ky6detGt27dmD59ejbuXi85LS0tjd69ezNr1iymTZtG165drY4kckNSU1NZvXq1c5QbHx/P0aNHsdlshISEcPvttzNy5EgMw6By5cpeMM6V7KACKHId2rVrx6xZs+jUqROd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XYmOjuaHH34gKCjI6khykWma7N2712Wcu3HjRux2O8WKFSMqKorRo0djGAZNmjQhODjY6sgi8i9UAEUsFBAQwJQpU7j77rvp3r07kydPpkePHlbHynU//fQT3bt3p23btkydOpXAwECrI3m1jIwM1q9f71L4Dhw4AED16tUxDINHHnkEwzCoWbOmxrkibkgFUMRi/v7+TJo0iYCAAHr37k16ejp9+/a1OlauubQK2rlzZyZPnkxAQIDVkbzO6dOnrxjnnjt3joCAAJo0aUKfPn2c41ztwyjiGVQARfIAPz8/vvzyS/z9/enXrx/p6ence++9VsfKcd9++y39+vWjR48efP311/j56VtSTjNNk927d7us7m3atAnTNClevDiGYTB27FgMw6Bx48YaxYt4KH23FckjfH19+fzzz/H392fAgAGkpaXxwAMPWB0rx3z99dcMGDCAu+++m/Hjx+uarTkkPT2ddevWOcve8uXLOXjwIAA1a9bEMAwee+wxDMOgRo0a2Gw2ixOLSG5QARTJQ3x8fPj4448JCAhg8ODBpKWl8cgjj1gdK9t98cUX3H///dx333188skneg9ZNjp16hQJCQnOwrdy5UrOnz9PYGAgTZo04e6773aOc0uUKGF1XBGxiAqgSB5js9l49913CQgIYOjQoaSlpfHEE09YHSvbfPTRRzz00EM8+OCDvP/++yp/WWCaJrt27XIZ527evBnTNClZsiSGYTBu3DiioqJo3LixTq4REScVQJE8yGaz8eabbxIYGMiTTz5JWloazzzzjNWxsuydd97hscce49FHH+Xtt9/WuPEGpaens3btWpfCd+jQIQBq166NYRg8+eSTGIZBtWrV9OcrItekAiiSR9lsNl5++WUCAgIYOXIkaWlpPPvss277j/obb7zB008/zVNPPcXrr7/utq8jN508edLlyhpJSUlcuHCBoKAgwsLCuPfeezEMg8jISIoXL251XBFxIyqAInmYzWbj+eefJyAggNGjR5OWlsaLL77oduXp5ZdfZsyYMYwZM4YXXnjB7fLnBtM02bFjh8vq3pYtWwAoVaoUhmHw4osvYhgGjRo10nY5IpIlKoAibmDUqFEEBATw1FNPkZaW5jYraKZp8vzzz/PCCy/wwgsv8Oyzz1odKc9IS0tjzZo1LmfnHj58GICQkBAMw+Dpp5/GMAyqVq3q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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "cd.preprocess_dataset()\n", - "ct = CausalTune(components_time_budget=5,) \n", - "ct.fit(data=cd, outcome='y_factual')\n", - "ct.causal_model.view_model()" - ] - }, - { - "cell_type": "markdown", - "id": "ca35fcef", - "metadata": {}, - "source": [ - "For how to proceed further with CausalTune, see for instance [here](https://github.com/py-why/causaltune/blob/main/notebooks/Random%20assignment%2C%20binary%20CATE%20example.ipynb)" - ] - }, - { - "cell_type": "markdown", - "id": "c1be7581", - "metadata": {}, - "source": [ - "### Instrumental variable identification\n", - "\n", - "In other problems of causal inference, one may seek to follow an instrumental variable approach ([Example notebook](https://github.com/py-why/causaltune/blob/main/notebooks/Comparing%20IV%20Estimators.ipynb)). " - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "id": "2a35636e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " x1 x2 x3 x4 y treatment Z\n", - "0 -2.167807 -0.081599 0.354765 -0.470893 0.950792 0 1\n", - "1 0.206365 1.144597 -1.338532 -0.237026 18.188874 1 1\n", - "2 -0.497604 1.264037 1.282048 1.036047 6.519928 0 0\n", - "3 1.092089 0.331639 -0.623374 0.321355 9.221536 0 0\n", - "4 -0.126635 -1.717113 0.645309 -1.320294 11.088779 1 1\n" - ] - } - ], - "source": [ - "#load data\n", - "df = iv_dgp_econml(p=4).data\n", - "del df['random']\n", - "print(df.head(5))" - ] - }, - { - "cell_type": "markdown", - "id": "a012cdff", - "metadata": {}, - "source": [ - "Suppose we want to use $Z$ as an instrument." - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "c9be746a", - "metadata": {}, - "outputs": [], - "source": [ - "cd = CausalityDataset(\n", - " data=df, \n", - " treatment='treatment',\n", - " outcomes=['y'],\n", - " instruments=['Z']\n", - " )\n", - "cd.preprocess_dataset()" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "0bfd06a6", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Outcomes: ['y']\n", - "Treatment: treatment\n", - "Instruments: ['Z']\n", - "Effect modifiers: ['x1', 'x2', 'x3', 'x4']\n" - ] - } - ], - "source": [ - "print('Outcomes:', cd.outcomes)\n", - "print('Treatment:', cd.treatment)\n", - "print('Instruments:', cd.instruments)\n", - "print('Effect modifiers:', cd.effect_modifiers)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0e738f3e", - "metadata": {}, - "outputs": [], - "source": [ - "ct = CausalTune(\n", - " components_time_budget=5,\n", - " estimator_list=['iv.econml.iv.dml.DMLIV']\n", - " ) \n", - "ct.fit(data=cd, outcome='y')" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "83f847f9", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "ct.causal_model.view_model()" - ] - }, - { - "cell_type": "markdown", - "id": "ecb28b61", - "metadata": {}, - "source": [ - "### Propensity modifiers\n", - "\n", - "If there are well-known propensity modifiers, it is also possible to make those explicit. This can, e.g., be used to pass them directly into the model instead of fitting a propensity weight model (for more details, see [here](https://github.com/py-why/causaltune/blob/main/notebooks/Propensity%20Model%20Selection.ipynb))." - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "b1407bbb", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " T Y X1 X2 X3 X4 X5 propensity\n", - "0 1 0.651561 1.266634 -1.493090 -0.139367 -1.234455 0.115191 0.314804\n", - "1 1 1.499142 0.977774 0.426410 0.709403 -0.371737 -1.062126 0.656799\n", - "2 0 -1.504549 0.037244 0.522880 -0.896096 0.838664 -0.006262 0.705601\n", - "3 1 -2.231536 -1.008786 0.058282 0.322617 0.213959 0.256430 0.368792\n", - "4 1 1.108775 1.296887 -0.063358 -1.825230 0.541003 0.221827 0.774054\n" - ] - } - ], - "source": [ - "#load data\n", - "df = generate_non_random_dataset().data\n", - "del df['random']\n", - "print(df.head(5))" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "1b906467", - "metadata": {}, - "outputs": [], - "source": [ - "cd = CausalityDataset(\n", - " data=df, \n", - " treatment='T',\n", - " outcomes=['Y'],\n", - " propensity_modifiers=['propensity']\n", - " )\n", - "cd.preprocess_dataset()" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "id": "71394906", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Outcomes: ['Y']\n", - "Treatment: T\n", - "Propensity Modifiers: ['propensity']\n", - "Effect modifiers: ['X1', 'X2', 'X3', 'X4', 'X5']\n" - ] - } - ], - "source": [ - "print('Outcomes:', cd.outcomes)\n", - "print('Treatment:', cd.treatment)\n", - "print('Propensity Modifiers:', cd.propensity_modifiers)\n", - "print('Effect modifiers:', cd.effect_modifiers)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "359fd218", - "metadata": {}, - "outputs": [], - "source": [ - "ct = CausalTune(\n", - " components_time_budget=5,\n", - ") \n", - "ct.fit(data=cd, outcome='Y')" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "id": "08e0ee9c", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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8ccfE90mxlwC4MvOnTunPDw8VNasWZWdnZ0qV66csrOzU5cvX9a6NJOIjo5WX375pQLUd999JwsINBQSEqKmTp2qHB0dFaCqVKmiFi9erJ4/f651aUIIkaokAJrYrFmzlI2NTar0BTMYDGrkyJEKUAMHDkxUmxhzDICxHj9+rGbMmKHs7OwUoMqVK6dmz56d7JXPWnq5zYuXl5fW5aRZf/31l+rdu7fKmDGjSp8+veratavssSyESNPkHkAT69mzJ4ULF2bChAkpPpaNjQ3jx49n7ty5zJkzh1atWhEeHp7i46aUbNmyoZQCYPHixTg5OTFgwAAKFy7MN998w6VLlzSuMGnu3bvHZ599xpYtW/jtt99wc3PTuqQ0JSoqitWrV1O7dm0qVqzIli1bGDlyJNevX2fx4sWyx7IQIm3TOoFaI29vb2VjY6POnTuXamNu3rxZZcmSRX3yySdvbRNjzjOA4eHhKl++fKpnz55xz125ckV9++236r333ovrw7Z582azv4x64cIFVaJECZU3b1519OhRrctJU27dumWSPpRCCGHNZAYwBfTq1YtChQqlyixgrKZNm7J//35u3rxJtWrVOHfuXKqNbSpz5szh/v37jBgxIu45R0dHpk6dSnBwcNwqYmdnZ0qXLs0vv/zC48ePNaw4frFtXtKlS0dAQACVK1fWuiSrp5QiICCALl26ULRoUSZPnoyrqysnT55k7969tGnTBnt7e63LFEIIsyEBMAVkyJCBoUOHsmLFCi5cuJBq41asWJGAgACyZMlicW1inj17xo8//kiXLl3i7beWOXNmevfuzYkTJ9i/fz+VKlViyJAhFCpUCDc3N86ePatB1W9at24dn332GWXKlJE2L6ng+fPnLFq0iE8//ZTq1atz6NAhpkyZwo0bN5gzZw7ly5fXukQhhDBPWk9BWqtnz56pggULqm7duqX62A8fPlSfffaZSp8+vVq+fPkrr5nrJeBffvlF2draqgsXLiT6PTdu3FCjR49W+fLlU4D67LPP1IYNG1R0dHQKVpqw2DYvHTp0kDYvKezq1atq2LBhKnfu3ApQTZo0UZs2bdLs314IISyNBMAU9Ouvvyo7Ozt18eLFVB87IiJCde3aVQFqypQpcW1izDEAxoblrl27vtP7IyIi1LJly1T16tUVoIoWLaqmTJmi7t27Z+JK4/dym5fv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2IBoILyeji8iIroHUESuQiHwm/PPF9cLvBY2wB84BPhdoa2IiFwtjQCKyFXwBzKBFtTdSKDt/PEyUfgTEalfCoAicpXuB3ZihcFrDYHOkb+dNOwsYxER96QAKCLX4H6sy7VPnn9d2yDobB91/jgKfyIiDUEBUESukR+wFsgAHjq/zc6lV/Dw4MIqlA+d328NuuwrItJwNAlEROrYASAF+BzIAX6u9F4rrOXdemHN9FWdPxGR60EBUETqkQFOAb8CXkBLtLaviMj1pwAoIiIi4mZ0D6CIiIiIm1EAFBEREXEzCoAiIiIibkYBUERERMTNKACKiIiIuBkFQBERERE3owAoIiIi4mYUAEVERETcjAKgiIiIiJtRABQRERFxMwqAIiIiIm5GAVBERETEzSgAioiIiLgZBUARERERN6MAKCIiIuJmFABFRERE3IwCoIiIiIibUQAUERERcTMKgCIiIiJuRgFQRERExM0oAIqIiIi4GQVAERERETejACgiIiLiZhQARURERNyMAqCIiIiIm1EAFBEREXEzCoAiIiIibkYBUERERMTNKACKiIiIuBkFQBERERE3owAoIiIi4mYUAEVERETcjAKgiIiIiJv5f/Ni/kTzTPigAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "ct.causal_model.view_model()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cef89ea2", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.19" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From 6c8be18448d6003652e58fd5eea2c214f703f524 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:08:08 +0100 Subject: [PATCH 14/22] Add files via upload Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- notebooks/CausalityDataset setup.ipynb | 1863 ++++++++++++++++++++++++ 1 file changed, 1863 insertions(+) create mode 100644 notebooks/CausalityDataset setup.ipynb diff --git a/notebooks/CausalityDataset setup.ipynb b/notebooks/CausalityDataset setup.ipynb new file mode 100644 index 00000000..e328bf46 --- /dev/null +++ b/notebooks/CausalityDataset setup.ipynb @@ -0,0 +1,1863 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f3a2f126", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "# Setting up the data and causal model: CausalityDataset\n", + "\n", + "This notebook demonstrates how to use and configure `CausalityDataset` using an arbitrary `pd.DataFrame`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "id": "d43137b0", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2\n", + "import os, sys\n", + "import warnings\n", + "warnings.filterwarnings('ignore') # suppress sklearn deprecation warnings for now..\n", + "\n", + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "# the below checks for whether we run dowhy, causaltune, and FLAML from source\n", + "root_path = root_path = os.path.realpath('../..')\n", + "try:\n", + " import causaltune\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"causaltune\"))\n", + "\n", + "try:\n", + " import dowhy\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"dowhy\"))\n", + "\n", + "try:\n", + " import flaml\n", + "except ModuleNotFoundError:\n", + " sys.path.append(os.path.join(root_path, \"FLAML\"))\n", + " \n", + " \n", + " \n", + "from causaltune import CausalTune\n", + "from causaltune.datasets import synth_ihdp, iv_dgp_econml, generate_non_random_dataset\n", + "from causaltune.data_utils import CausalityDataset\n", + "from causaltune.dataset_processor import CausalityDatasetProcessor" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e072c202", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# this makes the notebook expand to full width of the browser window\n", + "from IPython.core.display import display, HTML\n", + "display(HTML(\"\"))" + ] + }, + { + "cell_type": "markdown", + "id": "c2a0429f", + "metadata": {}, + "source": [ + "### Random assignment \n", + "We first illustrate the model setup with a subset of data from the Infant Health and Development Program (IHDP)." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "0efc918c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
treatmenty_factualx1x2x3
015.599916-0.528603-0.3434551.128554
106.875856-1.736945-1.8020020.383828
202.996273-0.807451-0.202946-0.360898
301.3662060.3900830.596582-1.850350
401.963538-1.045229-0.6027100.011465
\n", + "
" + ], + "text/plain": [ + " treatment y_factual x1 x2 x3\n", + "0 1 5.599916 -0.528603 -0.343455 1.128554\n", + "1 0 6.875856 -1.736945 -1.802002 0.383828\n", + "2 0 2.996273 -0.807451 -0.202946 -0.360898\n", + "3 0 1.366206 0.390083 0.596582 -1.850350\n", + "4 0 1.963538 -1.045229 -0.602710 0.011465" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df = synth_ihdp(return_df=True).iloc[:,:5]\n", + "display(df.head())" + ] + }, + { + "cell_type": "markdown", + "id": "c5bce66b", + "metadata": {}, + "source": [ + "Generally, at least three arguments have to be supplied to `CausalityDataset`:\n", + "- `data`: input dataframe\n", + "- `treatment`: name of treatment column\n", + "- `outcomes`: list of names of outcome columns; provide as list even if there's just one outcome of interest\n", + "\n", + "In addition, if the propensities to treat are known, then provide the corresponding column name(s) via `propensity_modifiers`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "bb50909e", + "metadata": {}, + "outputs": [], + "source": [ + "cd = CausalityDataset(data=df, treatment='treatment', outcomes=['y_factual'])" + ] + }, + { + "cell_type": "markdown", + "id": "73b6395a", + "metadata": {}, + "source": [ + "The next step is to use `cd.preprocess_dataset()` to deal with missing values, remove outliers etc." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "8803d695", + "metadata": {}, + "outputs": [], + "source": [ + "cd.preprocess_dataset()" + ] + }, + { + "cell_type": "markdown", + "id": "dafa93e0", + "metadata": {}, + "source": [ + "The causal model is built by assuming that all remaining features are `effect_modifiers`" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "6695f65f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['x1', 'x2', 'x3']\n" + ] + } + ], + "source": [ + "print(cd.effect_modifiers)" + ] + }, + { + "cell_type": "markdown", + "id": "50447729", + "metadata": {}, + "source": [ + "Subsequently, use the preprocessed `CausalityDataset` object for training as follow: `CausalTune.fit(cd, outcome='y_factual')`." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "eb9ebea5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fitting a Propensity-Weighted scoring estimator to be used in scoring tasks\n", + "Propensity Model Fitted Successfully\n" + ] + } + ], + "source": [ + "ct = CausalTune(components_time_budget=5,) \n", + "ct.fit(data=cd, outcome='y_factual')" + ] + }, + { + "cell_type": "markdown", + "id": "e8cf75fb", + "metadata": {}, + "source": [ + "The causal graph that CausalTune uses is " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "6b9a1ad6", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "ct.causal_model.view_model()" + ] + }, + { + "cell_type": "markdown", + "id": "f0ec03d0", + "metadata": {}, + "source": [ + "*Note that the variable `random` can be ignored and has no real meaning for the causal model.*" + ] + }, + { + "cell_type": "markdown", + "id": "80318c33", + "metadata": {}, + "source": [ + "#### Adding common causes\n", + "\n", + "If we had reason to assume that for instance `x1` and `x2` are `common causes` instead of `effect modifiers`, this can be made explicit:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "6babd054", + "metadata": {}, + "outputs": [], + "source": [ + "cd = CausalityDataset(data=df, treatment='treatment', outcomes=['y_factual'], common_causes=['x1', 'x2'])" + ] + }, + { + "cell_type": "markdown", + "id": "256f2054", + "metadata": {}, + "source": [ + "The causal graph becomes" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "510157f0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fitting a Propensity-Weighted scoring estimator to be used in scoring tasks\n", + "Propensity Model Fitted Successfully\n" + ] + } + ], + "source": [ + "cd.preprocess_dataset()\n", + "ct = CausalTune(components_time_budget=5,) \n", + "ct.fit(data=cd, outcome='y_factual')\n", + "ct.causal_model.view_model()" + ] + }, + { + "cell_type": "markdown", + "id": "ca35fcef", + "metadata": {}, + "source": [ + "For how to proceed further with CausalTune, see for instance [here](https://github.com/py-why/causaltune/blob/main/notebooks/Random%20assignment%2C%20binary%20CATE%20example.ipynb)" + ] + }, + { + "cell_type": "markdown", + "id": "c1be7581", + "metadata": {}, + "source": [ + "### Instrumental variable identification\n", + "\n", + "In other problems of causal inference, one may seek to follow an instrumental variable approach ([Example notebook](https://github.com/py-why/causaltune/blob/main/notebooks/Comparing%20IV%20Estimators.ipynb)). " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "2a35636e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " x1 x2 x3 x4 y treatment Z\n", + "0 -0.662658 1.124321 -1.699940 -0.379268 5.236122 0 0\n", + "1 -0.788565 1.336684 -0.539586 -0.785838 12.039615 1 1\n", + "2 -0.344655 -0.204201 -1.267158 0.898114 23.469351 1 1\n", + "3 0.125284 -0.557028 0.403744 0.579168 5.300115 0 0\n", + "4 0.356507 0.330607 0.430286 1.201554 12.855370 0 0\n" + ] + } + ], + "source": [ + "#load data\n", + "df = iv_dgp_econml(p=4).data\n", + "del df['random']\n", + "print(df.head(5))" + ] + }, + { + "cell_type": "markdown", + "id": "a012cdff", + "metadata": {}, + "source": [ + "Suppose we want to use $Z$ as an instrument." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "c9be746a", + "metadata": {}, + "outputs": [], + "source": [ + "cd = CausalityDataset(\n", + " data=df, \n", + " treatment='treatment',\n", + " outcomes=['y'],\n", + " instruments=['Z']\n", + " )\n", + "cd.preprocess_dataset()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "0bfd06a6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Outcomes: ['y']\n", + "Treatment: treatment\n", + "Instruments: ['Z']\n", + "Effect modifiers: ['x1', 'x2', 'x3', 'x4']\n" + ] + } + ], + "source": [ + "print('Outcomes:', cd.outcomes)\n", + "print('Treatment:', cd.treatment)\n", + "print('Instruments:', cd.instruments)\n", + "print('Effect modifiers:', cd.effect_modifiers)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "0e738f3e", + "metadata": {}, + "outputs": [], + "source": [ + "ct = CausalTune(\n", + " components_time_budget=5,\n", + " estimator_list=['iv.econml.iv.dml.DMLIV']\n", + " ) \n", + "ct.fit(data=cd, outcome='y')" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "83f847f9", + "metadata": {}, + "outputs": [], + "source": [ + "ct.causal_model.view_model()" + ] + }, + { + "cell_type": "markdown", + "id": "ecb28b61", + "metadata": {}, + "source": [ + "### Propensity modifiers\n", + "\n", + "If there are well-known propensity modifiers, it is also possible to make those explicit. This can, e.g., be used to pass them directly into the model instead of fitting a propensity weight model (for more details, see [here](https://github.com/py-why/causaltune/blob/main/notebooks/Propensity%20Model%20Selection.ipynb))." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "b1407bbb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " T Y X1 X2 X3 X4 X5 propensity\n", + "0 0 1.650705 0.521524 -1.393497 0.010672 -0.828778 1.019257 0.245100\n", + "1 0 -0.888552 -0.782541 -1.384920 -0.233656 0.150249 -0.495169 0.205945\n", + "2 0 -0.516344 -0.154831 -0.098985 2.335176 -1.888928 -0.594854 0.235870\n", + "3 1 0.601679 0.109516 0.092910 0.525252 -1.172202 -0.177947 0.439021\n", + "4 0 0.569122 -0.365630 -0.343061 -0.420554 -0.995160 1.548502 0.335151\n" + ] + } + ], + "source": [ + "#load data\n", + "df = generate_non_random_dataset().data\n", + "del df['random']\n", + "print(df.head(5))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "1b906467", + "metadata": {}, + "outputs": [], + "source": [ + "cd = CausalityDataset(\n", + " data=df, \n", + " treatment='T',\n", + " outcomes=['Y'],\n", + " propensity_modifiers=['propensity']\n", + " )\n", + "cd.preprocess_dataset()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "71394906", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Outcomes: ['Y']\n", + "Treatment: T\n", + "Propensity Modifiers: ['propensity']\n", + "Effect modifiers: ['X1', 'X2', 'X3', 'X4', 'X5']\n" + ] + } + ], + "source": [ + "print('Outcomes:', cd.outcomes)\n", + "print('Treatment:', cd.treatment)\n", + "print('Propensity Modifiers:', cd.propensity_modifiers)\n", + "print('Effect modifiers:', cd.effect_modifiers)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "359fd218", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fitting a Propensity-Weighted scoring estimator to be used in scoring tasks\n", + "Propensity Model Fitted Successfully\n" + ] + } + ], + "source": [ + "ct = CausalTune(\n", + " components_time_budget=5,\n", + ") \n", + "ct.fit(data=cd, outcome='Y')" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "08e0ee9c", + "metadata": {}, + "outputs": [], + "source": [ + "ct.causal_model.view_model()" + ] + }, + { + "cell_type": "markdown", + "id": "818762bf-a3e7-426b-87e7-3cbcaa5d1ef8", + "metadata": {}, + "source": [ + "### Pre-processing of the test dataset based on the training set\n", + "You can also preprocess the data in the CausalityDataset using one of the popular category encoders: OneHot, WoE, Label, Target." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "fd26bb39-e55f-4f76-b225-838ddb16675b", + "metadata": {}, + "outputs": [], + "source": [ + "unique_values_1 = ['A', 'B', 'C', 'D', 'E']\n", + "unique_values_2 = ['F', 'G', 'H', 'I', 'J', 'K']\n", + "unique_values_3 = ['L', 'M', 'N', 'O', 'P', 'Q', 'R']" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "9354687b-6d4a-448a-813d-c8f21c761b8c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
treatmenty_factualx1x2x3
015.599916-0.528603-0.3434551.128554
106.875856-1.736945-1.8020020.383828
202.996273-0.807451-0.202946-0.360898
301.3662060.3900830.596582-1.850350
401.963538-1.045229-0.6027100.011465
\n", + "
" + ], + "text/plain": [ + " treatment y_factual x1 x2 x3\n", + "0 1 5.599916 -0.528603 -0.343455 1.128554\n", + "1 0 6.875856 -1.736945 -1.802002 0.383828\n", + "2 0 2.996273 -0.807451 -0.202946 -0.360898\n", + "3 0 1.366206 0.390083 0.596582 -1.850350\n", + "4 0 1.963538 -1.045229 -0.602710 0.011465" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df_train = synth_ihdp(return_df=True).iloc[:,:5]\n", + "display(df_train.head())" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "f22414f8-0624-4e04-9a3d-4dfe31e4f8f0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
treatmenty_factualx1x2x3
015.599916-0.528603-0.3434551.128554
106.875856-1.736945-1.8020020.383828
202.996273-0.807451-0.202946-0.360898
301.3662060.3900830.596582-1.850350
401.963538-1.045229-0.6027100.011465
\n", + "
" + ], + "text/plain": [ + " treatment y_factual x1 x2 x3\n", + "0 1 5.599916 -0.528603 -0.343455 1.128554\n", + "1 0 6.875856 -1.736945 -1.802002 0.383828\n", + "2 0 2.996273 -0.807451 -0.202946 -0.360898\n", + "3 0 1.366206 0.390083 0.596582 -1.850350\n", + "4 0 1.963538 -1.045229 -0.602710 0.011465" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df_test = synth_ihdp(return_df=True).iloc[:,:5]\n", + "display(df_test.head())" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "70477eb1-9a14-4927-85ef-fb6888d432c7", + "metadata": {}, + "outputs": [], + "source": [ + "# Adding the category columns with random values\n", + "df_train['category_col1'] = np.random.choice(unique_values_1, len(df_train))\n", + "df_train['category_col2'] = np.random.choice(unique_values_2, len(df_train))\n", + "df_train['category_col3'] = np.random.choice(unique_values_3, len(df_train))\n", + "\n", + "df_test['category_col1'] = np.random.choice(unique_values_1, len(df_test))\n", + "df_test['category_col2'] = np.random.choice(unique_values_2, len(df_test))\n", + "df_test['category_col3'] = np.random.choice(unique_values_3, len(df_test))" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "ba538a59-a875-4766-a41a-f9099f3add16", + "metadata": {}, + "outputs": [], + "source": [ + "cd_train = CausalityDataset(\n", + " data=df_train,\n", + " treatment='treatment',\n", + " outcomes=['y_factual'],\n", + " effect_modifiers=['x1', 'x2', 'x3', 'category_col1', 'category_col2', 'category_col3']\n", + ")\n", + "\n", + "cd_test = CausalityDataset(\n", + " data=df_test,\n", + " treatment='treatment',\n", + " outcomes=['y_factual'],\n", + " effect_modifiers=['x1', 'x2', 'x3', 'category_col1', 'category_col2', 'category_col3']\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "71fb2260-ca6e-4a7c-b220-8de92af82917", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
treatmenty_factualx1x2x3category_col1category_col2category_col3random
015.599916-0.528603-0.3434551.128554EKR1
106.875856-1.736945-1.8020020.383828AFM1
202.996273-0.807451-0.202946-0.360898DHO0
301.3662060.3900830.596582-1.850350DKR0
401.963538-1.045229-0.6027100.011465CKQ0
\n", + "
" + ], + "text/plain": [ + " treatment y_factual x1 x2 x3 category_col1 \\\n", + "0 1 5.599916 -0.528603 -0.343455 1.128554 E \n", + "1 0 6.875856 -1.736945 -1.802002 0.383828 A \n", + "2 0 2.996273 -0.807451 -0.202946 -0.360898 D \n", + "3 0 1.366206 0.390083 0.596582 -1.850350 D \n", + "4 0 1.963538 -1.045229 -0.602710 0.011465 C \n", + "\n", + " category_col2 category_col3 random \n", + "0 K R 1 \n", + "1 F M 1 \n", + "2 H O 0 \n", + "3 K R 0 \n", + "4 K Q 0 " + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cd_train.data.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "78d7813b-cc59-4b49-a92a-fb41bae4bd9d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
treatmenty_factualx1x2x3category_col1category_col2category_col3random
015.599916-0.528603-0.3434551.128554BHM1
106.875856-1.736945-1.8020020.383828CIM0
202.996273-0.807451-0.202946-0.360898BKR0
301.3662060.3900830.596582-1.850350CHP1
401.963538-1.045229-0.6027100.011465AHO1
\n", + "
" + ], + "text/plain": [ + " treatment y_factual x1 x2 x3 category_col1 \\\n", + "0 1 5.599916 -0.528603 -0.343455 1.128554 B \n", + "1 0 6.875856 -1.736945 -1.802002 0.383828 C \n", + "2 0 2.996273 -0.807451 -0.202946 -0.360898 B \n", + "3 0 1.366206 0.390083 0.596582 -1.850350 C \n", + "4 0 1.963538 -1.045229 -0.602710 0.011465 A \n", + "\n", + " category_col2 category_col3 random \n", + "0 H M 1 \n", + "1 I M 0 \n", + "2 K R 0 \n", + "3 H P 1 \n", + "4 H O 1 " + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cd_test.data.head()" + ] + }, + { + "cell_type": "markdown", + "id": "2c4767e4-7aa2-47f5-ad9d-d830e77d78b0", + "metadata": {}, + "source": [ + "You can select one of the categorical encoders: `\"onehot\", \"label\", \"target\", \"woe\"`" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "7c0b8f72-6efb-4812-80f7-164557e9eea6", + "metadata": {}, + "outputs": [], + "source": [ + "dataset_processor = CausalityDatasetProcessor()\n", + "dataset_processor.fit(\n", + " cd=cd_train,\n", + " encoder_type=\"label\"\n", + ")\n", + "cd_train = dataset_processor.transform(cd_train)\n", + "cd_test = dataset_processor.transform(cd_test)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "7b9ee8de-ecfd-475c-9369-4bc9abd81454", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
treatmenty_factualx1x2x3randomcategory_col1category_col2category_col3
015.599916-0.528603-0.3434551.1285541.0111
106.875856-1.736945-1.8020020.3838281.0222
202.996273-0.807451-0.202946-0.3608980.0333
301.3662060.3900830.596582-1.8503500.0311
401.963538-1.045228-0.6027100.0114650.0414
\n", + "
" + ], + "text/plain": [ + " treatment y_factual x1 x2 x3 random category_col1 \\\n", + "0 1 5.599916 -0.528603 -0.343455 1.128554 1.0 1 \n", + "1 0 6.875856 -1.736945 -1.802002 0.383828 1.0 2 \n", + "2 0 2.996273 -0.807451 -0.202946 -0.360898 0.0 3 \n", + "3 0 1.366206 0.390083 0.596582 -1.850350 0.0 3 \n", + "4 0 1.963538 -1.045228 -0.602710 0.011465 0.0 4 \n", + "\n", + " category_col2 category_col3 \n", + "0 1 1 \n", + "1 2 2 \n", + "2 3 3 \n", + "3 1 1 \n", + "4 1 4 " + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cd_train.data.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "82ba4136-d406-4b3d-9b13-4bc765ab925d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
treatmenty_factualx1x2x3randomcategory_col1category_col2category_col3
015.599916-0.528603-0.3434551.1285541.0532
106.875856-1.736945-1.8020020.3838280.0442
202.996273-0.807451-0.202946-0.3608980.0511
301.3662060.3900830.596582-1.8503501.0436
401.963538-1.045228-0.6027100.0114651.0233
\n", + "
" + ], + "text/plain": [ + " treatment y_factual x1 x2 x3 random category_col1 \\\n", + "0 1 5.599916 -0.528603 -0.343455 1.128554 1.0 5 \n", + "1 0 6.875856 -1.736945 -1.802002 0.383828 0.0 4 \n", + "2 0 2.996273 -0.807451 -0.202946 -0.360898 0.0 5 \n", + "3 0 1.366206 0.390083 0.596582 -1.850350 1.0 4 \n", + "4 0 1.963538 -1.045228 -0.602710 0.011465 1.0 2 \n", + "\n", + " category_col2 category_col3 \n", + "0 3 2 \n", + "1 4 2 \n", + "2 1 1 \n", + "3 3 6 \n", + "4 3 3 " + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cd_test.data.head()" + ] + }, + { + "cell_type": "markdown", + "id": "4ef24918-f676-4da8-b77a-ebf1347c7be9", + "metadata": {}, + "source": [ + "### Example of model training on transformed data\n", + "Now if `outcome_model=\"auto\"` in the CausalTune constructor, we search over a simultaneous search space for the EconML estimators and for FLAML wrappers for common regressors. The old behavior is now achieved by `outcome_model=\"nested\"` (Refitting AutoML for each estimator)." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "7016148c-d48e-4d1d-a951-160b29b6a37b", + "metadata": {}, + "outputs": [], + "source": [ + "# training configs\n", + "\n", + "# set evaluation metric\n", + "metric = \"energy_distance\"\n", + "\n", + "# it's best to specify either time_budget or components_time_budget, \n", + "# and let the other one be inferred; time in seconds\n", + "components_time_budget = 10\n", + "\n", + "# specify training set size\n", + "train_size = 0.7" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "3f6b2cfd-a26e-4c96-8504-7380459d1a3d", + "metadata": {}, + "outputs": [], + "source": [ + "ct = CausalTune(\n", + " estimator_list=[\n", + " \"DomainAdaptationLearner\",\n", + " \"CausalForestDML\",\n", + " \"ForestDRLearner\",\n", + " ],\n", + " metric=metric,\n", + " verbose=1,\n", + " components_time_budget=components_time_budget,\n", + " train_size=train_size,\n", + " outcome_model=\"auto\",\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "cbdc9c92-33c8-41c4-ab15-8e15703b5a56", + "metadata": {}, + "outputs": [], + "source": [ + "# run causaltune\n", + "ct.fit(data=cd_train, outcome=cd_train.outcomes[0])\n", + "\n", + "print('---------------------')\n", + "# return best estimator\n", + "print(f\"Best estimator: {ct.best_estimator}\")\n", + "# config of best estimator:\n", + "print(f\"Best config: {ct.best_config}\")\n", + "# best score:\n", + "print(f\"Best score: {ct.best_score}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "56d79fe7-bed7-4ccb-96bd-5b0843b149fb", + "metadata": {}, + "outputs": [], + "source": [ + "predictions = ct.predict(cd_test)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "27bab1dd-abd2-41a4-b30c-62b4722d0872", + "metadata": {}, + "outputs": [], + "source": [ + "predictions" + ] + }, + { + "cell_type": "markdown", + "id": "ef1b4809-cc89-4318-af18-671ba2c70dd5", + "metadata": {}, + "source": [ + "### Using pre-processing in the model object\n", + "- You can also use `preprocess = True` in the `CausalTune` fit method to do preprocessing automatically\n", + "- You should specify `encoder_type`\n", + "- You should also specify `encoder_outcome` (binary target column) for the `\"woe\", \"target\"` encoders, no need for `\"onehot\", \"label\"`" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "7d251250-c64a-43b5-b804-1e3e672acb38", + "metadata": {}, + "outputs": [], + "source": [ + "unique_values_1 = ['A', 'B', 'C', 'D', 'E']\n", + "unique_values_2 = ['F', 'G', 'H', 'I', 'J', 'K']\n", + "unique_values_3 = ['L', 'M', 'N', 'O', 'P', 'Q', 'R']\n", + "\n", + "df_train = synth_ihdp(return_df=True).iloc[:,:5]\n", + "df_test = synth_ihdp(return_df=True).iloc[:,:5]\n", + "\n", + "df_train['category_col1'] = np.random.choice(unique_values_1, len(df_train))\n", + "df_train['category_col2'] = np.random.choice(unique_values_2, len(df_train))\n", + "df_train['category_col3'] = np.random.choice(unique_values_3, len(df_train))\n", + "\n", + "df_test['category_col1'] = np.random.choice(unique_values_1, len(df_test))\n", + "df_test['category_col2'] = np.random.choice(unique_values_2, len(df_test))\n", + "df_test['category_col3'] = np.random.choice(unique_values_3, len(df_test))" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "fef7b317-08aa-45bb-8eb1-f8c8eacae428", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
treatmenty_factualx1x2x3category_col1category_col2category_col3
015.599916-0.528603-0.3434551.128554AJN
106.875856-1.736945-1.8020020.383828BJP
202.996273-0.807451-0.202946-0.360898AJP
301.3662060.3900830.596582-1.850350EFM
401.963538-1.045229-0.6027100.011465DGQ
\n", + "
" + ], + "text/plain": [ + " treatment y_factual x1 x2 x3 category_col1 \\\n", + "0 1 5.599916 -0.528603 -0.343455 1.128554 A \n", + "1 0 6.875856 -1.736945 -1.802002 0.383828 B \n", + "2 0 2.996273 -0.807451 -0.202946 -0.360898 A \n", + "3 0 1.366206 0.390083 0.596582 -1.850350 E \n", + "4 0 1.963538 -1.045229 -0.602710 0.011465 D \n", + "\n", + " category_col2 category_col3 \n", + "0 J N \n", + "1 J P \n", + "2 J P \n", + "3 F M \n", + "4 G Q " + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_train.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "372e47a5-1da8-4273-80d1-ad8392720b4d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
treatmenty_factualx1x2x3category_col1category_col2category_col3
015.599916-0.528603-0.3434551.128554CKN
106.875856-1.736945-1.8020020.383828DIN
202.996273-0.807451-0.202946-0.360898AGP
301.3662060.3900830.596582-1.850350DJM
401.963538-1.045229-0.6027100.011465EHP
\n", + "
" + ], + "text/plain": [ + " treatment y_factual x1 x2 x3 category_col1 \\\n", + "0 1 5.599916 -0.528603 -0.343455 1.128554 C \n", + "1 0 6.875856 -1.736945 -1.802002 0.383828 D \n", + "2 0 2.996273 -0.807451 -0.202946 -0.360898 A \n", + "3 0 1.366206 0.390083 0.596582 -1.850350 D \n", + "4 0 1.963538 -1.045229 -0.602710 0.011465 E \n", + "\n", + " category_col2 category_col3 \n", + "0 K N \n", + "1 I N \n", + "2 G P \n", + "3 J M \n", + "4 H P " + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_test.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "d0f3ae9f-1f5d-44b8-8c50-953a4ce1e7ef", + "metadata": {}, + "outputs": [], + "source": [ + "cd_train = CausalityDataset(\n", + " data=df_train,\n", + " treatment='treatment',\n", + " outcomes=['y_factual'],\n", + " effect_modifiers=['x1', 'x2', 'x3', 'category_col1', 'category_col2', 'category_col3']\n", + ")\n", + "\n", + "cd_test = CausalityDataset(\n", + " data=df_test,\n", + " treatment='treatment',\n", + " outcomes=['y_factual'],\n", + " effect_modifiers=['x1', 'x2', 'x3', 'category_col1', 'category_col2', 'category_col3']\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "6c1da720-1ef6-4bba-8bb5-047c9bff01d4", + "metadata": {}, + "outputs": [], + "source": [ + "ct = CausalTune(\n", + " estimator_list=[\n", + " \"DomainAdaptationLearner\",\n", + " \"CausalForestDML\",\n", + " \"ForestDRLearner\",\n", + " ],\n", + " metric=metric,\n", + " verbose=1,\n", + " components_time_budget=components_time_budget,\n", + " train_size=train_size,\n", + " outcome_model=\"auto\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "82699ee7-aafb-45c9-994f-9a0296dfe30a", + "metadata": {}, + "outputs": [], + "source": [ + "# run causaltune\n", + "ct.fit(data=cd_train, outcome=cd_train.outcomes[0], preprocess=True, encoder_type = \"label\")\n", + "\n", + "print('---------------------')\n", + "# return best estimator\n", + "print(f\"Best estimator: {ct.best_estimator}\")\n", + "# config of best estimator:\n", + "print(f\"Best config: {ct.best_config}\")\n", + "# best score:\n", + "print(f\"Best score: {ct.best_score}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "92cbd4ad-ab7d-45dd-a13c-c7c99dacd63b", + "metadata": {}, + "outputs": [], + "source": [ + "predictions = ct.predict(cd_train, preprocess=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "d16777d6-f468-469d-813f-da1f90455d37", + "metadata": {}, + "outputs": [], + "source": [ + "predictions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ffaa475c-2cd6-46c8-ab23-f64f0f5f1506", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 1210ff8e07bb64c0df6e24ef59e51e7ec3aa5b28 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Thu, 12 Sep 2024 11:38:40 +0100 Subject: [PATCH 15/22] Update dataset_processor.py Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- causaltune/dataset_processor.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/causaltune/dataset_processor.py b/causaltune/dataset_processor.py index 11ef5313..7941abff 100644 --- a/causaltune/dataset_processor.py +++ b/causaltune/dataset_processor.py @@ -8,6 +8,16 @@ class CausalityDatasetProcessor(BaseEstimator, TransformerMixin): + """ + A custom dataset processor for CausalTune experiments, designed to preprocess datasets by encoding categorical features, + normalizing numerical features, and handling missing values for causal inference tasks. + + Attributes: + encoder_type (str): The type of encoder used for categorical feature encoding (e.g., 'onehot', 'label', 'target', 'woe'). + outcome (str): The target variable or outcome used for encoding and modeling. + encoder: The encoder object used during feature transformations. + """ + def __init__(self): self.encoder_type = None self.outcome = None From 3ec70002d633056fda32344ae199d962b594d08c Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Thu, 12 Sep 2024 11:41:27 +0100 Subject: [PATCH 16/22] Update dataset_processor.py Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- causaltune/dataset_processor.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/causaltune/dataset_processor.py b/causaltune/dataset_processor.py index 7941abff..44d7ee71 100644 --- a/causaltune/dataset_processor.py +++ b/causaltune/dataset_processor.py @@ -9,16 +9,19 @@ class CausalityDatasetProcessor(BaseEstimator, TransformerMixin): """ - A custom dataset processor for CausalTune experiments, designed to preprocess datasets by encoding categorical features, - normalizing numerical features, and handling missing values for causal inference tasks. - + A processor for CausalityDataset, designed to preprocess data for causal inference tasks by encoding, normalizing, + and handling missing values. + Attributes: - encoder_type (str): The type of encoder used for categorical feature encoding (e.g., 'onehot', 'label', 'target', 'woe'). - outcome (str): The target variable or outcome used for encoding and modeling. - encoder: The encoder object used during feature transformations. + encoder_type (str): Type of encoder used for categorical feature encoding ('onehot', 'label', 'target', 'woe'). + outcome (str): The target variable used for encoding. + encoder: Encoder object used during feature transformations. """ def __init__(self): + """ + Initializes CausalityDatasetProcessor with default attributes for encoder_type, outcome, and encoder. + """ self.encoder_type = None self.outcome = None self.encoder = None From aa014e54d45da605afc5a38833e404df06678af9 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Thu, 12 Sep 2024 11:44:02 +0100 Subject: [PATCH 17/22] Update dataset_processor.py Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- causaltune/dataset_processor.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/causaltune/dataset_processor.py b/causaltune/dataset_processor.py index 44d7ee71..a880adf2 100644 --- a/causaltune/dataset_processor.py +++ b/causaltune/dataset_processor.py @@ -11,13 +11,11 @@ class CausalityDatasetProcessor(BaseEstimator, TransformerMixin): """ A processor for CausalityDataset, designed to preprocess data for causal inference tasks by encoding, normalizing, and handling missing values. - Attributes: encoder_type (str): Type of encoder used for categorical feature encoding ('onehot', 'label', 'target', 'woe'). outcome (str): The target variable used for encoding. encoder: Encoder object used during feature transformations. """ - def __init__(self): """ Initializes CausalityDatasetProcessor with default attributes for encoder_type, outcome, and encoder. @@ -32,6 +30,15 @@ def fit( encoder_type: Optional[str] = "onehot", outcome: str = None, ): + """ + Fits the processor by preprocessing the input CausalityDataset. + Args: + cd (CausalityDataset): The dataset for causal analysis. + encoder_type (str, optional): Encoder to use for categorical features. Default is 'onehot'. + outcome (str, optional): The target variable for encoding (needed for 'target' or 'woe'). Default is None. + Returns: + CausalityDatasetProcessor: The fitted processor instance. + """ cd = copy.deepcopy(cd) self.preprocess_dataset( cd, encoder_type=encoder_type, outcome=outcome, fit_phase=True From b3dd13208fdc20f2bc664ecfda32db28db5a640b Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Thu, 12 Sep 2024 11:46:16 +0100 Subject: [PATCH 18/22] Update dataset_processor.py Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- causaltune/dataset_processor.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/causaltune/dataset_processor.py b/causaltune/dataset_processor.py index a880adf2..fb8deee4 100644 --- a/causaltune/dataset_processor.py +++ b/causaltune/dataset_processor.py @@ -46,6 +46,15 @@ def fit( return self def transform(self, cd: CausalityDataset): + """ + Transforms the CausalityDataset using the fitted encoder. + Args: + cd (CausalityDataset): Dataset to transform. + Returns: + CausalityDataset: Transformed dataset. + Raises: + ValueError: If processor has not been trained yet. + """ if self.encoder: cd = self.preprocess_dataset( cd, From b8b3a89a5f3a63f8b908ad92f95596e2b9c9e604 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Thu, 12 Sep 2024 11:46:59 +0100 Subject: [PATCH 19/22] Update dataset_processor.py Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- causaltune/dataset_processor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/causaltune/dataset_processor.py b/causaltune/dataset_processor.py index fb8deee4..de06ee31 100644 --- a/causaltune/dataset_processor.py +++ b/causaltune/dataset_processor.py @@ -10,7 +10,7 @@ class CausalityDatasetProcessor(BaseEstimator, TransformerMixin): """ A processor for CausalityDataset, designed to preprocess data for causal inference tasks by encoding, normalizing, - and handling missing values. + and handling missing values Attributes: encoder_type (str): Type of encoder used for categorical feature encoding ('onehot', 'label', 'target', 'woe'). outcome (str): The target variable used for encoding. From 390b0766b26909cfcb2a93ae8cc506c9372d5c04 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Thu, 12 Sep 2024 11:47:05 +0100 Subject: [PATCH 20/22] Update dataset_processor.py Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- causaltune/dataset_processor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/causaltune/dataset_processor.py b/causaltune/dataset_processor.py index de06ee31..fb8deee4 100644 --- a/causaltune/dataset_processor.py +++ b/causaltune/dataset_processor.py @@ -10,7 +10,7 @@ class CausalityDatasetProcessor(BaseEstimator, TransformerMixin): """ A processor for CausalityDataset, designed to preprocess data for causal inference tasks by encoding, normalizing, - and handling missing values + and handling missing values. Attributes: encoder_type (str): Type of encoder used for categorical feature encoding ('onehot', 'label', 'target', 'woe'). outcome (str): The target variable used for encoding. From 582d686d95b5d407876b094681e46303ced9dea3 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Thu, 12 Sep 2024 11:47:11 +0100 Subject: [PATCH 21/22] Update dataset_processor.py Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- causaltune/dataset_processor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/causaltune/dataset_processor.py b/causaltune/dataset_processor.py index fb8deee4..de06ee31 100644 --- a/causaltune/dataset_processor.py +++ b/causaltune/dataset_processor.py @@ -10,7 +10,7 @@ class CausalityDatasetProcessor(BaseEstimator, TransformerMixin): """ A processor for CausalityDataset, designed to preprocess data for causal inference tasks by encoding, normalizing, - and handling missing values. + and handling missing values Attributes: encoder_type (str): Type of encoder used for categorical feature encoding ('onehot', 'label', 'target', 'woe'). outcome (str): The target variable used for encoding. From f533461dfacc9f6418a81a8073c1a2631e4dcff1 Mon Sep 17 00:00:00 2001 From: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> Date: Thu, 12 Sep 2024 11:47:17 +0100 Subject: [PATCH 22/22] Update dataset_processor.py Signed-off-by: AlxdrPolyakov <122611538+AlxdrPolyakov@users.noreply.github.com> --- causaltune/dataset_processor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/causaltune/dataset_processor.py b/causaltune/dataset_processor.py index de06ee31..fb8deee4 100644 --- a/causaltune/dataset_processor.py +++ b/causaltune/dataset_processor.py @@ -10,7 +10,7 @@ class CausalityDatasetProcessor(BaseEstimator, TransformerMixin): """ A processor for CausalityDataset, designed to preprocess data for causal inference tasks by encoding, normalizing, - and handling missing values + and handling missing values. Attributes: encoder_type (str): Type of encoder used for categorical feature encoding ('onehot', 'label', 'target', 'woe'). outcome (str): The target variable used for encoding.