Estimating effect of multiple treatments

[1]:
import numpy as np
import pandas as pd
import logging

import dowhy
from dowhy import CausalModel
import dowhy.datasets

import econml
import warnings
warnings.filterwarnings('ignore')
[7]:
data = dowhy.datasets.linear_dataset(10, num_common_causes=4, num_samples=10000,
                                    num_instruments=0, num_effect_modifiers=2,
                                     num_treatments=2,
                                    treatment_is_binary=False,
                                    num_discrete_common_causes=2,
                                    num_discrete_effect_modifiers=0,
                                    one_hot_encode=False)
df=data['df']
df.head()
[7]:
X0 X1 W0 W1 W2 W3 v0 v1 y
0 1.915092 1.620087 -0.734004 1.166135 1 1 4.812868 6.143449 315.635386
1 0.002147 0.669278 -0.488148 1.662905 0 0 2.241058 -0.507441 20.008368
2 0.248668 0.744331 0.395333 0.363403 1 1 8.223679 9.169402 322.803160
3 1.391820 0.685058 2.196834 -0.031341 1 2 13.784811 16.208969 1188.634520
4 0.978381 0.656576 0.686080 0.260394 2 1 12.353938 13.503698 785.596373
[8]:
model = CausalModel(data=data["df"],
                    treatment=data["treatment_name"], outcome=data["outcome_name"],
                    graph=data["gml_graph"])
INFO:dowhy.causal_model:Model to find the causal effect of treatment ['v0', 'v1'] on outcome ['y']
[9]:
model.view_model()
from IPython.display import Image, display
display(Image(filename="causal_model.png"))
../_images/example_notebooks_dowhy_multiple_treatments_4_0.png
[10]:
identified_estimand= model.identify_effect()
print(identified_estimand)
INFO:dowhy.causal_identifier:Common causes of treatment and outcome:['W0', 'Unobserved Confounders', 'W1', 'W2', 'W3']
WARNING:dowhy.causal_identifier:If this is observed data (not from a randomized experiment), there might always be missing confounders. Causal effect cannot be identified perfectly.
WARN: Do you want to continue by ignoring any unobserved confounders? (use proceed_when_unidentifiable=True to disable this prompt) [y/n] y
INFO:dowhy.causal_identifier:Instrumental variables for treatment and outcome:[]
Estimand type: nonparametric-ate
### Estimand : 1
Estimand name: backdoor
Estimand expression:
    d
─────────(Expectation(y|W0,W1,W2,W3))
d[v₀  v₁]
Estimand assumption 1, Unconfoundedness: If U→{v0,v1} and U→y then P(y|v0,v1,W0,W1,W2,W3,U) = P(y|v0,v1,W0,W1,W2,W3)
### Estimand : 2
Estimand name: iv
No such variable found!

Linear model

Let us first see an example for a linear model. The control_value and treatment_value can be provided as a tuple/list when the treatment is multi-dimensional.

The interpretation is change in y when v0 and v1 are changed from (0,0) to (1,1).

[16]:
linear_estimate = model.estimate_effect(identified_estimand,
                                        method_name="backdoor.linear_regression",
                                       control_value=(0,0),
                                       treatment_value=(1,1),
                                       method_params={'need_conditional_estimates': False})
print(linear_estimate)
INFO:dowhy.causal_estimator:INFO: Using Linear Regression Estimator
INFO:dowhy.causal_estimator:b: y~v0+v1+W0+W1+W2+W3+v0*X0+v0*X1+v1*X0+v1*X1
*** Causal Estimate ***

## Identified estimand
Estimand type: nonparametric-ate
### Estimand : 1
Estimand name: backdoor
Estimand expression:
    d
─────────(Expectation(y|W0,W1,W2,W3))
d[v₀  v₁]
Estimand assumption 1, Unconfoundedness: If U→{v0,v1} and U→y then P(y|v0,v1,W0,W1,W2,W3,U) = P(y|v0,v1,W0,W1,W2,W3)
### Estimand : 2
Estimand name: iv
No such variable found!

## Realized estimand
b: y~v0+v1+W0+W1+W2+W3+v0*X0+v0*X1+v1*X0+v1*X1
Target units: ate

## Estimate
Mean value: 90.33055385892129

You can estimate conditional effects, based on effect modifiers.

[18]:
linear_estimate = model.estimate_effect(identified_estimand,
                                        method_name="backdoor.linear_regression",
                                       control_value=(0,0),
                                       treatment_value=(1,1))
print(linear_estimate)
INFO:dowhy.causal_estimator:INFO: Using Linear Regression Estimator
INFO:dowhy.causal_estimator:b: y~v0+v1+W0+W1+W2+W3+v0*X0+v0*X1+v1*X0+v1*X1
*** Causal Estimate ***

## Identified estimand
Estimand type: nonparametric-ate
### Estimand : 1
Estimand name: backdoor
Estimand expression:
    d
─────────(Expectation(y|W0,W1,W2,W3))
d[v₀  v₁]
Estimand assumption 1, Unconfoundedness: If U→{v0,v1} and U→y then P(y|v0,v1,W0,W1,W2,W3,U) = P(y|v0,v1,W0,W1,W2,W3)
### Estimand : 2
Estimand name: iv
No such variable found!

## Realized estimand
b: y~v0+v1+W0+W1+W2+W3+v0*X0+v0*X1+v1*X0+v1*X1
Target units: ate

## Estimate
Mean value: 90.33055385892129
### Conditional Estimates
__categorical__X0  __categorical__X1
(-2.629, 0.14]     (-2.936, 0.0176]      -3.709237
                   (0.0176, 0.586]       25.191433
                   (0.586, 1.084]        43.708158
                   (1.084, 1.661]        61.782760
                   (1.661, 4.444]        90.521027
(0.14, 0.72]       (-2.936, 0.0176]      24.438689
                   (0.0176, 0.586]       54.299181
                   (0.586, 1.084]        72.005026
                   (1.084, 1.661]        90.203724
                   (1.661, 4.444]       119.455480
(0.72, 1.232]      (-2.936, 0.0176]      41.988317
                   (0.0176, 0.586]       72.977085
                   (0.586, 1.084]        90.270855
                   (1.084, 1.661]       108.403973
                   (1.661, 4.444]       136.661504
(1.232, 1.845]     (-2.936, 0.0176]      58.596700
                   (0.0176, 0.586]       90.604757
                   (0.586, 1.084]       108.531656
                   (1.084, 1.661]       126.376825
                   (1.661, 4.444]       156.005501
(1.845, 4.73]      (-2.936, 0.0176]      90.504006
                   (0.0176, 0.586]      120.364554
                   (0.586, 1.084]       137.619648
                   (1.084, 1.661]       155.753611
                   (1.661, 4.444]       185.702174
dtype: float64

More methods

You can also use methods from EconML or CausalML libraries that support multiple treatments. You can look at examples from the conditional effect notebook: https://microsoft.github.io/dowhy/example_notebooks/dowhy-conditional-treatment-effects.html

Propensity-based methods do not support multiple treatments currently.