Skip to content

Instantly share code, notes, and snippets.

@JonasSchroeder
Created September 7, 2023 06:51
Show Gist options
  • Save JonasSchroeder/b5b12473ea08124e5010042d01b8fb68 to your computer and use it in GitHub Desktop.
Save JonasSchroeder/b5b12473ea08124e5010042d01b8fb68 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"from dowhy import CausalModel\n",
"from lightgbm import LGBMRegressor"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Package Version\n",
"----------------------------- -------\n",
"appnope 0.1.3\n",
"asttokens 2.2.1\n",
"backcall 0.2.0\n",
"backports.functools-lru-cache 1.6.5\n",
"Bottleneck 1.3.5\n",
"causal-learn 0.1.3.3\n",
"cloudpickle 2.2.1\n",
"comm 0.1.4\n",
"contourpy 1.0.5\n",
"cycler 0.11.0\n",
"debugpy 1.6.7\n",
"decorator 5.1.1\n",
"dowhy 0.8\n",
"econml 0.14.1\n",
"executing 1.2.0\n",
"fonttools 4.25.0\n",
"gcastle 1.0.3\n",
"graphviz 0.20.1\n",
"imageio 2.31.2\n",
"importlib-metadata 6.8.0\n",
"ipykernel 6.25.1\n",
"ipympl 0.9.3\n",
"ipython 8.14.0\n",
"ipython-genutils 0.2.0\n",
"ipywidgets 8.1.0\n",
"jedi 0.19.0\n",
"joblib 1.3.2\n",
"jupyter_client 8.3.0\n",
"jupyter_core 5.3.1\n",
"jupyterlab-widgets 3.0.8\n",
"kiwisolver 1.4.4\n",
"lightgbm 4.0.0\n",
"llvmlite 0.40.1\n",
"matplotlib 3.7.1\n",
"matplotlib-inline 0.1.6\n",
"mkl-fft 1.3.6\n",
"mkl-random 1.2.2\n",
"mkl-service 2.4.0\n",
"mpmath 1.3.0\n",
"munkres 1.1.4\n",
"nest-asyncio 1.5.6\n",
"networkx 2.8.7\n",
"numba 0.57.1\n",
"numexpr 2.8.4\n",
"numpy 1.24.4\n",
"packaging 23.0\n",
"pandas 1.5.3\n",
"parso 0.8.3\n",
"patsy 0.5.3\n",
"pexpect 4.8.0\n",
"pickleshare 0.7.5\n",
"Pillow 9.4.0\n",
"pip 23.2.1\n",
"platformdirs 3.10.0\n",
"prompt-toolkit 3.0.39\n",
"psutil 5.9.5\n",
"ptyprocess 0.7.0\n",
"pure-eval 0.2.2\n",
"pydot 1.4.2\n",
"Pygments 2.16.1\n",
"pyparsing 3.0.9\n",
"PyQt6 6.5.2\n",
"PyQt6-Qt6 6.5.2\n",
"PyQt6-sip 13.5.2\n",
"python-dateutil 2.8.2\n",
"pytz 2022.7\n",
"pyzmq 23.2.1\n",
"scikit-learn 1.2.2\n",
"scipy 1.11.1\n",
"seaborn 0.12.2\n",
"setuptools 68.0.0\n",
"shap 0.41.0\n",
"six 1.16.0\n",
"slicer 0.0.7\n",
"sparse 0.14.0\n",
"stack-data 0.6.2\n",
"statsmodels 0.14.0\n",
"sympy 1.12\n",
"threadpoolctl 3.2.0\n",
"tornado 6.3.2\n",
"tqdm 4.66.1\n",
"traitlets 5.9.0\n",
"typing_extensions 4.7.1\n",
"wcwidth 0.2.6\n",
"wheel 0.38.4\n",
"widgetsnbextension 4.0.8\n",
"zipp 3.16.2\n",
"Note: you may need to restart the kernel to use updated packages.\n"
]
}
],
"source": [
"pip list"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"# packages in environment at /Users/jonasschroeder/opt/anaconda3/envs/causal:\n",
"#\n",
"# Name Version Build Channel\n",
"appnope 0.1.3 pyhd8ed1ab_0 conda-forge\n",
"asttokens 2.2.1 pyhd8ed1ab_0 conda-forge\n",
"backcall 0.2.0 pyh9f0ad1d_0 conda-forge\n",
"backports 1.0 pyhd8ed1ab_3 conda-forge\n",
"backports.functools_lru_cache 1.6.5 pyhd8ed1ab_0 conda-forge\n",
"blas 1.0 mkl \n",
"bottleneck 1.3.5 py310h4e76f89_0 \n",
"brotli 1.0.9 hca72f7f_7 \n",
"brotli-bin 1.0.9 hca72f7f_7 \n",
"bzip2 1.0.8 h1de35cc_0 \n",
"ca-certificates 2023.7.22 h8857fd0_0 conda-forge\n",
"causal-learn 0.1.3.3 pypi_0 pypi\n",
"cloudpickle 2.2.1 pypi_0 pypi\n",
"comm 0.1.4 pyhd8ed1ab_0 conda-forge\n",
"contourpy 1.0.5 py310haf03e11_0 \n",
"cycler 0.11.0 pyhd3eb1b0_0 \n",
"debugpy 1.6.7 py310hcec6c5f_0 \n",
"decorator 5.1.1 pyhd8ed1ab_0 conda-forge\n",
"dowhy 0.8 pypi_0 pypi\n",
"econml 0.14.1 pypi_0 pypi\n",
"executing 1.2.0 pyhd8ed1ab_0 conda-forge\n",
"fonttools 4.25.0 pyhd3eb1b0_0 \n",
"freetype 2.12.1 hd8bbffd_0 \n",
"gcastle 1.0.3 pypi_0 pypi\n",
"giflib 5.2.1 h6c40b1e_3 \n",
"imageio 2.31.2 pypi_0 pypi\n",
"importlib-metadata 6.8.0 pyha770c72_0 conda-forge\n",
"importlib_metadata 6.8.0 hd8ed1ab_0 conda-forge\n",
"intel-openmp 2023.1.0 ha357a0b_43547 \n",
"ipykernel 6.25.1 pyh5fb750a_0 conda-forge\n",
"ipympl 0.9.3 pyhd8ed1ab_0 conda-forge\n",
"ipython 8.14.0 pyhd1c38e8_0 conda-forge\n",
"ipython_genutils 0.2.0 py_1 conda-forge\n",
"ipywidgets 8.1.0 pyhd8ed1ab_0 conda-forge\n",
"jedi 0.19.0 pyhd8ed1ab_0 conda-forge\n",
"joblib 1.3.2 pypi_0 pypi\n",
"jpeg 9e h6c40b1e_1 \n",
"jupyter_client 8.3.0 pyhd8ed1ab_0 conda-forge\n",
"jupyter_core 5.3.1 py310h2ec42d9_0 conda-forge\n",
"jupyterlab_widgets 3.0.8 pyhd8ed1ab_0 conda-forge\n",
"kiwisolver 1.4.4 py310hcec6c5f_0 \n",
"lcms2 2.12 hf1fd2bf_0 \n",
"lerc 3.0 he9d5cce_0 \n",
"libbrotlicommon 1.0.9 hca72f7f_7 \n",
"libbrotlidec 1.0.9 hca72f7f_7 \n",
"libbrotlienc 1.0.9 hca72f7f_7 \n",
"libcxx 14.0.6 h9765a3e_0 \n",
"libdeflate 1.17 hb664fd8_0 \n",
"libffi 3.3 hb1e8313_2 \n",
"libpng 1.6.39 h6c40b1e_0 \n",
"libsodium 1.0.18 hbcb3906_1 conda-forge\n",
"libtiff 4.5.0 hcec6c5f_2 \n",
"libwebp 1.2.4 hf6ce154_1 \n",
"libwebp-base 1.2.4 h6c40b1e_1 \n",
"lightgbm 4.0.0 pypi_0 pypi\n",
"llvmlite 0.40.1 pypi_0 pypi\n",
"lz4-c 1.9.4 hcec6c5f_0 \n",
"matplotlib 3.7.1 py310hecd8cb5_1 \n",
"matplotlib-base 3.7.1 py310ha533b9c_1 \n",
"matplotlib-inline 0.1.6 pyhd8ed1ab_0 conda-forge\n",
"mkl 2023.1.0 h8e150cf_43559 \n",
"mkl-service 2.4.0 py310h6c40b1e_1 \n",
"mkl_fft 1.3.6 py310h3ea8b11_1 \n",
"mkl_random 1.2.2 py310h3ea8b11_1 \n",
"mpmath 1.3.0 pypi_0 pypi\n",
"munkres 1.1.4 py_0 \n",
"ncurses 6.4 hcec6c5f_0 \n",
"nest-asyncio 1.5.6 pyhd8ed1ab_0 conda-forge\n",
"networkx 2.8.7 pypi_0 pypi\n",
"numba 0.57.1 pypi_0 pypi\n",
"numexpr 2.8.4 py310h827a554_1 \n",
"numpy 1.24.4 pypi_0 pypi\n",
"openssl 1.1.1v h8a1eda9_0 conda-forge\n",
"packaging 23.0 py310hecd8cb5_0 \n",
"pandas 1.5.3 py310h3ea8b11_0 \n",
"parso 0.8.3 pyhd8ed1ab_0 conda-forge\n",
"patsy 0.5.3 pypi_0 pypi\n",
"pexpect 4.8.0 pyh1a96a4e_2 conda-forge\n",
"pickleshare 0.7.5 py_1003 conda-forge\n",
"pillow 9.4.0 py310hcec6c5f_0 \n",
"pip 23.2.1 py310hecd8cb5_0 \n",
"platformdirs 3.10.0 pyhd8ed1ab_0 conda-forge\n",
"prompt-toolkit 3.0.39 pyha770c72_0 conda-forge\n",
"prompt_toolkit 3.0.39 hd8ed1ab_0 conda-forge\n",
"psutil 5.9.5 py310h90acd4f_0 conda-forge\n",
"ptyprocess 0.7.0 pyhd3deb0d_0 conda-forge\n",
"pure_eval 0.2.2 pyhd8ed1ab_0 conda-forge\n",
"pydot 1.4.2 pypi_0 pypi\n",
"pygments 2.16.1 pyhd8ed1ab_0 conda-forge\n",
"pyparsing 3.0.9 py310hecd8cb5_0 \n",
"pyqt6 6.5.2 pypi_0 pypi\n",
"pyqt6-qt6 6.5.2 pypi_0 pypi\n",
"pyqt6-sip 13.5.2 pypi_0 pypi\n",
"python 3.10.0 hdfd78df_5 \n",
"python-dateutil 2.8.2 pyhd3eb1b0_0 \n",
"python-graphviz 0.20.1 pypi_0 pypi\n",
"python_abi 3.10 2_cp310 conda-forge\n",
"pytz 2022.7 py310hecd8cb5_0 \n",
"pyzmq 23.2.1 py310hcabbbd4_0 conda-forge\n",
"readline 8.2 hca72f7f_0 \n",
"scikit-learn 1.2.2 pypi_0 pypi\n",
"scipy 1.11.1 pypi_0 pypi\n",
"seaborn 0.12.2 py310hecd8cb5_0 \n",
"setuptools 68.0.0 py310hecd8cb5_0 \n",
"shap 0.41.0 pypi_0 pypi\n",
"six 1.16.0 pyhd3eb1b0_1 \n",
"slicer 0.0.7 pypi_0 pypi\n",
"sparse 0.14.0 pypi_0 pypi\n",
"sqlite 3.41.2 h6c40b1e_0 \n",
"stack_data 0.6.2 pyhd8ed1ab_0 conda-forge\n",
"statsmodels 0.14.0 pypi_0 pypi\n",
"sympy 1.12 pypi_0 pypi\n",
"tbb 2021.8.0 ha357a0b_0 \n",
"threadpoolctl 3.2.0 pypi_0 pypi\n",
"tk 8.6.12 h5d9f67b_0 \n",
"tornado 6.3.2 py310h6c40b1e_0 \n",
"tqdm 4.66.1 pypi_0 pypi\n",
"traitlets 5.9.0 pyhd8ed1ab_0 conda-forge\n",
"typing-extensions 4.7.1 hd8ed1ab_0 conda-forge\n",
"typing_extensions 4.7.1 pyha770c72_0 conda-forge\n",
"tzdata 2023c h04d1e81_0 \n",
"wcwidth 0.2.6 pyhd8ed1ab_0 conda-forge\n",
"wheel 0.38.4 py310hecd8cb5_0 \n",
"widgetsnbextension 4.0.8 pyhd8ed1ab_0 conda-forge\n",
"xz 5.4.2 h6c40b1e_0 \n",
"zeromq 4.3.4 he49afe7_1 conda-forge\n",
"zipp 3.16.2 pyhd8ed1ab_0 conda-forge\n",
"zlib 1.2.13 h4dc903c_0 \n",
"zstd 1.5.5 hc035e20_0 \n",
"\n",
"Note: you may need to restart the kernel to use updated packages.\n"
]
}
],
"source": [
"conda list"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# Train set\n",
"earnings_interaction_train = pd.read_csv('../Causal-Inference-and-Discovery-in-Python/data/ml_earnings_interaction_train.csv')\n",
"\n",
"# Test set\n",
"earnings_interaction_test = pd.read_csv('../Causal-Inference-and-Discovery-in-Python/data/ml_earnings_interaction_test.csv')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Overview and Summary\n",
"\n",
"While trying to understand how meta-learners work, I noticed that the causal graph we define in step 1 of DoWhy's four-step process only matters sometimes.\n",
"\n",
"I read Matheus Facure's Book, [Causal Inference for the Brave and Good](\"https://matheusfacure.github.io/python-causality-handbook/21-Meta-Learners.html?highlight=meta%20learner\"), in parallel to Aleksander Molak's Causal Inference and Discovery in Python.\n",
"\n",
"I adapted the code for the S-Learner from Chaper 21 in Facure's Book which works without specifying a graph. The outcome was identical to using DoWhy with specifying a graph (graph 1), even when switching confounder with an effect modifier (graph 3)\n",
"\n",
"However, changing the direction of the edge between treatment and confounder changed the estimated treatment effect through the variables' changed roles.\n",
"\n",
"My conclusion: Unlike my initial assumption, the specified graph can play a role in DoWhy's estimation but not always. Specifically the role of confounder and effect modifier is \"ignored\". \n",
"\n",
"I have trouble understanding why. Is it expected? What am I missing here.\n",
"\n",
"**Outline:**\n",
"- 0: S-Learner without Graph\n",
"- Graph 1: S-Learner in DoWhy as it is in Molak's book --> same result as without (graphical) model specification\n",
"- Graph 2: Like Graph 1 but edge direction between confounder and treatment flipped --> different result than in Graph 1\n",
"- Graph 3: Like Graph 1 but confounder and effect modifier switched --> same result as in Graph 1 (weird)\n",
"\n",
"# 0: Without Graph"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[LightGBM] [Warning] Accuracy may be bad since you didn't explicitly set num_leaves OR 2^max_depth > num_leaves. (num_leaves=31).\n",
"[LightGBM] [Warning] Accuracy may be bad since you didn't explicitly set num_leaves OR 2^max_depth > num_leaves. (num_leaves=31).\n",
"[LightGBM] [Warning] Auto-choosing col-wise multi-threading, the overhead of testing was 0.000286 seconds.\n",
"You can set `force_col_wise=true` to remove the overhead.\n",
"[LightGBM] [Info] Total Bins 290\n",
"[LightGBM] [Info] Number of data points in the train set: 5000, number of used features: 3\n",
"[LightGBM] [Info] Start training from score 143134.027200\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] Accuracy may be bad since you didn't explicitly set num_leaves OR 2^max_depth > num_leaves. (num_leaves=31).\n",
"[LightGBM] [Warning] Accuracy may be bad since you didn't explicitly set num_leaves OR 2^max_depth > num_leaves. (num_leaves=31).\n"
]
}
],
"source": [
"# Without DoWhy (adapted from Matheus Facure)\n",
"# Note: we can see that S-Learners ignore assumptions about relationships between features (not based on causal graph)\n",
"y = \"earnings\"\n",
"T = \"took_a_course\"\n",
"X = [\"age\", \"python_proficiency\"]\n",
"\n",
"s_learner = LGBMRegressor(n_estimators=500, max_depth=10)\n",
"s_learner.fit(earnings_interaction_train[X+[T]], earnings_interaction_train[y])\n",
"\n",
"s_learner_cate_train = (s_learner.predict(earnings_interaction_train[X].assign(**{T: 1})) -\n",
" s_learner.predict(earnings_interaction_train[X].assign(**{T: 0})))"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"S-Learner CATE without DoWhy: 12547.068205674783\n"
]
}
],
"source": [
"print(f\"S-Learner CATE without DoWhy: {s_learner_cate_train.mean()}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Graph 1 (as it should me)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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I1ABFBERkVS3YsUKwsPDyZ07Nxs2bKBevXpWR5J/UA0XERGRVHP58mWefPJJAgICqF+/Pg6HQ+UvA9IEUERERFLF/v37CQoKYufOnbz88suMGDECm81mdSy5ARVAERERuWcff/wxPXr0IF++fGzatInatWtbHUluQUvAIiIictcuXbrE8OHD6dSpE02aNMHhcKj8ZQKaAIqIiMhd+eWXX7Db7Xz33Xf85z//YfDgwVryzSRUAEVEROSOvf/++/Tq1YtChQqxZcsWqlevbnUkuQNaAhYREZEUu3jxIgMHDuSJJ56gVatWxMbGqvxlQpoAioiISIr8/PPP2O129uzZw9y5c+nXr5+WfDMpTQBFRETktpYtW0a1atU4f/480dHR9O/fX+UvE1MBFBERkZuKi4ujT58+hISE0L59e3bu3Imvr6/VseQeaQlYREREbmjPnj3Y7Xb+97//MW/ePHr27Kmpn5vQBFBERESus3DhQmrUqEFiYiLbt2+nV69eKn9uRAVQRERErjl//jw9evQgIiICu91OTEwMlStXtjqWpDItAYuIiAgA33//PXa7nd9++4333nuP8PBwqyNJGtEEUERExMMZY/jvf/9LrVq18Pb2ZseOHSp/bk4FUERExIOdPXuWbt260bt3b8LCwti+fTsVK1a0OpakMS0Bi4iIeKhdu3Zht9s5dOgQS5YsISQkxOpIkk40ARQREfEwxhjefPNNateuTc6cOdm5c6fKn4dRARQREfEgZ86cISgoiAEDBtCrVy+io6MpV66c1bEknWkJWERExEPs3LmTwMBAjh07RlRUFE888YTVkcQimgCKiIi4OWMMr7/+OvXq1SN//vzExsaq/Hk4FUARERE3durUKbp06cLQoUMZMGAAmzdvpnTp0lbHEotpCVhERMRNbd++ncDAQE6fPs1HH31Ex44drY4kGYQmgCIiIm7GGMMrr7xC/fr1eeihh3A4HCp/kowKoIiIiBs5efIkHTp0YNSoUQwbNowNGzZQsmRJq2NJBqMlYBERETexZcsWgoKCOH/+PJ999hkBAQFWR5IMShNAERGRTC4pKYkXX3yRRo0aUbx4cZxOp8qf3JIKoIiISCZ27NgxAgICePrppxk9ejRr166lWLFiVseSDE5LwCIiIpnUhg0bCA4OJj4+npUrV9KyZUurI0kmoQmgiIhIJpOYmMjU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",
"text/plain": [
"<Figure size 800x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Construct the graph (the graph is constant for all iterations)\n",
"nodes = ['took_a_course', 'python_proficiency', 'earnings', 'age']\n",
"edges = [\n",
" ('took_a_course', 'earnings'),\n",
" ('age', 'took_a_course'),\n",
" ('age', 'earnings'),\n",
" ('python_proficiency', 'earnings')\n",
"]\n",
"\n",
"# Generate the GML graph\n",
"gml_string = 'graph [directed 1\\n'\n",
"\n",
"for node in nodes:\n",
" gml_string += f'\\tnode [id \"{node}\" label \"{node}\"]\\n'\n",
"\n",
"for edge in edges:\n",
" gml_string += f'\\tedge [source \"{edge[0]}\" target \"{edge[1]}\"]\\n'\n",
" \n",
"gml_string += ']'\n",
"\n",
"# Instantiate the CausalModel \n",
"model = CausalModel(\n",
" data=earnings_interaction_train,\n",
" treatment='took_a_course',\n",
" outcome='earnings',\n",
" effect_modifiers='python_proficiency',\n",
" graph=gml_string\n",
")\n",
"\n",
"model.view_model()"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Estimand type: nonparametric-ate\n",
"\n",
"### Estimand : 1\n",
"Estimand name: backdoor\n",
"Estimand expression:\n",
" d \n",
"────────────────(E[earnings|age])\n",
"d[took_a_course] \n",
"Estimand assumption 1, Unconfoundedness: If U→{took_a_course} and U→earnings then P(earnings|took_a_course,age,U) = P(earnings|took_a_course,age)\n",
"\n",
"### Estimand : 2\n",
"Estimand name: iv\n",
"No such variable(s) found!\n",
"\n",
"### Estimand : 3\n",
"Estimand name: frontdoor\n",
"No such variable(s) found!\n",
"\n"
]
}
],
"source": [
"# Get the estimand\n",
"estimand = model.identify_effect()\n",
"\n",
"print(estimand)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/utils/_clustering.py:35: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def _pt_shuffle_rec(i, indexes, index_mask, partition_tree, M, pos):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/utils/_clustering.py:54: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def delta_minimization_order(all_masks, max_swap_size=100, num_passes=2):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/utils/_clustering.py:63: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def _reverse_window(order, start, length):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/utils/_clustering.py:69: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def _reverse_window_score_gain(masks, order, start, length):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/utils/_clustering.py:77: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def _mask_delta_score(m1, m2):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/links.py:5: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def identity(x):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/links.py:10: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def _identity_inverse(x):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/links.py:15: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def logit(x):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/links.py:20: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def _logit_inverse(x):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/utils/_masked_model.py:363: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def _build_fixed_single_output(averaged_outs, last_outs, outputs, batch_positions, varying_rows, num_varying_rows, link, linearizing_weights):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/utils/_masked_model.py:385: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def _build_fixed_multi_output(averaged_outs, last_outs, outputs, batch_positions, varying_rows, num_varying_rows, link, linearizing_weights):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/utils/_masked_model.py:428: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def _init_masks(cluster_matrix, M, indices_row_pos, indptr):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/utils/_masked_model.py:439: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def _rec_fill_masks(cluster_matrix, indices_row_pos, indptr, indices, M, ind):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/maskers/_tabular.py:186: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def _single_delta_mask(dind, masked_inputs, last_mask, data, x, noop_code):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/maskers/_tabular.py:197: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def _delta_masking(masks, x, curr_delta_inds, varying_rows_out,\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/maskers/_image.py:175: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def _jit_build_partition_tree(xmin, xmax, ymin, ymax, zmin, zmax, total_ywidth, total_zwidth, M, clustering, q):\n",
"/Users/jonasschroeder/opt/anaconda3/envs/causal/lib/python3.10/site-packages/shap/explainers/_partition.py:676: NumbaDeprecationWarning: The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
" def lower_credit(i, value, M, values, clustering):\n",
"The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
"The 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\n",
"A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().\n",
"`sparse` was renamed to `sparse_output` in version 1.2 and will be removed in 1.4. `sparse_output` is ignored unless you leave `sparse` to its default value.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"[LightGBM] [Warning] Accuracy may be bad since you didn't explicitly set num_leaves OR 2^max_depth > num_leaves. (num_leaves=31).\n",
"[LightGBM] [Warning] Accuracy may be bad since you didn't explicitly set num_leaves OR 2^max_depth > num_leaves. (num_leaves=31).\n",
"[LightGBM] [Warning] Auto-choosing col-wise multi-threading, the overhead of testing was 0.000072 seconds.\n",
"You can set `force_col_wise=true` to remove the overhead.\n",
"[LightGBM] [Info] Total Bins 292\n",
"[LightGBM] [Info] Number of data points in the train set: 5000, number of used features: 4\n",
"[LightGBM] [Info] Start training from score 143134.027200\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] Accuracy may be bad since you didn't explicitly set num_leaves OR 2^max_depth > num_leaves. (num_leaves=31).\n"
]
}
],
"source": [
"# Get estimate (S-Learner) with DoWhy\n",
"estimate = model.estimate_effect(\n",
" identified_estimand=estimand,\n",
" method_name='backdoor.econml.metalearners.SLearner',\n",
" target_units='ate',\n",
" method_params={\n",
" 'init_params': {\n",
" 'overall_model': LGBMRegressor(n_estimators=500, max_depth=10)\n",
" },\n",
" 'fit_params': {}\n",
" })"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"DoWhy S-Learner's CATE: 12547.068205674783\n"
]
}
],
"source": [
"s_cate = estimate.cate_estimates.mean()\n",
"print(f\"DoWhy S-Learner's CATE: {s_cate}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Graph 2: Switch Arrow T<-X to T->X"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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VKhQgZ9++onChQv/6xY5f/x3FS4+ATwEhAFBwMZz16Vz6V8+564/f8r5RqADEA4czrLV//3f/9GkSRPefPNNXn/9dT744AOVPxERkVx266230r17d8C5NHz++2+//ca8efP+sWXuHP9diQtPALcBrXH+I7iRj5bxBEoD3wB1+O9//0ufPn247bbbiIuLw9/fPweyioiIyNX8+OOP+Pr6kpqaetHPKlSowP/93/9RuPBOcuP472pcdAK4DWjGjf/yOXf7QxjThEmTgrHb7bRr146kpCSVPxERkTw0depUUlNTL3nCx++//87//jeRnD7+Q1Pg2xvcV/7jghPAQ4APOfPL/1t6Ohw6BF988TJRUTrRQ0REJK/9+eeffP7552zbto3k5GS2bt3KkSNHAChVCnbuhNtv9yQnj/9/TwJ3AqVycL/WsrwA9uzZkw8++IATJ07k0B7DgDhy9pfvZIwHNlsIsCDH9y0iIiLXLiUlhW3btlG69DDuu+8HPD2vvdY0b+78vmrV5bbwBIJxpeN/dt80p4BYCizKtb3bbJnAQpwvDHXts4NEREQKgjvuuIPWrdOA7697HzNmXG2LDFzt+O9irwGcQu4/JM9z95P7MjIyOHPmTJ7cl4iISMH19/HfGLjEOSJX5OPj/LqyvDv+54VstyWbzcaqVavIzMzkxRdfpGbNmnh5eXH77bcTGRnJnj17LrrNe++9x3333cdNN91EqVKlePjhh9m5c+dV72v9+vWUKVOGoKAgTp48ma18P/30Ob16reeeezK5+WYoVw46doRvr/N1mwsXQkAA3HKL88vXF959F5x/BawDtmfr8TVv3pzm52fL/9CzZ08qV6584fLu3bux2Wy8+OKLTJo0ibvvvhsvLy9WrlxJZmYmkyZNokaNGnh7e1OyZEnq1q3LtGnTsuxz165dhIWFcfvtt+Pl5UWtWrWYPn369T0BIiIiueRqx6vTp08zcuRIfH19KVGiBKVKlSIgIICPP/74on3ZbDaGDFnPm29mUqsWeHnBnDkwezbYbLByJQwcCGXKQOnS0LUr7N2bdR/Nm/+9DAywe7fzti+9BK+8AnffDbfckkFAwDri4xdelOGdd96hevXqeHl54ePjw8KFCy86zgPMnDmT++67j1tuuYVixYpRs2ZNRo8efd3P4w0x2bRx40bz119/mX79+hnADBkyxCxb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j8PhUPnLBzQBFBERkVzx+++/ExoaSnx8PM8//zxPPPEEHh6aPeUHKoAiIiKS45YuXUpkZCRFixZlzZo13H///VZHkn9QDRcREZEcc/bsWR5//HGCgoJo0qQJycnJKn/5kCaAIiIikiN2795NSEgIW7Zs4eWXX2b48OHYbDarY8klqACKiIjIDfvoo4/o1asXJUqUYN26dTRq1MjqSHIFWgIWERGR63bmzBkee+wxHn74YVq0aEFycrLKXwGgCaCIiIhcl59//hm73c63337Lf/7zH4YMGaIl3wJCBVBERESu2QcffEDv3r0pU6YMGzZsoF69elZHkmugJWARERHJttOnTzNo0CAeeeQR2rZtS1JSkspfAaQJoIiIiGTLrl27sNvt7Ny5k5kzZ9K/f38t+RZQmgCKiIjIVS1atAh/f39OnjxJfHw8AwYMUPkrwFQARURE5LJSU1Pp27cvYWFhdOrUiS1btuDr62t1LLlBWgIWERGRS9q5cyd2u53/+7//Y9asWURHR2vq5yI0ARQREZGLzJ07l/r165ORkcHmzZvp3bu3yp8LUQEUERGRC06ePEmvXr2IiorCbreTkJDAvffea3UsyWFaAhYREREAvvvuO+x2O7/++itz5swhMjLS6kiSSzQBFBERcXPGGN59910aNmyIp6cniYmJKn8uTgVQRETEjR0/fpwePXrQp08fIiIi2Lx5M7Vq1bI6luQyLQGLiIi4qa1bt2K329m7dy8LFiwgLCzM6kiSRzQBFBERcTPGGN58800aNWqEt7c3W7ZsUflzMyqAIiIibuTYsWOEhIQwcOBAevfuTXx8PNWrV7c6luQxLQGLiIi4iS1bthAcHMyBAweIi4vjkUcesTqSWEQTQBERERdnjOH111/n/vvvp2TJkiQlJan8uTkVQBERERd25MgRunXrxrBhwxg4cCDr16+natWqVscSi2kJWERExEVt3ryZ4OBgjh49yv/+9z+6dOlidSTJJzQBFBERcTHGGF555RWaNGnCHXfcQXJyssqfZKECKCIi4kIOHz5M586dGTlyJI8++ihr1qyhcuXKVseSfEZLwCIiIi5iw4YNhISEcPLkST799FOCgoKsjiT5lCaAIiIiBVxmZiYvvPACDzzwABUrVsThcKj8yRWpAIqIiBRgBw4cICgoiKeeeoqYmBhWrlxJhQoVrI4l+ZyWgEVERAqoNWvWEBoaSlpaGsuWLaNNmzZWR5ICQhNAERGRAiYjI4NJkybRokUL7rnnHrZu3aryJ9dEE0AREZECJCUlhYiICJYvX864ceMYN24chQrpcC7XRv9iRERECogVK1YQHh6OMYavv/6aBx980OpIUkBpCVhERCSfy8jIYPz48bRq1YratWvjcDhU/uSGaAIoIiKSj+3du5fw8HDWrFnDxIkTGT16NJ6enlbHkgJOBVBERCSf+uqrr4iIiKBw4cKsWLGCwMBAqyOJi9ASsIiISD6Tnp7O6NGjadOmDf7+/jgcDpU/yVGaAIqIiOQje/bsITQ0lI0bNzJlyhRiYmLw8NC8RnKWCqCIiEg+8fnnnxMZGYm3tzerV6+mSZMmVkcSF6U/KURERCx29uxZYmJi6NChAwEBATgcDpU/yVWaAIqIiFjo119/JSQkhMTERF566SVGjBiBzWazOpa4OBVAERERi3z88cf06tWL4sWLs3btWho3bmx1JHETWgIWERHJY2lpaTz22GN06dKFwMBAkpOTVf4kT2kCKCIikod+/vlngoOD2bp1K9OmTWPo0KFa8pU8pwIoIiKSRz788EOio6MpU6YMGzZsoH79+lZHEjelJWAREZFcdvr0aYYMGUL37t1p06YNSUlJKn9iKU0ARUREctGuXbsIDg5mx44dzJgxgwEDBmjJVyynCaCIiEguWbx4MfXq1ePEiRPEx8czcOBAlT/JF1QARUREclhqair9+/cnNDSUjh07smXLFnx9fa2OJXKBloBFRERy0Pfff4/dbmfXrl2888479O7dW1M/yXc0ARQREckh8+bNo379+pw9e5bNmzfTp08flT/Jl1QARUREbtDJkyeJjo4mMjKS7t27k5iYSJ06dayOJXJZWgIWERG5Adu3b8dut7N7925mz55NVFSU1ZFErkoTQBERketgjOG9996jQYMGeHh4kJCQoPInBYYKoIiIyDU6ceIEkZGR9O7dm/DwcDZt2oSPj4/VsUSyTUvAIiIi12Dbtm088sgj7N27lwULFhAWFmZ1JJFrpgmgiIhINhhjeOutt2jYsCHe3t5s2bJF5U8KLBVAERGRqzh27BihoaEMGDCA6Oho4uPjqV69utWxRK6bloBFRESuICkpieDgYFJSUoiNjcVut1sdSeSGaQIoIiJyCcYY3njjDQICAihRogTJ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",
"text/plain": [
"<Figure size 800x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Construct the graph\n",
"nodes = ['took_a_course', 'python_proficiency', 'earnings', 'age']\n",
"edges = [\n",
" ('took_a_course', 'earnings'),\n",
" ('took_a_course', 'age'),\n",
" ('age', 'earnings'),\n",
" ('python_proficiency', 'earnings')\n",
"]\n",
"\n",
"# Generate the GML graph\n",
"gml_string = 'graph [directed 1\\n'\n",
"\n",
"for node in nodes:\n",
" gml_string += f'\\tnode [id \"{node}\" label \"{node}\"]\\n'\n",
"\n",
"for edge in edges:\n",
" gml_string += f'\\tedge [source \"{edge[0]}\" target \"{edge[1]}\"]\\n'\n",
" \n",
"gml_string += ']'\n",
"\n",
"# Instantiate the CausalModel \n",
"model = CausalModel(\n",
" data=earnings_interaction_train,\n",
" treatment='took_a_course',\n",
" outcome='earnings',\n",
" effect_modifiers='python_proficiency',\n",
" graph=gml_string\n",
")\n",
"\n",
"model.view_model()"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Estimand type: nonparametric-ate\n",
"\n",
"### Estimand : 1\n",
"Estimand name: backdoor\n",
"Estimand expression:\n",
" d \n",
"────────────────(E[earnings])\n",
"d[took_a_course] \n",
"Estimand assumption 1, Unconfoundedness: If U→{took_a_course} and U→earnings then P(earnings|took_a_course,,U) = P(earnings|took_a_course,)\n",
"\n",
"### Estimand : 2\n",
"Estimand name: iv\n",
"No such variable(s) found!\n",
"\n",
"### Estimand : 3\n",
"Estimand name: frontdoor\n",
"No such variable(s) found!\n",
"\n"
]
}
],
"source": [
"# Get the estimand\n",
"estimand = model.identify_effect()\n",
"\n",
"print(estimand)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[LightGBM] [Warning] Accuracy may be bad since you didn't explicitly set num_leaves OR 2^max_depth > num_leaves. (num_leaves=31).\n",
"[LightGBM] [Warning] Accuracy may be bad since you didn't explicitly set num_leaves OR 2^max_depth > num_leaves. (num_leaves=31).\n",
"[LightGBM] [Warning] Auto-choosing col-wise multi-threading, the overhead of testing was 0.000072 seconds.\n",
"You can set `force_col_wise=true` to remove the overhead.\n",
"[LightGBM] [Info] Total Bins 259\n",
"[LightGBM] [Info] Number of data points in the train set: 5000, number of used features: 3\n",
"[LightGBM] [Info] Start training from score 143134.027200\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().\n",
"`sparse` was renamed to `sparse_output` in version 1.2 and will be removed in 1.4. `sparse_output` is ignored unless you leave `sparse` to its default value.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] Accuracy may be bad since you didn't explicitly set num_leaves OR 2^max_depth > num_leaves. (num_leaves=31).\n"
]
}
],
"source": [
"# Get estimate (S-Learner) with DoWhy\n",
"estimate = model.estimate_effect(\n",
" identified_estimand=estimand,\n",
" method_name='backdoor.econml.metalearners.SLearner',\n",
" target_units='ate',\n",
" method_params={\n",
" 'init_params': {\n",
" 'overall_model': LGBMRegressor(n_estimators=500, max_depth=10)\n",
" },\n",
" 'fit_params': {}\n",
" })"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"DoWhy S-Learner's CATE: 4907.357034585269\n"
]
}
],
"source": [
"s_cate = estimate.cate_estimates.mean()\n",
"print(f\"DoWhy S-Learner's CATE: {s_cate}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Graph 3: Switch Confounder and Effect Modifer"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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6+rt9+/fb4oWLWrq1atnVq1aZf71r3+ZSZMmGS8vr3TbiYiIWCkjx6tTp06ZAQMGmNWrV5sNGzaYzp07m+LFixubzWbeeuutdPtzHTsx9etj1qzBbNiA+eorzFtvuY7lVapgxo7FfPIJZvlyzP33Y9q2TX/cDwx0fV25/OOPrtt6e2M6d8b885+ur3r1MPfff485derU1ft/9dVXDWD69OljPvzwQxMTE2Nq1KhhKlWqlO44HxsbawAzduxY869//ct89tln5pVXXjHjxo3L4mf8+jJcAI0x5sCBAwYwo0aNSnf9rl27DGCmTZtmjDHm5MmTpmDBgqZr167ptvvvf/9rChQoYMLDw69e9+cC+Oyzz5o8efKY55577g4eSjvz519maiomJQVTvTpmwoSMl7///AeTJw8mIuLG25w8iSlY0CtDj+92C2DVqlVNSkpKum2DgoKMr6/vTR99p06dTPny5c3vv/+e7voxY8aYe+65x5w4ceKmtxcREckOd3K8atmypcH1bs2mQIECJj4+3qSlpRljXAWwaFHMiRPpj9VXCuCoUemvX7DAdf1vv926ANar5+oTV67fvdt1fWxsrDHGmLS0NFO6dGnTpEmTdHl/+uknky9fvnTH+TFjxphixYplwjOYOW7rBXMbN24EXMuXf9a4cWNq167N559/DsCOHTtITk6+ZrsKFSrQrl27q9v9aQrJ8OHDmTlzJmvWrGHy5Mm3EwswpKYmMG+eaw0/f37Im9f1/fvvXaeFZ9Snn0JaGowefeNtduyA5GQnAwZEpbv+Ro/vdvTo0eOaj7Jp3Lgx+/btY9SoUXzyySecPn063c8vXLjA559/zsMPP8y9995Lamrq1a+uXbty4cIFdu7ceceZREREMsPtHK/+8Y9/0KJFC+677z62bt16dR8XL14kJCQEHx8f7PZ4ANq1g/vvv/599uiR/nL9+q7vP/1067zdukGePNe77UEAvv32Ww4dOkRwcHC621WsWJEWLVqku65x48acOnWKsLAw3nvvPY4dO3brAFnots4CPn78OABlypS55mdly5blp8vP5q22+/TTT9Ndl5KSQnx8PHXq1KFLly63E+myM0yceIYlS2DKFAgMdP1D8PKCIUNu78WgR4+6vpcvf+NtLj88li17kdWr038A9f79+zly5Ag9Lv+L++or1wdL9/jLv8CkpCSOHz9+9frz588DsH79en744Yd02zqdTmrXrk1MTAzLli3DZrNRokQJateuTbFixUhOTiY1NZXFixezePHi62aeNm0ay5Ytu/UTICIikkUyerx66qmn2LNnD2XKlKF27dp899131ww/vv32W4YMCQXgOnXjqhIl0l8uUOBKllvnvfFtfwf+6DulSpW65ralSpXixx9/vHq5X79+pKam8vrrr9OnTx+cTicBAQHMnTuXjh073jpMJrutAlji8jPx22+/Uf4vDenXX3+lZMmS12z3V3/e7oorJzt06tSJDh06sH79eu6/UZW/rhSio6F/f5g3L/1Pjh2DYsUyvqcHHnB9/+UXqFDh+ttc+Qdx6dKFa3524cIF8ufPf/Wyl5cXqamp12yXkpJy3X3bbLZrrvPy8qJq1apUrVqVS5cucfToUb755ht27txJhw4dyJcvHzabjfLly1/zgtMr7r333us/GBERkWyS0ePVvn37uPfee2nYsCE2m43//Oc/1932yuH2OofOLOZ6r+Erfefw4cPXbHHo0KFrrhs4cCADBw7k3LlzbN68mZkzZxIUFMR3331HpUqVsjbyX93OevE333xjgGtesLh7924DmCeffNIY88drAHv06JFuu59//tkUKFDAREREXL3uz68B/Prrr03ZsmVN/fr1zeHDh28j2e+meHHM8OHp1/k//NC1Vv/ndf1bff34o+s1gP363eo1gJgePdK/BvB6j2/48OGmePHi5sKFC1evO3bsmLn//vuv+xrAhQsXZugRv/zyywYw+/fvN8YY06FDB9OgQQNz8eLFjD5pIiIi2S4jx6vevXubmjVrXr3cqlWrq68BvPJVs2ZNs3btCgOY0aOvPVZfeQ1gQkL66zdudF2/ceOtXwO4cOG1+wXMzJlPGGNu7zWA1/PPf/7TAGbdunW38QxmjgxPAPfs2UPNmjUZNmwYixcvxsvLiy5dunDw4EFmzJhBhQoVmDBhAgDFihVjxowZTJs2jf79+xMWFsbx48eZPXs299xzDzNnzrzufdSuXZstW7bQoUMHWrduzWeffXbNpPH6ChMUlI8VKy5Rq5ZrjX7vXli48OZLudfj7Q3TpsHTT7vGw2FhULQofP21a5o4e7ZrojhjRgGmTfvolo+vX79+vPrqq0RGRjJ06FCOHz/OggULKFKkSIYzde/enbp169KoUSMeeOABfvrpJ15++WUqVapE9erVAVi0aBEtW7akVatWjBw5Em9vb86cOcMPP/zABx98wIYNG27viRAREckCGTleBQUFsXbtWkaNGkXfvn2vmbDZ7Xb69OmDl5cNGGDBo3CNHr28vJg9ezbDhw+nb9++DBo0iFOnTjF79mzKlCmDl9cfp1oMHTqUggUL0qJFC8qUKcOhQ4eYP38+RYsWJSAgIPsfQkabImA2btxo0tLSzHPPPWdq1Khh8uXLZ0qWLGkiIyPNzz//fM1tli9fburXr2/y589vihYtanr27Hl1YnXFX98GxhhjfvnlF1OrVi3j7e1t/u///i9D+U6ebGUGD8Y8+CDm3nsxLVtitmy5ttVn9GvVKkxAAOaeezD33Yfx83P9NeH6uc0Y0z5Dj88YY1auXGlq165t7rnnHuPj42Pi4+NveBbw9SaAL7zwgmnevLkpWbKkyZ8/v6lYsaIZPHiwOXjwYLrtfvzxRzNo0CBTrlw5ky9fPvPAAw+Y5s2bm7lz52boORQREckOGTlePfvss8bb29sUKFDAFCtWzJQpU8b07dvX/LW6kK0TQNvlCeDMdBlee+01U61aNZM/f35To0YN8+abb5qePXsaPz+/q9usXLnStG3b1pQqVcrkz5/flC1b1gQHB5svv/wyc5/cDLL8s4AzzzRgIXDt6+0yX15gMvBMNtyXiIiI3FjOO/6fOnWKGjVq0KtXL1577bVsyHX73KgAfgXUy+b7q5ON9yciIiLXsvb4f+jQIZ555hnatm1LiRIl+Omnn3jppZf45ptv2LNnD3Xq5MyucFtnAVvB6XTidDpvuk3evHmBukALYAdw/e3T0lyfEXgjNlv69/u5vjxAM1T+REREcoJbH/8zx/WP/wUKFODgwYOMGjWKEydOcO+999K0aVNeeeWVHFv+4DY+C9gqc+bMIV++fDf9Onjw4OWtp3KzX37VqpAv342/2rfPSKI0TpwYgdsMTkVERHIpYwyHDh0iMbETWVv+wPXWL1Ovufb+++/ngw8+4NChQ6SkpHDq1CnWr19PkyZNsjjP3cnxS8C//vorv/71U5v/on79+n96771wwM6V9+j5s3//Gy5evPF+CheGmjVv/PPUVIiPh8hI1y+8fv36+Pn5Ub9+fbp168aDDz54y8cjIiIid+bIkSOsW7eOL7/8kqSkJL788ktOnjwJQEwMBAe7Pgks8+UBQoCYrNi5JXJ8Abx9xwGfy9+vLYF3yun04uhRJ7Vrw+V/a4Br+Tk1NZUhQ4bw+uuvZ9r9iYiISHpDhw5l+fLlV4+9f1a8OPz8c2Huvfc8mXn8d5W/EsABoHgm7tdaOX4J+PaVAD4DCuH6pWWGPNhs9xEZWSpd+QNIS0ujYMGCd/D5xSIiInI7Jk+eTMGCBa/7CVuFClUgX75NZPbx37W/z3Cn8gduWQDBdTbQVlxl8G7/Ebiav822ldDQa0/7NsbwxhtvXH1DZhEREcka1atXZ/ny5df92axZs8iXz5/MPv679pedZxlnDzctgOD6ZR3AtWYPt/8P4cr2oZf3U4/+/ftTsWLFq5/Xe+X7P/7xj6uvQRAREZGscfLkSf7xj38ApDsWV6xYkX79+l3eKvOP/+7IjQsguMa1McA6XKdug+udb270qdE2/nhnnGaXbxfNlbFvvnz5mDVrFsYYvLy8qFWrFnFxcWzcuBF/f3927dqVVQ9ERETEo+3atQs/Pz82bdpEfHw8NWvWxMvLC2MMs2fPJl++fH/aOnOP/+7IDU8CuZn9wBpgF5AAnP7Tz4oAAUATXGcSX/+9e1JTU6lWrRqHDx8mKSmJWrVqcfDgQUJDQ9m7dy/PPfccEyZMuPqXiYiIiNw5YwwvvvgiTzzxBI0aNSIuLo5KlSpx4MAB/P39KV26NN9///3l9wS+kbs//rsbDyuAf2aAs0AKrg91vo8b/2WQ3tdff825c+fSfXhzSkoK06ZN44UXXiAoKIgVK1ZQokSJLMgtIiLiGY4fP86AAQP48MMPeeyxx5g3b166SV9CQgKFChXCx8fnNvZ658d/d+LBBTBrfPjhh0RFRVGoUCHi4uJo3ry51ZFERERynW3bthEaGkpycjIrV66kW7duVkdyK27+GsDsFxQUhMPhoGLFirRu3Zrnnnvulh9lJyIiIi5Op5Nnn32WwMBAvL29cTgcKn9ZQAUwC1SoUIFNmzYxefJknnjiCbp168bRo0etjiUiIpKjHT16lG7dujF16lQmT57Mxo0bKV++vNWx3JKWgLPYJ598Qr9+/ciXLx+xsbG0bt3a6kgiIiI5zhdffEF4eDiXLl1i9erVdOrUyepIbk0TwCzWqVMnHA4H1atXp23btsydO5e0tMz8iBoREZHcKy0tjaeffpp27dpRo0YNHA6Hyl820AQwm6SmpvL000/z9NNP0759e6KjoylVqpTVsURERCxz6NAhIiMj2bBhAzNmzOCpp54iT57M+hg3uRkVwGz2+eefExERAUBMTAzt27e3OJGIiEj2+/PxcM2aNbRr187iRJ5FS8DZrH379jgcDurWrUvHjh2ZOXOmloRFRMRjpKWl8dRTT9GxY0fq1avHvn37VP4soAmgRdLS0pg3bx6zZs2idevWxMTEULZsWatjiYiIZJlff/2V8PBwtmzZwuzZs5k6daqWfC2iAmgxnfUkIiKe4JNPPiEyMpL8+fOzZs0aAgMDrY7k0bQEbLHAwEAcDgf+/v507tyZadOmkZqaanUsERGRTJGamsrUqVPp3LkzjRo1wuFwqPzlAJoA5hBOp5MFCxYwffp0mjVrRmxsrN78UkREcrWff/6ZsLAwdu7cyTPPPMPjjz+Ol5dmTzmBCmAOo88+FBERd7Bu3Tr69+9PoUKFiIuLo3nz5lZHkj9RDc9hWrRogcPhoFmzZgQFBfH4449z6dIlq2OJiIhkyKVLl3jssccICgqiRYsWJCUlqfzlQJoA5lDGGF566SWmTJlCo0aNiIuLo1KlSlbHEhERuaGDBw8SGhrK3r17ee6555gwYQI2m83qWHIdmgDmUDabjYkTJ7J161Z+++03fH19ee+996yOJSIicl3//Oc/8fPz49ChQ2zdupWJEyeq/OVgKoA5XJMmTUhKSqJNmzb06tWL8ePHk5KSYnUsERERAC5evMj48eN5+OGHadu2LUlJSTRp0sTqWHILWgLOJYwxLF68mMcee4wGDRoQHx9PlSpVrI4lIiIe7D//+Q/BwcH8+9//5vnnn2fMmDGa+uUSmgDmEjabjXHjxrF9+3ZOnDiBn58fb7/9ttWxRETEQ7399tv4+flx8uRJtm/fztixY1X+chEVwFymUaNGJCYm0qlTJx555BFGjx7NhQsXrI4lIiIe4sKFC4waNYpHHnmEzp07k5iYSMOGDa2OJbdJS8C5lDGGV155hQkTJlC7dm3sdjvVq1e3OpaIiLix77//nuDgYA4cOMDLL7/M8OHDNfXLpTQBzKVsNhsjR45k586dnDt3Dn9/f2JjY62OJSIibio2NhZ/f3/OnTvHzp07GTFihMpfLqYCmMv5+vqyd+9eevToQXh4OMOGDSM5OdnqWCIi4iaSk5MZOnQo4eHh9OjRg7179+Lr62t1LLlLWgJ2E8YY3nzzTcaMGUP16tWx2+3UqlXL6lgiIpKLHThwgODgYP7v//6PxYsXM2jQIE393IQmgG7CZrMxePBgEhISuHTpEg0bNmTVqlVWxxIRkVxq1apVNGrUiLS0NHbv3s3gwYNV/tyICqCbqVu3Lnv27OGRRx4hKiqKgQMHcu7cOatjiYhILnHu3DkGDhxIVFQUwcHBJCQkULduXatjSSbTErAbW7lyJaNGjcLb2xu73U6dOnWsjiQiIjnYV199RXBwMD/99BPLli2jf//+VkeSLKIJoBuLiooiISEBLy8vAgICePPNN1HfFxGRvzLG8MYbb9C4cWPy5MnDnj17VP7cnAqgm/Px8WHXrl1EREQwePBg+vXrx9mzZ62OJSIiOcSZM2fo168fQ4YMITIykt27d1O7dm2rY0kW0xKwB1mzZg3Dhw+nbNmy2O12GjRoYHUkERGx0L59+wgODubXX3/l1VdfJTw83OpIkk00AfQg4eHh7N27l4IFC9KkSRNeffVVLQmLiHigK58m1aRJEwoWLMjevXtV/jyMCqCHqVGjBjt37mTQoEGMGDGCsLAwTp8+bXUsERHJJqdPnyY0NJSRI0cyePBgdu7cSY0aNayOJdlMS8AezG63M3ToUB544AHsdjv+/v5WRxIRkSy0d+9eQkJCOHr0KMuXL+eRRx6xOpJYRBNADxYcHExiYiLFihWjWbNm/P3vf9eSsIiIGzLGsHjxYpo3b06xYsVITExU+fNwKoAermrVqmzbto0RI0YwduxY+vbty6lTp6yOJSIimeTkyZP06dOHcePGMXLkSLZt20bVqlWtjiUW0xKwXPXuu+8yaNAgihUrRnx8PI0bN7Y6koiI3IXdu3cTEhLCqVOneOutt+jVq5fVkSSH0ARQrnr44YdJSkriwQcfpGXLlrz00ktaEhYRyYWMMbz44ou0aNGCUqVKkZSUpPIn6agASjre3t5s2bKFcePGMXHiRHr27MmJEyesjiUiIhl04sQJevbsyaRJk3j00UfZvHkz3t7eVseSHEZLwHJDH3zwAQMGDKBQoULExcXRvHlzqyOJiMhNbN++ndDQUM6dO8fKlSsJCgqyOpLkUJoAyg11794dh8NBhQoVaN26NQsWLMDpdFodS0RE/sLpdPLcc8/RunVrKlasiMPhUPmTm1IBlJuqUKECmzZt4vHHH2fKlCkEBQVx9OhRq2OJiMhlR48eJSgoiCeeeILJkyezceNGKlSoYHUsyeG0BCwZtn79evr160f+/PmJi4ujVatWVkcSEfFomzdvJiwsjJSUFKKjo+nUqZPVkSSX0ARQMqxz5844HA6qVatGmzZteOaZZ7QkLCJigbS0NObOnUvbtm2pXr06+/btU/mT26IJoNy21NRU5syZw9y5c+nQoQOrV6+mVKlSVscSEfEIhw8fJjIyks8//5wZM2YwY8YM8ubNa3UsyWVUAOWOffbZZ0RGRmKz2YiJiaFdu3ZWRxIRcWsbNmwgIiICYwwxMTG0b9/e6kiSS2kJWO5Yhw4dcDgc+Pj40KFDB2bNmkVaWprVsURE3E5aWhozZ86kQ4cO1KlTB4fDofInd0UTQLlraWlpzJs3j1mzZhEYGEhMTAxlypSxOpaIiFv49ddfiYiIYPPmzcyaNYtp06aRJ08eq2NJLqcCKJlm06ZNhIeHk5qaSnR0NA899JDVkUREcrV//etfREZGki9fPtasWUNgYKDVkcRNaAlYMk2bNm1wOBz4+fnRuXNnnnzySVJTU62OJSKS66SmpjJt2jQ6deqEv78/DodD5U8ylSaAkumcTicLFixg+vTpNG/enDVr1lC+fHmrY4mI5Aq//PILYWFh7Nixg7lz5zJ58mS8vDSvkcylAihZZuvWrYSFhZGcnMyqVavo2rWr1ZFERHK0jz76iP79+1OwYEHi4uJo0aKF1ZHETelPCskyLVu2JCkpiaZNm9KtWzcmT57MpUuXrI4lIpLjXLp0icmTJ9OtWzeaNWuGw+FQ+ZMspQmgZDmn08mLL77I1KlTCQgIIC4ujooVK1odS0QkR/jpp58IDQ1lz549PPvss0ycOBGbzWZ1LHFzmgBKlvPy8uKxxx5jy5Yt/Prrr/j6+vL+++9bHUtExHLvvfcefn5+/Pbbb2zZsoVJkyap/Em2UAGUbNO0aVOSkpIIDAykZ8+eTJgwgZSUFKtjiYhku5SUFMaPH0+vXr0IDAy8+nIZkeyiJWDJdsYYFi9ezGOPPYavry/x8fFUrlzZ6lgiItniP//5DyEhIezbt4/nn3+esWPHauon2U4TQMl2NpuNcePGsX37do4fP46fnx9r1661OpaISJZ755138PPz48SJE2zfvp1x48ap/IklVADFMo0aNSIxMZGOHTvSp08fxo4dy4ULF6yOJSKS6S5cuMCYMWPo27cvnTp1IjExkUaNGlkdSzyYloDFcsYYXnnlFSZMmICPjw92u51q1apZHUtEJFN8//33hISE8PXXX/PSSy8xYsQITf3EcpoAiuVsNhsjR45k586dnD17Fn9/f+Lj462OJSJy1+Li4mjYsCFnz55l586djBw5UuVPcgQVQMkxfH192bt3L0FBQYSGhjJ8+HCSk5OtjiUictuSk5MZPnw4YWFhdO/enb179+Lr62t1LJGrtAQsOY4xhuXLlzNu3Dhq1KiB3W6nZs2aVscSEcmQb775huDgYL7//nsWL17M4MGDNfWTHEcTQMlxbDYbQ4cOZffu3aSkpNCwYUOio6OtjiUickurV6+mUaNGXLp0id27dzNkyBCVP8mRVAAlx6pXrx4JCQn06dOHfv36MWjQIM6fP291LBGRa5w7d45BgwbRv39/+vbty549e6hXr57VsURuSEvAkiusWLGC0aNH4+3tjd1up06dOlZHEhEBYP/+/QQHB3Pw4EGWLl1KVFSU1ZFEbkkTQMkVBgwYQEJCAjabjYCAAN566y30t4uIWMkYw5tvvklAQABeXl4kJCSo/EmuoQIouYaPjw+7d+8mPDycQYMGERUVxdmzZ62OJSIe6OzZs/Tv35/BgwcTERHBrl278PHxsTqWSIZpCVhypZiYGIYPH0758uWx2+3Ur1/f6kgi4iG+/PJLHnnkEX799VdeffVVwsPDrY4kcts0AZRcKSIigsTERO655x6aNGnCa6+9piVhEclSxhheffVVGjduTMGCBdm7d6/Kn+RaKoCSa9WoUYMdO3YwYMAAhg8fTnh4OKdPn7Y6loi4odOnTxMWFsaIESMYNGgQO3fupEaNGlbHErljWgIWt2C32xkyZAilSpXCbrfj5+dndSQRcROJiYmEhIRw+PBhli9fTnBwsNWRRO6aJoDiFoKDg0lMTKRIkSI0bdqUJUuWaElYRO6KMYa///3vNGvWjKJFi5KUlKTyJ25DBVDcRrVq1di+fTvDhw9nzJgxBAcHc+rUKatjiUgudOrUKR555BHGjh3L8OHD2bZtG1WrVrU6lkim0RKwuKW1a9cyaNAgihcvTnx8PAEBAVZHEpFcYvfu3YSEhHDq1CnefPNNHn74YasjiWQ6TQDFLfXu3ZukpCQeeOABWrRowcsvv6wlYRG5KWMML730Ei1btuTBBx8kKSlJ5U/clgqguK3KlSuzZcsWxo4dy4QJE+jVqxcnTpywOpaI5EAnTpygV69eTJw4kXHjxrFlyxa8vb2tjiWSZbQELB7hgw8+ICoqisKFCxMXF0ezZs2sjiQiOcSOHTsICQnh3LlzrFixgu7du1sdSSTLaQIoHqF79+44HA7Kly9P69atWbhwIU6n0+pYImIhp9PJggULaNWqFRUqVMDhcKj8icdQARSPUbFiRTZt2sSkSZOYPHky3bt359ixY1bHEhELHDt2jKCgIKZMmcLjjz/Opk2bqFChgtWxRLKNloDFI3388cf079+fAgUKEBsbS6tWrayOJCLZZMuWLYSFhXHx4kVWr15N586drY4kku00ARSP1KVLFxwOB1WrVqVt27bMmzdPS8Iibs7pdPLMM8/Qpk0bqlatisPhUPkTj6UCKB6rXLlyfP7550ydOpXp06fTpUsXjhw5YnUsEckChw8fpnPnzsyYMYNp06bx+eefU65cOatjiVhGS8AiwKeffkpkZCR58uRhzZo1tGnTxupIIpJJNm7cSHh4OMYYoqOj6dChg9WRRCynCaAI0LFjRxwOB7Vq1aJ9+/bMnj2btLQ0q2OJyF1IS0tj9uzZdOjQAR8fHxwOh8qfyGWaAIr8SVpaGs888wyzZ8+mTZs2REdHU6ZMGatjicht+u2334iIiOCLL75g5syZPPnkk+TJk8fqWCI5hgqgyHVs2rSJ8PBw0tLSiI6OpmPHjlZHEpEM0ks6RG5NS8Ai19GmTRscDge+vr506tSJ6dOnk5qaanUsEbmJ1NRUpk+fTqdOnfD19cXhcKj8idyAJoAiN+F0OnnuueeYMWMGzZs3JzY2VmcOiuRAv/zyC+Hh4Wzfvp25c+cyefJkvLw04xC5ERVAkQzYunUroaGhXLx4kVWrVtGlSxerI4nIZR999BH9+/enYMGCxMbG0rJlS6sjieR4+vNIJANatmyJw+GgcePGdO3alSlTpnDp0iWrY4l4tEuXLjF58mS6detG06ZNSUpKUvkTySBNAEVug9Pp5MUXX2Tq1Kk0btyY2NhYKlasaHUsEY/z3//+l9DQUBISEpg/fz4TJ07Ukq/IbVABFLkDO3bsIDQ0lDNnzrBy5Uq6d+9udSQRj/H+++8zYMAAihQpQlxcHE2bNrU6kkiuoz+XRO5As2bNSEpKolWrVvTo0YNJkyaRkpJidSwRt5aSksLEiRPp2bMnrVu3JikpSeVP5A5pAihyF4wx/O1vf+Pxxx/Hz8+PuLg4KleubHUsEbfz448/EhISgsPhYOHChYwbNw6bzWZ1LJFcSxNAkbtgs9l49NFH2bZtG0ePHsXPz4+1a9daHUvEraxduxY/Pz+OHTvGtm3bePTRR1X+RO6SCqBIJggICCAxMZEOHTrQp08fxo4dy8WLF62OJZKrXbhwgbFjx9KnTx86duxIUlISAQEBVscScQtaAhbJRMYYli5dysSJE6lbty7x8fFUq1bN6lgiuc4PP/xAcHAw+/fv56WXXmLkyJGa+olkIk0ARTKRzWZj9OjR7Ny5k9OnT+Pv74/dbrc6lkiuEh8fj7+/P2fOnGHnzp2MGjVK5U8kk6kAimQBPz8/9u7dS7du3QgJCWHEiBEkJydbHUskR0tOTmbEiBGEhoYSFBREYmIifn5+VscScUtaAhbJQsYYli9fzrhx46hRowZ2u52aNWtaHUskx/n2228JDg7mu+++429/+xtDhgzR1E8kC2kCKJKFbDYbQ4cOZdeuXVy8eJGGDRsSExNjdSyRHCU6OpqGDRuSkpLC7t27GTp0qMqfSBZTARTJBvXr12fPnj307t2byMhIhgwZwvnz562OJWKp8+fPM3jwYPr160efPn1ISEigXr16VscS8QhaAhbJRsYYVqxYwejRo6lSpQp2ux0fHx+rY4lku/379xMcHMzBgwdZsmQJAwYMsDqSiEfRBFAkG9lsNgYOHMiePXswxtCoUSNWrFhhdSyRbGOM4a233iIgIACbzUZCQoLKn4gFVABFLODj40NCQgJhYWEMHDiQqKgozp49a3UskSx19uxZoqKiGDRoEOHh4ezevVsTcBGLaAlYxGLR0dGMGDGCChUqYLfb9RoocUtffvklwcHB/PLLL7z66qtERERYHUnEo2kCKGKxyMhI9uzZQ/78+WncuDGvv/46+rtM3IUxhtdee40mTZpQoEAB9u7dq/InkgOoAIrkALVq1WLnzp1ERUUxbNgwwsPDOX36tNWxRO7K6dOnCQ8PZ/jw4QwYMICdO3fqfTBFcggtAYvkMHFxcQwbNoxSpUpht9v1SQiSKyUlJREcHMzhw4d5/fXXCQkJsTqSiPyJJoAiOUxoaCiJiYkUKVKEpk2bsnTpUi0JS65hjGHJkiU0bdqUIkWKkJiYqPInkgOpAIrkQNWqVWP79u0MGzaM0aNHExwczO+//251LJGbOnXqFMHBwYwZM4bhw4ezfft2qlWrZnUsEbkOLQGL5HDvvPMOgwcPpnjx4sTHxxMQEGB1JJFrJCQkEBISwokTJ3jzzTfp3bu31ZFE5CY0ARTJ4fr06UNSUhIlS5akRYsWLFq0SEvCkmMYY3j55Zdp0aIFJUuWJCkpSeVPJBdQARTJBSpXrszWrVsZM2YM48eP5+GHH+bEiRNWxxIPd+LECXr16sWECRMYO3YsW7dupXLlylbHEpEM0BKwSC7z/vvvM2DAAAoXLkx8fDxNmza1OpJ4oB07dhAaGsqZM2dYuXIl3bt3tzqSiNwGTQBFcpkePXqQlJREuXLlaNWqFc8//zxOp9PqWOIhnE4nCxcupHXr1pQrVw6Hw6HyJ5ILqQCK5EKVKlXiiy++YOLEiTz++OP06NGDY8eOWR1L3NyxY8fo3r07kydPZuLEiXzxxRdUrFjR6lgicge0BCySy3300Uf079+fggULEhsbS8uWLa2OJG5oy5YthIWFcfHiRVatWkWXLl2sjiQid0ETQJFcrmvXrjgcDry9vWnTpg3z58/XkrBkGqfTybx582jbti1VqlTB4XCo/Im4ARVAETdQvnx5Nm7cyBNPPMGTTz5Jly5dOHLkiNWxJJc7cuQIXbp0Yfr06UydOpUNGzZQrlw5q2OJSCbQErCIm/n000+JiIggb968rFmzhjZt2lgdSXKhjRs3Eh4ejtPpJDo6mo4dO1odSUQykSaAIm6mY8eO7Nu3j1q1atG+fXvmzJlDWlqa1bEkl0hLS2P27Nl06NCB2rVr43A4VP5E3JAmgCJuKi0tjblz5zJ79mzatm1LTEwMpUuXtjqW5GC//fYbkZGRbNq0iZkzZ/Lkk0+SJ08eq2OJSBZQARRxc39eyouJiaFDhw5WR5Ic6NNPPyUyMhIvLy9iY2P10gERN6clYBE317ZtWxwOBw0aNOChhx5ixowZpKamWh1LcojU1FSmT59Op06d8PX1Zd++fSp/Ih5AE0ARD+F0Onn22WeZMWMGLVu2ZM2aNTqj08P973//IywsjG3btvH000/zxBNP4OWluYCIJ1ABFPEwf35D39WrV9O5c2erI4kFPv74Y/r370+BAgWIjY2lVatWVkcSkWykP/VEPEyrVq1wOBwEBATQpUsXnnjiCS5dumR1LMkmly5dYsqUKXTt2pXGjRvjcDhU/kQ8kCaAIh7K6XTywgsvMHXqVJo0aUJcXBwVKlSwOpZkof/+97+EhYWxe/du5s2bx6RJk7TkK+KhVABFPNyOHTsICQnh3LlzrFixgu7du1sdSbLA+++/z4ABAyhcuDBxcXE0a9bM6kgiYiH96Sfi4Zo1a4bD4aBly5b06NGDSZMmkZKSYnUsySQpKSlMnDiRnj170qpVK5KSklT+REQTQBFxMcbw8ssvM2XKFPz8/IiLi6Ny5cpWx5K78OOPPxIaGkpSUhILFizg0UcfxWazWR1LRHIATQBFBACbzcaECRPYunUrR44cwc/Pj3fffdfqWHKH1q5di5+fH0ePHmXbtm2MHz9e5U9ErlIBFJF0GjduTFJSEu3bt6d3796MGzeOixcvWh1LMujixYuMHTuWPn360KFDBxITEwkICLA6lojkMFoCFpHrMsawZMkSJk2aRL169YiPj6dq1apWx5Kb+OGHHwgJCeGrr77ixRdfZNSoUZr6ich1aQIoItdls9kYM2YMO3bs4NSpU/j5+WG3262OJTdgt9vx9/fn9OnT7Ny5k9GjR6v8icgNqQCKyE35+/uTmJhI165dCQkJYeTIkVy4cMHqWHJZcnIyI0aMICQkhG7durF37178/PysjiUiOZyWgEUkQ4wxvP7664wbN45atWpht9upUaOG1bE82rfffktwcDDfffcdixYtYujQoZr6iUiGaAIoIhlis9kYNmwYu3fvJjk5GX9/f2JiYqyO5bGio6Np2LAhFy9eZNeuXQwbNkzlT0QyTAVQRG5L/fr12bt3Lw8//DCRkZEMGTKE8+fPWx3LY5w/f57BgwfTr18/evfuzZ49e6hfv77VsUQkl9ESsIjcEWMMb731FmPGjKFKlSrY7XZ8fHysjuXWvv76a4KDg/nPf/7DkiVLGDBggKZ+InJHNAEUkTtis9kYNGgQCQkJGGMICAhgxYoVVsdyWytWrKBRo0YYY0hISGDgwIEqfyJyx1QAReSu1KlTh927dxMSEsLAgQOJiori7NmzVsdyG2fPniUqKoqBAwcSFhZGQkICderUsTqWiORyWgIWkUyzevVqRo4cSYUKFbDb7dSrV8/qSLnav//9b4KDg/n5559ZtmwZ/fr1szqSiLgJTQBFJNP069ePPXv2kC9fPho3bszy5cvR35i378pb7jRu3Jh8+fKxZ88elT8RyVQqgCKSqWrVqsWuXbvo378/Q4cOJSIigjNnzlgdK9c4ffo04eHhDBs2jKioKHbt2kWtWrWsjiUibkZLwCKSZeLi4hg6dChlypTBbrfj6+trdaQcLSkpieDgYA4fPsxrr71GaGio1ZFExE1pAigiWSY0NJTExETuu+8+mjZtytKlS7UkfB3GGJYuXUrTpk0pXLgwiYmJKn8ikqVUAEUkS1WvXp3t27czZMgQRo8eTXBwML///rvVsXKM33//neDgYEaPHs2wYcPYvn071apVszqWiLg5LQGLSLZ5++23GTx4MCVLliQ+Pp5GjRpZHclSCQkJhISEcOLECd544w369OljdSQR8RCaAIpItunbty9JSUkUL16c5s2bs2jRIo9cEjbGsGjRIlq0aEHJkiVJTExU+RORbKUCKCLZqkqVKmzbto3Ro0czfvx4evfuzcmTJ62OlW1OnDjBww8/zPjx4xk9ejRbt26lSpUqVscSEQ+jJWARscx7773HgAEDKFq0KPHx8TRp0sTqSFlq586dhISEcObMGVasWEGPHj2sjiQiHkoTQBGxTM+ePXE4HJQpU4aWLVvywgsv4HQ6rY6V6ZxOJ88//zytWrWibNmyJCUlqfyJiKVUAEXEUpUqVWLz5s1MmDCBxx57jB49enD8+HGrY2WaY8eO0aNHDx5//HEmTpzI5s2bqVSpktWxRMTDaQlYRHKMdevWERUVRcGCBYmLi6NFixZWR7orW7duJSwsjOTkZFatWkXXrl2tjiQiAmgCKCI5SLdu3XA4HHh7exMYGMj8+fNz5ZKw0+lk/vz5tGnTBm9vbxwOh8qfiOQoKoAikqOUL1+ejRs3MnnyZKZNm0bXrl05cuSI1bEy7MiRI3Tp0oUnn3ySKVOmsHHjRsqXL291LBGRdLQELCI51ieffEK/fv3ImzcvsbGxBAYGWh3ppjZt2kR4eDipqalER0fz0EMPWR1JROS6NAEUkRyrU6dOOBwOatasSbt27ZgzZw5paWlWx7pGWloac+bMoX379tSqVYt9+/ap/IlIjqYJoIjkeGlpaTz99NPMmTOHdu3aER0dTenSpe9ijwY4A6QA+YHCgO2O9nTo0CEiIiLYuHEjTz31FDNmzCBPnjx3kU1EJOupAIpIrrFhwwYiIiIwxhATE0P79u1v49ZfAWuAXcAe4PSfflYEaAQ0AcKBuhna42effUZERAReXl7ExMTQrl2728gjImIdLQGLSK7Rrl07HA4H9erVo2PHjjz11FOkpqbe4lbrgJZAPWAhsJH05Y/Llzde/nm9y9t/dMM9pqamMmPGDB566CEaNGiAw+FQ+RORXEUTQBHJddLS0nj22Wd56qmnaNmyJbGxsZQtW/YvWx0HxgKxuP7WvZ23k7myfTiwGCh+9Sf/+9//CA8PZ+vWrcyZM4epU6fi5aW/pUUkd1EBFJFca/PmzYSFhZGSksLq1avp3Lnz5Z98CXTEVQLv5qSRPEAJ4DOgHuvXr6dfv37kz5+f2NhYWrdufXcPQETEIvqzVURyrdatW+NwOGjUqBFdunRh6tSpXLq0F2jF3Zc/Lt/+OMa05KWXBtOlSxcCAgJwOBwqfyKSq2kCKCK5ntPpZOHChbzwwjS++SYP99/vxGbLvLeLSU2F48chPn4mY8Y8pSVfEcn19L+YiFxj3rx5/POf/7zm+hUrVmCz2dizZ0/2h7oJLy8vpkyZwv797ShS5FKmlj+AvHnhwQe9GDfu+3Tlb/HixVSrVo38+fNjs9k4deoUAwYMwNvb+7bvo02bNrRp0ybzQouI3IQKoIhc40YFMGdbxwMPfEbevFmzd5vNiettZFxnBzscDsaNG0fbtm3ZsGEDO3bsoHDhwsyYMYN33333tve/dOlSli5dmrmhRURuIIv+qxQRyW7zuf2zff9w6RLYbNyiQOa5fD9d2b9/PwBDhw6lcePGV7eoWrXqHd2/j4/PHd1OROROaAIo4gZmzZqFzWYjKSmJ3r17U6RIEYoWLUpkZCRHjx4FYPDgwRQvXpzz589fc/t27dpRp04dAGw2G+fOnWPlypXYbDZsNts1S5Nnzpxh5MiRlCxZkhIlStC7d29+/fXXdNs4nU4WLFhArVq1KFCgAA8++CD9+/fnl19+SbddmzZtqFu3LgkJCbRq1Yp7772XKlWq8Oyzz+J0ZrTMfQVsw9vbSVAQvPsu1K8P99wDVarA3/6WfutNm1xlb/VqmDQJypWDAgXghx9cP3/zTWjQwHX74sXh4YfhwAFwnRSylTZtAoiMjASgSZMm2Gw2BgwYAHDdJWCn08nixYvx9fWlYMGCFCtWjKZNm/L++++nex7++jynpKQwd+7cq8/hAw88wMCBA6/+Tq/w9vYmKCiI9evX4+/vT8GCBalVqxZvvvnmNc/U//73P4YNG0aFChXInz8/ZcuWpW/fvhw+fJizZ89SrFgxhg8ffs3tDh48SJ48eVi4cOHNfxUikjsYEcn1Zs6caQBTqVIl8/jjj5tPPvnEvPjii6ZQoULGz8/PpKSkmH379hnAvP766+luu3//fgOYJUuWGGOM2bFjhylYsKDp2rWr2bFjh9mxY4fZv3+/McaYt956ywCmSpUqZuzYseaTTz4xy5cvN/fff79p27Ztuv0OGzbMAGbMmDFm/fr15pVXXjEPPPCAqVChgjl69OjV7QIDA02JEiVM9erVzSuvvGI+/fRTM2rUKAOYlStXZvAZmGqMyWsqVcKUK4epWBHz5puYjz7CRERgALNwIcYY19fGja7rypXD9O2Lef99zIcfYo4fx8yb5/pZWBhm3TrMqlWYKlUwRYtivvsOY0xes3//UDN9+nQDmLfeesvs2LHD/PDDD8YYY6KiokylSpXSpevXr5+x2WxmyJAh5r333jMff/yxeeaZZ8yiRYvSPQ+BgYFXL6elpZnOnTubQoUKmdmzZ5tPP/3ULF++3JQrV874+PiY8+fPX922UqVKpnz58sbHx8esWrXKfPLJJ+aRRx4xgPniiy+ubvfLL7+YMmXKmJIlS5oXX3zRfPbZZyY+Pt4MGjTIHDhwwBhjzIQJE0yhQoXMqVOn0j2Gxx9/3Nxzzz3m2LFjGfydiEhOpgIo4gauFMAJEyakuz4mJsYAJjo62hjjKhm+vr7pthk5cqQpUqSIOXPmzNXrChUqZKKioq65nysFcNSoUemuX7BggQHMb7/9Zowx5sCBA9fdbteuXQYw06ZNu3pdYGCgAcyuXbvSbevj42M6deqUwWegnTEGU6kSxmbDOBx/lD1jMB07YooUwZw7l74Atm6dfruTJzEFC2K6dk1//X//iylQABMejjHGZoxpf/W5SEhISJfkrwVw8+bNBjBPPvnkTR/BXwtgbGysAcw777yTbruEhAQDmKVLl169rlKlSuaee+4xP/3009XrkpOTTfHixc3w4cOvXjdo0CCTL18+8/XXX98wx//93/8ZLy8v89JLL6XbV4kSJczAgQNv+hhEJPfQErCIG4mIiEh3OTg4mLx587Jx40YAHn30URwOB9u2bQPg9OnTrF69mqioKO67774M30+PHj3SXa5fvz4AP/30E8DV+7uyLHpF48aNqV27Np9//nm660uXLp3udXRX9nllfzdncH22r0udOq7l2z8LD4fTpyExMf31ffqkv7xjByQnw19iU6ECtGsHrtgGSLj8/dY+/vhjAEaPHp2h7a/48MMPKVasGN27dyc1NfXql6+vL6VLl2bTpk3ptvf19aVixYpXL99zzz3UqFEj3XP48ccf07ZtW2rXrn3D+61SpQpBQUEsXboUc/ldwtasWcPx48cZM2bMbT0GEcm5VABF3Ejp0qXTXc6bNy8lSpTg+PHjAPTs2RNvb2+WLFkCuN7W5dy5c7ddTkqUKJHucoECBQBITk4GuHp/ZcqUuea2ZcuWvfrzG+3vyj6v7O/mzvDnz/b9y1OQ7rq/3C1/jXfl59eJTdmyf779aeBiBrLB0aNHyZMnzzW/m1s5fPgwp06dIn/+/OTLly/d16FDhzh27Fi67TPyHB49epTy5cvf8r4fffRRvv/+ez799FMAlixZQrNmzfD397+txyAiOZfOAhZxI4cOHaJcuXJXL6empnL8+PGr5cDLy4vRo0czbdo0XnjhBZYuXUr79u2pWbNmpua4cn+//fbbNYXj119/pWTJkpl4bynpLh06dO0WV677a0ey2dJfvvLz3367dh+//grpY6dmKN0DDzxAWloahw4dum4hvpErJ9isX7/+uj8vXLhwhvf15yx/PQnnetq1a0fdunX5+9//zn333UdiYiLR0dG3fX8iknNpAijiRmJiYtJdttvtpKampju7dMiQIeTPn5+IiAi+/fbb6y7rZXz6dn3t2rUDuKY0JCQkcODAAdq3b3/H+75W/nSX9u+HffvSb7FmDRQuDLcaYDVrBgULwl+7zi+/wIYNkD52xv5+7tKlCwDLli3L0PZXBAUFcfz4cdLS0mjUqNE1X3dS2rt06cLGjRv59ttvb7ntuHHjWLduHVOnTqVUqVI88sgjt31/IpJzaQIo4kbWrl1L3rx56dixI/v372fGjBk0aNCA4ODgq9sUK1aM/v37s2zZMipVqkT37t2v2U+9evXYtGkTH3zwAWXKlKFw4cK3VThq1qzJsGHDWLx4MV5eXnTp0oWDBw8yY8YMKlSowIQJEzLl8boUBopwZRm4bFno0QNmzXIt5UZHw6efwnPPwb333nxPxYrBjBkwbRr07w9hYa5l39mzXW8JM3PmlS2LAAUylK5Vq1b069ePuXPncvjwYYKCgihQoABJSUnce++9jB079rq3Cw0NJSYmhq5du/Loo4/SuHFj8uXLxy+//MLGjRvp2bMnDz/8cIYyXDFnzhw+/vhjWrduzbRp06hXrx6nTp1i/fr1TJw4kVq1al3dNjIykqlTp7J582amT59O/vz5b7JnEcltVABF3MjatWuZNWsWy5Ytw2az0b17d15++eVrDt4hISEsW7aMkSNHXvdzbRctWsTo0aMJDQ3l/PnzBAYGXnPSwa0sW7aMqlWr8sYbb7BkyRKKFi1K586dmT9//nVfr3bnbEAjYAMAvr4wcKCrrH3/vasQvvgiZLRzTp0KDz7oeu/A+HjXRLBNG5g3D6pXv3J/AZe/Z8yKFSvw9/fnjTfeYMWKFRQsWBAfHx+mTZt2w9vkyZOH999/n0WLFrF69Wrmz59P3rx5KV++PIGBgdSrVy/D939FuXLl2L17NzNnzuTZZ5/l+PHjPPDAA7Rs2ZLixYun27ZgwYJ0796d6OhoRowYcdv3JSI5m81cOc1LRHKtWbNmMXv2bI4ePZqh19dNmjSJZcuW8fPPP2dyGbPKNGAh3t6p1K0LH36YlfeVF5gMPJOVd2K5lJQUvL29admyJXa73eo4IpLJNAEU8SA7d+7ku+++Y+nSpQwfPtxNyh9AOK6PaMsOqZfvzz0dPXqUb7/9lrfeeovDhw/zxBNPWB1JRLKACqCIB2nWrBn33nsvQUFBzJ071+o4GZaWlsbNFitsttrkydMC2JbFSfIAzYA6WXw/1lm3bh0DBw6kTJkyLF26VG/9IuKmtAQsIjmet7f3Td8U2vUaxceBoGxIsw7omg33IyKSdTQBFJEc74MPPuDixRu/8bLrPfFqAmGAHUjLghR5gBBU/kTEHWgCKCJu5Djgc/l7ZpbAPEAJ4ABQ/BbbiojkfHojaBFxIyWAz4BCuEpbZshzeX+fofInIu5CBVBE3Ew9YCuuMni3JfDK5G/r5f2KiLgHFUARcUP1cC3Xhly+fLtF8Mr2oZf3o/InIu5FBVBE3FRxIAbXWbvNLl+Xlxt/goeNP86La3b5dtFo2VdE3JFOAhERD7EfWAPsAhK48tnBLkVwfbxbE1xv8uy+7/MnIgIqgCLikQxwFkgB8gP3cTuf7SsiktupAIqIiIh4GL0GUERERMTDqACKiIiIeBgVQBEREREPowIoIiIi4mFUAEVEREQ8jAqgiIiIiIdRARQRERHxMCqAIiIiIh5GBVBERETEw6gAioiIiHgYFUARERERD6MCKCIiIuJhVABFREREPIwKoIiIiIiHUQEUERER8TAqgCIiIiIeRgVQRERExMOoAIqIiIh4GBVAEREREQ+jAigiIiLiYVQARURERDyMCqCIiIiIh1EBFBEREfEwKoAiIiIiHkYFUERERMTDqACKiIiIeBgVQBEREREPowIoIiIi4mFUAEVEREQ8jAqgiIiIiIdRARQRERHxMCqAIiIiIh5GBVBERETEw/w/UMWHCUIKUroAAAAASUVORK5CYII=",
"text/plain": [
"<Figure size 800x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Construct the graph \n",
"nodes = ['took_a_course', 'python_proficiency', 'earnings', 'age']\n",
"edges = [\n",
" ('took_a_course', 'earnings'),\n",
" ('python_proficiency','took_a_course'),\n",
" ('age', 'earnings'),\n",
" ('python_proficiency', 'earnings')\n",
"]\n",
"\n",
"# Generate the GML graph\n",
"gml_string = 'graph [directed 1\\n'\n",
"\n",
"for node in nodes:\n",
" gml_string += f'\\tnode [id \"{node}\" label \"{node}\"]\\n'\n",
"\n",
"for edge in edges:\n",
" gml_string += f'\\tedge [source \"{edge[0]}\" target \"{edge[1]}\"]\\n'\n",
" \n",
"gml_string += ']'\n",
"\n",
"# Instantiate the CausalModel \n",
"model = CausalModel(\n",
" data=earnings_interaction_train,\n",
" treatment='took_a_course',\n",
" outcome='earnings',\n",
" effect_modifiers='age',\n",
" graph=gml_string\n",
")\n",
"\n",
"model.view_model()"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Estimand type: nonparametric-ate\n",
"\n",
"### Estimand : 1\n",
"Estimand name: backdoor\n",
"Estimand expression:\n",
" d \n",
"────────────────(E[earnings|python_proficiency])\n",
"d[took_a_course] \n",
"Estimand assumption 1, Unconfoundedness: If U→{took_a_course} and U→earnings then P(earnings|took_a_course,python_proficiency,U) = P(earnings|took_a_course,python_proficiency)\n",
"\n",
"### Estimand : 2\n",
"Estimand name: iv\n",
"No such variable(s) found!\n",
"\n",
"### Estimand : 3\n",
"Estimand name: frontdoor\n",
"No such variable(s) found!\n",
"\n"
]
}
],
"source": [
"# Get the estimand\n",
"estimand = model.identify_effect()\n",
"\n",
"print(estimand)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[LightGBM] [Warning] Accuracy may be bad since you didn't explicitly set num_leaves OR 2^max_depth > num_leaves. (num_leaves=31).\n",
"[LightGBM] [Warning] Accuracy may be bad since you didn't explicitly set num_leaves OR 2^max_depth > num_leaves. (num_leaves=31).\n",
"[LightGBM] [Warning] Auto-choosing col-wise multi-threading, the overhead of testing was 0.000147 seconds.\n",
"You can set `force_col_wise=true` to remove the overhead.\n",
"[LightGBM] [Info] Total Bins 292\n",
"[LightGBM] [Info] Number of data points in the train set: 5000, number of used features: 4\n",
"[LightGBM] [Info] Start training from score 143134.027200\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] No further splits with positive gain, best gain: -inf\n",
"[LightGBM] [Warning] Accuracy may be bad since you didn't explicitly set num_leaves OR 2^max_depth > num_leaves. (num_leaves=31).\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().\n",
"`sparse` was renamed to `sparse_output` in version 1.2 and will be removed in 1.4. `sparse_output` is ignored unless you leave `sparse` to its default value.\n"
]
}
],
"source": [
"# Get estimate (S-Learner) with DoWhy\n",
"estimate = model.estimate_effect(\n",
" identified_estimand=estimand,\n",
" method_name='backdoor.econml.metalearners.SLearner',\n",
" target_units='ate',\n",
" method_params={\n",
" 'init_params': {\n",
" 'overall_model': LGBMRegressor(n_estimators=500, max_depth=10)\n",
" },\n",
" 'fit_params': {}\n",
" })"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"DoWhy S-Learner's CATE: 12547.068205674783\n"
]
}
],
"source": [
"s_cate = estimate.cate_estimates.mean()\n",
"print(f\"DoWhy S-Learner's CATE: {s_cate}\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "causal",
"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.0"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment