---
title: Examples
keywords: fastai
sidebar: home_sidebar
summary: "Various examples of CausalNLP on semi-simulated or real datasets."
description: "Various examples of CausalNLP on semi-simulated or real datasets."
nb_path: "nbs/99_examples.ipynb"
---
<!--
#################################################
### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
#################################################
# file to edit: nbs/99_examples.ipynb
# command to build the docs after a change: nbdev_build_docs
-->
<div class="container" id="notebook-container">
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
</div>
{% endraw %}
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="kn">from</span> <span class="nn">causalnlp</span> <span class="kn">import</span> <span class="n">CausalInferenceModel</span>
<span class="kn">from</span> <span class="nn">causalnlp</span> <span class="kn">import</span> <span class="n">Autocoder</span>
</pre></div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="What-is-the-causal-impact-of-a-positive-review-on-product-views?">What is the causal impact of a positive review on product views?<a class="anchor-link" href="#What-is-the-causal-impact-of-a-positive-review-on-product-views?"> </a></h2><p>We use a semi-simulated dataset generated from <a href="https://github.com/rpryzant/causal-text">this repo</a>, which is available in the <code>sample_data</code> folder. The reviews and product types are real, while the outcomes (e.g., 1=product clicked, 0=not clicked) are simulated.</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s1">'sample_data/music_seed50.tsv'</span><span class="p">,</span> <span class="n">sep</span><span class="o">=</span><span class="s1">'</span><span class="se">\t</span><span class="s1">'</span><span class="p">,</span> <span class="n">error_bad_lines</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
</div>
{% endraw %}
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">df</span><span class="o">.</span><span class="n">head</span><span class="p">()</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_html rendered_html output_subarea output_execute_result"><div>
<style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>index</th>
<th>id</th>
<th>rating</th>
<th>product</th>
<th>text</th>
<th>summary</th>
<th>price</th>
<th>T_true</th>
<th>C_true</th>
<th>Y_sim</th>
<th>negative</th>
<th>positive</th>
<th>T_ac</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>7</td>
<td>0001388703</td>
<td>1.0</td>
<td>mp3 music</td>
<td>buy the cd. do not buy the mp3 album. downlo...</td>
<td>Buy the CD. Do not buy the MP3.</td>
<td>13.01</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0.548733</td>
<td>0.451267</td>
<td>0</td>
</tr>
<tr>
<th>1</th>
<td>8</td>
<td>0001388703</td>
<td>5.0</td>
<td>mp3 music</td>
<td>takes me back to my childhood!</td>
<td>Love it!</td>
<td>13.01</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0.008373</td>
<td>0.991627</td>
<td>1</td>
</tr>
<tr>
<th>2</th>
<td>12</td>
<td>0001388703</td>
<td>5.0</td>
<td>audio cd</td>
<td>the passion and ingenuity of green's music is ...</td>
<td>No one like Keith Green</td>
<td>13.01</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>0.043761</td>
<td>0.956239</td>
<td>1</td>
</tr>
<tr>
<th>3</th>
<td>13</td>
<td>0001388703</td>
<td>5.0</td>
<td>mp3 music</td>
<td>keith's music is a timeless message. since hi...</td>
<td>Never Gets Old</td>
<td>13.01</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0.038876</td>
<td>0.961124</td>
<td>1</td>
</tr>
<tr>
<th>4</th>
<td>15</td>
<td>0001377647</td>
<td>5.0</td>
<td>audio cd</td>
<td>i have fallen in love with john michael talbot...</td>
<td>Talbot a masterpiece</td>
<td>18.99</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>0.019828</td>
<td>0.980172</td>
<td>1</td>
</tr>
</tbody>
</table>
</div></div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p><code>Y_sim</code> is the simulated outcome indicating whether or not the product was clicked. <code>C_true</code> is a categorical variable, where 1 is an audio CD and and 0 is something else (e.g., MP3). In this dataset, outcomes were simulated such that <code>C_true</code> is a counfounding variable for this problem.</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>The treatment is whether or not the review is positive, which affects <code>Y_sim</code>. Let's pretend we don't have a rating and need to infer this from text using the <a href="/causalnlp/autocoder.html#Autocoder"><code>Autocoder</code></a>. This can be done with:</p>
<div class="highlight"><pre><span></span><span class="n">ac</span> <span class="o">=</span> <span class="n">Autocoder</span><span class="p">()</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">ac</span><span class="o">.</span><span class="n">code_sentiment</span><span class="p">(</span><span class="n">df</span><span class="p">[</span><span class="s1">'text'</span><span class="p">]</span><span class="o">.</span><span class="n">values</span><span class="p">,</span> <span class="n">df</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="mi">16</span><span class="p">,</span> <span class="n">binarize</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">df</span><span class="p">[</span><span class="s1">'T_ac'</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="s1">'positive'</span><span class="p">]</span>
</pre></div>
<p>We've already created this as the <code>T_ac</code> column (along with the <code>positive</code> and <code>negative</code> columns), so invoking the above is not needed. Note that <code>T_ac</code> is an imperfect approximation of <code>T_true</code>. In CausalNLP, we can include the raw text as covariates to improve our estimates.</p>
<p>Let's fit the causal inference model. We will adjust for both <code>C_true</code> and the raw text of the review to minimize bias from confounding. CausalNLP supports the following metalearners: S-Learner, T-Learner, X-Learner, and R-Learner. See <a href="https://arxiv.org/abs/1706.03461">this paper</a> for more information on these. We will use the T-Learner as the metalearner here. By default, T-Learners use LightGBM classifiers with 31 leaves. Let's increase the number of leaves to 500. In practice, you can supply a learner with hyperparameters that you've tuned beforehand to accurately predict the outcome.</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="kn">from</span> <span class="nn">lightgbm</span> <span class="kn">import</span> <span class="n">LGBMClassifier</span>
<span class="kn">from</span> <span class="nn">sklearn.linear_model</span> <span class="kn">import</span> <span class="n">LogisticRegression</span><span class="p">,</span> <span class="n">LinearRegression</span>
<span class="n">cm</span> <span class="o">=</span> <span class="n">CausalInferenceModel</span><span class="p">(</span><span class="n">df</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s1">'t-learner'</span><span class="p">,</span>
<span class="n">learner</span><span class="o">=</span><span class="n">LGBMClassifier</span><span class="p">(</span><span class="n">num_leaves</span><span class="o">=</span><span class="mi">500</span><span class="p">),</span>
<span class="n">treatment_col</span><span class="o">=</span><span class="s1">'T_ac'</span><span class="p">,</span>
<span class="n">outcome_col</span><span class="o">=</span><span class="s1">'Y_sim'</span><span class="p">,</span>
<span class="n">text_col</span><span class="o">=</span><span class="s1">'text'</span><span class="p">,</span>
<span class="n">include_cols</span><span class="o">=</span><span class="p">[</span><span class="s1">'C_true'</span><span class="p">])</span>
<span class="n">cm</span><span class="o">.</span><span class="n">fit</span><span class="p">()</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_subarea output_stream output_stdout output_text">
<pre>outcome column (categorical): Y_sim
treatment column: T_ac
numerical/categorical covariates: ['C_true']
text covariate: text
preprocess time: 1.118110179901123 sec
start fitting causal inference model
time to fit causal inference model: 10.667636632919312 sec
</pre>
</div>
</div>
<div class="output_area">
<div class="output_text output_subarea output_execute_result">
<pre><causalnlp.causalinference.CausalInferenceModel at 0x7f079361b0f0></pre>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h3 id="Average-Treatment-Effect-(ATE)">Average Treatment Effect (ATE)<a class="anchor-link" href="#Average-Treatment-Effect-(ATE)"> </a></h3><p>We can calculate the overall average treatment effect (ATE) as follows:</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">cm</span><span class="o">.</span><span class="n">estimate_ate</span><span class="p">()</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_text output_subarea output_execute_result">
<pre>{'ate': 0.1309311542209525}</pre>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>The overall ATE is an increase of 13 percentage points in probability.</p>
<p>Unlike machine learning, there is no ground truth to which our estimate can be compared for causal inference on real-world datasets. Hoewver, since this is a simulated dataset, we can compare our estimate with the ground truth ATE of <code>0.1479</code> (14.79 percentage point change in outcome), and our estimate is close.</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
<span class="k">def</span> <span class="nf">ATE_adjusted</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="n">T</span><span class="p">,</span> <span class="n">Y</span><span class="p">):</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">list</span><span class="p">)</span>
<span class="k">for</span> <span class="n">c</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="n">y</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="n">T</span><span class="p">,</span> <span class="n">Y</span><span class="p">):</span>
<span class="n">x</span><span class="p">[</span><span class="n">c</span><span class="p">,</span> <span class="n">t</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
<span class="n">C0_ATE</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">])</span> <span class="o">-</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">])</span>
<span class="n">C1_ATE</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">])</span> <span class="o">-</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">])</span>
<span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">([</span><span class="n">C0_ATE</span><span class="p">,</span> <span class="n">C1_ATE</span><span class="p">])</span>
<span class="nb">print</span><span class="p">(</span><span class="n">ATE_adjusted</span><span class="p">(</span><span class="n">df</span><span class="o">.</span><span class="n">C_true</span><span class="p">,</span> <span class="n">df</span><span class="o">.</span><span class="n">T_true</span><span class="p">,</span> <span class="n">df</span><span class="o">.</span><span class="n">Y_sim</span><span class="p">))</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_subarea output_stream output_stdout output_text">
<pre>0.14785542719890196
</pre>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Such oracle estimates are not available for real-world datsets, as mentioned. For real-world scenarios, we can, at least, evaluate the robustness of the ATE estimate to various data manipuations (i.e., sensitivity analysis or refutation).</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">cm</span><span class="o">.</span><span class="n">evaluate_robustness</span><span class="p">()</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_html rendered_html output_subarea output_execute_result"><div>
<style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>Method</th>
<th>ATE</th>
<th>New ATE</th>
<th>New ATE LB</th>
<th>New ATE UB</th>
<th>Distance from Desired (should be near 0)</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>Placebo Treatment</td>
<td>0.130931</td>
<td>0.00477642</td>
<td>-0.00452705</td>
<td>0.0140799</td>
<td>0.00477642</td>
</tr>
<tr>
<th>0</th>
<td>Random Cause</td>
<td>0.130931</td>
<td>0.131122</td>
<td>0.122196</td>
<td>0.140049</td>
<td>0.000191267</td>
</tr>
<tr>
<th>0</th>
<td>Subset Data(sample size @0.8)</td>
<td>0.130931</td>
<td>0.129383</td>
<td>0.117239</td>
<td>0.141528</td>
<td>-0.0015477</td>
</tr>
<tr>
<th>0</th>
<td>Random Replace</td>
<td>0.130931</td>
<td>0.130196</td>
<td>0.121209</td>
<td>0.139184</td>
<td>-0.000734766</td>
</tr>
</tbody>
</table>
</div></div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Here, we see the distance from the desired value is near zero for each sensitivy analysis method , which is good.</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h3 id="Conditional-Average-Treatment-Effect-(CATE)">Conditional Average Treatment Effect (CATE)<a class="anchor-link" href="#Conditional-Average-Treatment-Effect-(CATE)"> </a></h3><p>We can also calculate the conditional average treatment effects (CATE). For instance, here is the treatment effect for those reviews that mention the word ``toddler.''</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">series</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="s1">'text'</span><span class="p">]</span>
<span class="n">cm</span><span class="o">.</span><span class="n">estimate_ate</span><span class="p">(</span><span class="n">df</span><span class="p">[</span><span class="s1">'text'</span><span class="p">]</span><span class="o">.</span><span class="n">str</span><span class="o">.</span><span class="n">contains</span><span class="p">(</span><span class="s1">'toddler'</span><span class="p">))</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_text output_subarea output_execute_result">
<pre>{'ate': 0.15559234254638685}</pre>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h3 id="Individualized-Treatment-Effect-(ITE)">Individualized Treatment Effect (ITE)<a class="anchor-link" href="#Individualized-Treatment-Effect-(ITE)"> </a></h3><p>We can easily predict the treatment effect for new or existing observations on a per-unit basis. We just need to make sure the DataFrame supplied as input to <a href="/causalnlp/core.causalinference.html#CausalInferenceModel.predict"><code>CausalInferenceModel.predict</code></a> contains the right columns. This can easily be checked with <a href="/causalnlp/core.causalinference.html#CausalInferenceModel.get_required_columns"><code>CausalInferenceModel.get_required_columns</code></a>:</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">cm</span><span class="o">.</span><span class="n">get_required_columns</span><span class="p">()</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_text output_subarea output_execute_result">
<pre>['T_ac', 'C_true', 'text']</pre>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">test_df</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">({</span>
<span class="s1">'T_ac'</span> <span class="p">:</span> <span class="p">[</span><span class="mi">1</span><span class="p">],</span>
<span class="s1">'C_true'</span> <span class="p">:</span> <span class="p">[</span><span class="mi">1</span><span class="p">],</span>
<span class="s1">'text'</span> <span class="p">:</span> <span class="p">[</span><span class="s1">'I love the music of Zamfir and his pan flute.'</span><span class="p">]</span>
<span class="p">})</span>
</pre></div>
</div>
</div>
</div>
</div>
{% endraw %}
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">cm</span><span class="o">.</span><span class="n">predict</span><span class="p">(</span><span class="n">test_df</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_text output_subarea output_execute_result">
<pre>array([[0.40062776]])</pre>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h3 id="Model-Interpetability">Model Interpetability<a class="anchor-link" href="#Model-Interpetability"> </a></h3><p>We can use the <code>interpret</code> method to identify the attributes most predictive of individualized treatment effects across observations. Features begnning with <code>v_</code> are word (or vocabulary) features. We see that words like "music", "cd", and "love" in addition to the categorical attribute <code>C_true</code> (the known confounder which is 1 for audio CDs) are most predictive of <em>individualized</em> causal effects.</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">cm</span><span class="o">.</span><span class="n">interpret</span><span class="p">(</span><span class="n">plot</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s1">'feature_importance'</span><span class="p">)[</span><span class="mi">1</span><span class="p">][:</span><span class="mi">10</span><span class="p">]</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_text output_subarea output_execute_result">
<pre>v_music 0.079042
v_cd 0.066838
v_album 0.055168
v_like 0.040784
v_love 0.040635
C_true 0.039949
v_just 0.035671
v_song 0.035362
v_great 0.029918
v_heard 0.028373
dtype: float64</pre>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">cm</span><span class="o">.</span><span class="n">explain</span><span class="p">(</span><span class="n">test_df</span><span class="p">,</span> <span class="n">row_num</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_png output_subarea ">
<img src="data:image/png;base64,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5J133tHzzz8f62IAAAAAACJYv3697rvvPt1www1asmSJVqxYodmzZzfpvQ888IDWrl3bxiWMLQJRAAAAAAAAUbJ48WINGjRIM2bM0G677aa3335bEydObNJ7J0yYoAULFrRxCWOLQBQAAAAAAECUbNmyRb1795YkrVy5UqWlperfv3+T3rvtttvqp59+0tatW9uyiDEVH+sCALGycuVKzZs3T4WFhRo5cqSmTp2q+Ph4lZSU6IUXXtCvv/6q6upqDRw4UFOnTlVmZqYk6b///a8WLlyooqIipaamasqUKdpuu+0kSZ9//rkWL16srVu3ql+/fjrkkEPUrVu3Op/9xBNPaMSIEdp1111rXrv33ns1efJkjRo1SvPmzdPSpUtVVlamHj166MADD1Rubm6d5fz00096/vnnddFFF9W8NmvWLB166KEaMmSIXNfV4sWL9emnn6q0tFRDhgzR1KlTlZKSEuW1CQAAAAB49NFH9dNPP+nnn3/W/Pnzteeee2rQoEE103/55Rc99dRTOvvss5WVlaXVq1frkUce0RlnnKGePXsqPj5effv21YoVKzR+/PiYfY+2REYUuqwvv/xSJ510ki644AJt2LBB7777riTJdV2NHz9eF154oS688ELFx8fr1VdflSSVl5dr3rx5OvHEEzVjxgydfvrp6tOnjyRp2bJleu+993TcccfpsssuU25urubMmRPxs8eNG6cvv/yy5vm6deu0ZcsWDR8+XJLUr18/nXPOOZo+fbrGjRunZ599VpWVlc3+jkuWLNGyZct02mmn6eKLL1ZycrJeeeWVZi8HAAAAANC4U045Rbm5uTrooIM0Y8YMrVmzRtnZ2TXTBwwYoJ122klz585VRUWFnn/+eU2ZMkU9e/asmadXr15as2ZNLIrvCQJR6LJ23XVXZWVlKSUlRZMmTaoJDKWmpmr06NFKSEhQUlKSJk2apJ9++qnmfY7jaO3ataqoqFBGRkZNyuUnn3yiiRMnqlevXvL5fNprr720evVqbd68uc5njxw5Mmza//73P40aNUrx8ZakuN122yk1NVU+n08TJkxQZWWl1q9f3+zv+Mknn2jKlCnKzMxUfHy8Jk+erG+++UbV1dXNXhYAAAAAoHlKS0uVlJQU9trkyZNVWlqqBx54QJmZmdpll13CpicmJqq0tNTLYnqKrnnosgJd7SQpKytLhYWFkqSKigrNnz9fK1asqPnxl5WVqbq6WomJiTr66KP1/vvv66WXXtKAAQN0wAEHqGfPntqyZYvmz5+v119/vWa5ruuqsLCwTve8pKQkjRgxQl999ZUmTpyor776SoccckjN9Pfff1+fffaZCgsL5TiOysrKVFxc3OzvuGXLFj399NNyHKfmNZ/Pp61bt4Z9fwAAAABA9KWkpKisrCzstbi4OI0fP17z5s3TAQccEHa+JllPnOTkZC+L6SkCUeiyCgoKav7esmWLMjIyJFkQaMOGDTrzzDOVnp6u1atX67777quZd9iwYRo2bJgqKir09ttv66WXXtLvf/97ZWZmaq+99qoZL6oxY8eO1cKFC5Wbm6vKykoNHjxYkpSXl6fFixfr5JNPVu/eveU4jm688caIy0hISFBFRUXN8+rqahUVFdU8z8zM1GGHHaaBAwc2fcUAAAAAAKJim2220YYNG8JeKygo0MKFC7XDDjvo9ddf15lnnlnTO0ayoVuael7ZEdE1D13WRx99pIKCApWUlOi9997T2LFjJVn0OT4+XsnJySopKdE777xT856tW7dq2bJlNfMkJibWRK933nlnLVq0SGvXrpVkKZhff/11vZ8/fPhwbd68WQsWLNCYMWNqllNeXi6fz6e0tDRVV1dr4cKFdSLoAdnZ2aqsrNTy5ctVVVWld999V1VVVTXTd955Z7399ts1XQCLioq0bNmyFq8zAAAAAEDTDR8+XHl5eTXPXdfV3LlztcMOO+jQQw9Venq6FixYUDO9srJSq1at0tChQ2NRXE+QEYUua9y4cXr88cdVWFiobbfdVpMmTZIk7b777pozZ45uuukmZWRkaI899qgJ3riuqw8++EAvvPCCHMdRnz59NHXqVEnSqFGjVF5erueee05btmxRUlKShg4dqjFjxkT8/Pj4eI0aNUqff/659t1335rXhw4dqmHDhunOO+9UQkKC9thjD2VlZUVcRnJysg4++GC99NJLcl1Xe+65Z1iXu913312Sar5nWlqaxo4dq5EjR7Z+BQIAAAAAGtS3b18lJSXp119/Vf/+/bVkyRIVFRVpypQpchxHhx9+uO69916NGDFCubm5+vbbbzVo0KCaHjudkeO6bqzLALQ1KnnTOY3PAgAAAADwa/R88/vvv9fHH3+sadOmNbqwBx54QIcddljNTbHq0aHP2whE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
"
>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="What-is-the-causal-impact-of-having-a-PhD-on-making-over-$50K?">What is the causal impact of having a PhD on making over $50K?<a class="anchor-link" href="#What-is-the-causal-impact-of-having-a-PhD-on-making-over-$50K?"> </a></h2><blockquote><p>Text is Optional in CausalNLP</p>
</blockquote>
<p>Despite the "NLP" in the name, <strong>CausalNLP</strong> can be used for causal analyses on traditional tabular datasets with no text fields.</p>
<p>Note:This dataset is from the early to mid 1990s, and we are using it as a toy dataset for demonstration purposes only.</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s1">'sample_data/adult-census.csv'</span><span class="p">)</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">rename</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">applymap</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">else</span> <span class="n">x</span><span class="p">)</span>
<span class="n">filter_set</span> <span class="o">=</span> <span class="s1">'Doctorate'</span>
<span class="n">df</span><span class="p">[</span><span class="s1">'treatment'</span><span class="p">]</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="s1">'education'</span><span class="p">]</span><span class="o">.</span><span class="n">apply</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="mi">1</span> <span class="k">if</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">filter_set</span> <span class="k">else</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">df</span><span class="o">.</span><span class="n">head</span><span class="p">()</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_html rendered_html output_subarea output_execute_result"><div>
<style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>age</th>
<th>workclass</th>
<th>fnlwgt</th>
<th>education</th>
<th>education-num</th>
<th>marital-status</th>
<th>occupation</th>
<th>relationship</th>
<th>race</th>
<th>sex</th>
<th>capital-gain</th>
<th>capital-loss</th>
<th>hours-per-week</th>
<th>native-country</th>
<th>class</th>
<th>treatment</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>25</td>
<td>Private</td>
<td>178478</td>
<td>Bachelors</td>
<td>13</td>
<td>Never-married</td>
<td>Tech-support</td>
<td>Own-child</td>
<td>White</td>
<td>Female</td>
<td>0</td>
<td>0</td>
<td>40</td>
<td>United-States</td>
<td><=50K</td>
<td>0</td>
</tr>
<tr>
<th>1</th>
<td>23</td>
<td>State-gov</td>
<td>61743</td>
<td>5th-6th</td>
<td>3</td>
<td>Never-married</td>
<td>Transport-moving</td>
<td>Not-in-family</td>
<td>White</td>
<td>Male</td>
<td>0</td>
<td>0</td>
<td>35</td>
<td>United-States</td>
<td><=50K</td>
<td>0</td>
</tr>
<tr>
<th>2</th>
<td>46</td>
<td>Private</td>
<td>376789</td>
<td>HS-grad</td>
<td>9</td>
<td>Never-married</td>
<td>Other-service</td>
<td>Not-in-family</td>
<td>White</td>
<td>Male</td>
<td>0</td>
<td>0</td>
<td>15</td>
<td>United-States</td>
<td><=50K</td>
<td>0</td>
</tr>
<tr>
<th>3</th>
<td>55</td>
<td>?</td>
<td>200235</td>
<td>HS-grad</td>
<td>9</td>
<td>Married-civ-spouse</td>
<td>?</td>
<td>Husband</td>
<td>White</td>
<td>Male</td>
<td>0</td>
<td>0</td>
<td>50</td>
<td>United-States</td>
<td>>50K</td>
<td>0</td>
</tr>
<tr>
<th>4</th>
<td>36</td>
<td>Private</td>
<td>224541</td>
<td>7th-8th</td>
<td>4</td>
<td>Married-civ-spouse</td>
<td>Handlers-cleaners</td>
<td>Husband</td>
<td>White</td>
<td>Male</td>
<td>0</td>
<td>0</td>
<td>40</td>
<td>El-Salvador</td>
<td><=50K</td>
<td>0</td>
</tr>
</tbody>
</table>
</div></div>
</div>
</div>
</div>
</div>
{% endraw %}
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="kn">from</span> <span class="nn">causalnlp</span> <span class="kn">import</span> <span class="n">CausalInferenceModel</span>
<span class="n">cm</span> <span class="o">=</span> <span class="n">CausalInferenceModel</span><span class="p">(</span><span class="n">df</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s1">'t-learner'</span><span class="p">,</span>
<span class="n">treatment_col</span><span class="o">=</span><span class="s1">'treatment'</span><span class="p">,</span>
<span class="n">outcome_col</span><span class="o">=</span><span class="s1">'class'</span><span class="p">,</span>
<span class="n">ignore_cols</span><span class="o">=</span><span class="p">[</span><span class="s1">'fnlwgt'</span><span class="p">,</span> <span class="s1">'education'</span><span class="p">,</span><span class="s1">'education-num'</span><span class="p">])</span><span class="o">.</span><span class="n">fit</span><span class="p">()</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_subarea output_stream output_stdout output_text">
<pre>replaced ['<=50K', '>50K'] in column "class" with [0, 1]
outcome column (categorical): class
treatment column: treatment
numerical/categorical covariates: ['age', 'workclass', 'marital-status', 'occupation', 'relationship', 'race', 'sex', 'capital-gain', 'capital-loss', 'hours-per-week', 'native-country']
preprocess time: 0.4857158660888672 sec
start fitting causal inference model
time to fit causal inference model: 5.035430908203125 sec
</pre>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Overall, the average treatment effect of having a PhD is an increase of 20 percentage points in the probability of making over $50K (with respect to this model and dataset):</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">cm</span><span class="o">.</span><span class="n">estimate_ate</span><span class="p">()</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_text output_subarea output_execute_result">
<pre>{'ate': 0.20340645077516034}</pre>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>For those who have a Master's degree:</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">cm</span><span class="o">.</span><span class="n">estimate_ate</span><span class="p">(</span><span class="n">cm</span><span class="o">.</span><span class="n">df</span><span class="p">[</span><span class="s1">'education'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'Masters'</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_text output_subarea output_execute_result">
<pre>{'ate': 0.17672418257642838}</pre>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>For those who are high school dropouts:</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">cm</span><span class="o">.</span><span class="n">estimate_ate</span><span class="p">(</span><span class="n">cm</span><span class="o">.</span><span class="n">df</span><span class="p">[</span><span class="s1">'education'</span><span class="p">]</span><span class="o">.</span><span class="n">isin</span><span class="p">([</span><span class="s1">'Preschool'</span><span class="p">,</span> <span class="s1">'1st-4th'</span><span class="p">,</span> <span class="s1">'5th-6th'</span><span class="p">,</span> <span class="s1">'7th-8th'</span><span class="p">,</span> <span class="s1">'9th'</span><span class="p">,</span> <span class="s1">'10th'</span><span class="p">,</span> <span class="s1">'12th'</span><span class="p">]))</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_text output_subarea output_execute_result">
<pre>{'ate': 0.2586697863578173}</pre>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="What-is-the-causal-impact-of-a-job-training-program-on-earnings?">What is the causal impact of a job training program on earnings?<a class="anchor-link" href="#What-is-the-causal-impact-of-a-job-training-program-on-earnings?"> </a></h2><p>This is another example of causal inference on purely tabular data (no text). Here, we will use the famous <a href="https://rdrr.io/cran/sbw/man/lalonde.html">LaLonde dataset</a> from a job training study.</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s1">'sample_data/lalonde.csv'</span><span class="p">)</span>
<span class="n">df</span><span class="o">.</span><span class="n">head</span><span class="p">()</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_html rendered_html output_subarea output_execute_result"><div>
<style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>ID</th>
<th>treat</th>
<th>age</th>
<th>educ</th>
<th>black</th>
<th>hispan</th>
<th>married</th>
<th>nodegree</th>
<th>re74</th>
<th>re75</th>
<th>re78</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>NSW1</td>
<td>1</td>
<td>37</td>
<td>11</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>0.0</td>
<td>0.0</td>
<td>9930.0460</td>
</tr>
<tr>
<th>1</th>
<td>NSW2</td>
<td>1</td>
<td>22</td>
<td>9</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0.0</td>
<td>0.0</td>
<td>3595.8940</td>
</tr>
<tr>
<th>2</th>
<td>NSW3</td>
<td>1</td>
<td>30</td>
<td>12</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0.0</td>
<td>0.0</td>
<td>24909.4500</td>
</tr>
<tr>
<th>3</th>
<td>NSW4</td>
<td>1</td>
<td>27</td>
<td>11</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0.0</td>
<td>0.0</td>
<td>7506.1460</td>
</tr>
<tr>
<th>4</th>
<td>NSW5</td>
<td>1</td>
<td>33</td>
<td>8</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0.0</td>
<td>0.0</td>
<td>289.7899</td>
</tr>
</tbody>
</table>
</div></div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Unlike other meta-learners that use LightGBM as a default, the S-Learner uses Linear Regression as the default base learner for regression problems, which is a model that is often used for this dataset. The ATE estimate is $1548, which indicates that the job training program had an overall positive effect.</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="kn">from</span> <span class="nn">causalnlp</span> <span class="kn">import</span> <span class="n">CausalInferenceModel</span>
<span class="n">cm</span> <span class="o">=</span> <span class="n">CausalInferenceModel</span><span class="p">(</span><span class="n">df</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s1">'s-learner'</span><span class="p">,</span>
<span class="n">treatment_col</span><span class="o">=</span><span class="s1">'treat'</span><span class="p">,</span>
<span class="n">outcome_col</span><span class="o">=</span><span class="s1">'re78'</span><span class="p">,</span>
<span class="n">include_cols</span><span class="o">=</span><span class="p">[</span><span class="s1">'age'</span><span class="p">,</span> <span class="s1">'educ'</span><span class="p">,</span> <span class="s1">'black'</span><span class="p">,</span> <span class="s1">'hispan'</span><span class="p">,</span> <span class="s1">'married'</span><span class="p">,</span> <span class="s1">'nodegree'</span><span class="p">,</span> <span class="s1">'re74'</span><span class="p">,</span> <span class="s1">'re75'</span><span class="p">])</span>
<span class="n">cm</span><span class="o">.</span><span class="n">fit</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">cm</span><span class="o">.</span><span class="n">estimate_ate</span><span class="p">())</span> <span class="c1"># ATE estimate = $1548</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_subarea output_stream output_stdout output_text">
<pre>outcome column (numerical): re78
treatment column: treat
numerical/categorical covariates: ['age', 'educ', 'black', 'hispan', 'married', 'nodegree', 're74', 're75']
preprocess time: 0.017691612243652344 sec
start fitting causal inference model
time to fit causal inference model: 0.0024728775024414062 sec
{'ate': 1548.2438019996084}
</pre>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
</div>