Iterating over multiple refutation tests

The objective of this notebook is to compare the ability of refuters to detect the problems in a given set of estimators. Note: This notebook makes use of the optional dependencies: - pygraphviz - econml

Import Dependencies

[23]:
from dowhy.datasets import linear_dataset
from dowhy import CausalModel
import econml

# Config dict to set the logging level
import logging.config
DEFAULT_LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'loggers': {
        '': {
            'level': 'WARN',
        },
    }
}

logging.config.dictConfig(DEFAULT_LOGGING)
# Disabling warnings output
import warnings
from sklearn.exceptions import DataConversionWarning
warnings.filterwarnings(action='ignore', category=DataConversionWarning)

Inspection Parameters

These parameters give us the option of inspecting the intermediate steps to sanity check the steps performed

[24]:
inspect_datasets = True
inspect_models = True
inspect_identified_estimands = True
inspect_estimates = True
inspect_refutations = True

Estimator List

We pass a list of strings, corresponding to the estimators of interest

[25]:
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LassoCV
from sklearn.ensemble import GradientBoostingRegressor

estimator_list = ["backdoor.propensity_score_matching", "backdoor.propensity_score_weighting", "backdoor.econml.dml.DML"]
method_params= [ None, None, {"init_params":{'model_y':GradientBoostingRegressor(),
                                                              'model_t': GradientBoostingRegressor(),
                                                              "model_final":LassoCV(fit_intercept=False),
                                                              'featurizer':PolynomialFeatures(degree=1, include_bias=False)},
                                               "fit_params":{}} ]

Refuter List

A list of strings, corresponding to each refuter we wish to run

[26]:
refuter_list = ["bootstrap_refuter", "data_subset_refuter"]

Create the Datasets

[27]:
# Parameters for creating the Dataset
TREATMENT_IS_BINARY = True
BETA = 10
NUM_SAMPLES = 5000
NUM_CONFOUNDERS = 5
NUM_INSTRUMENTS = 3
NUM_EFFECT_MODIFIERS = 2

# Creating a Linear Dataset with the given parameters
linear_data = linear_dataset(
            beta = BETA,
            num_common_causes = NUM_CONFOUNDERS,
            num_instruments = NUM_INSTRUMENTS,
            num_effect_modifiers = NUM_EFFECT_MODIFIERS,
            num_samples = NUM_SAMPLES,
            treatment_is_binary = True
        )
# Other datasets come here


# Append them together in an array
datasets = [linear_data]

Inspect Data

[28]:
dataset_num = 1
if inspect_datasets is True:
    for data in datasets:
        print("####### Dataset {}###########################################################################################".format(dataset_num))
        print(data['df'].head())
        print("#############################################################################################################")
        dataset_num += 1
####### Dataset 1###########################################################################################
         X0        X1   Z0        Z1   Z2        W0        W1        W2  \
0  1.967335  1.905424  1.0  0.670757  0.0 -0.202865 -1.144348  1.183711
1  1.128093 -1.239441  0.0  0.867080  0.0 -0.356516  1.708609  1.092528
2  1.652412 -0.091724  1.0  0.571701  0.0 -0.932946 -2.417561  0.628134
3 -1.435738  0.029290  1.0  0.107491  0.0 -0.573645 -1.436408 -0.625384
4  1.811213  0.656676  1.0  0.789946  0.0 -1.196961 -1.909887  0.436464

         W3        W4    v0          y
0  0.936799 -0.174390  True  12.717473
1 -0.040246 -1.029646  True  15.072868
2 -1.921820  0.121284  True  -9.638836
3  1.963276 -1.014058  True   5.584867
4 -0.035781 -0.435584  True  -2.168388
#############################################################################################################

Create the CausalModels

[29]:
models = []
for data in datasets:
    model = CausalModel(
                data = data['df'],
                treatment = data['treatment_name'],
                outcome = data['outcome_name'],
                graph = data['gml_graph']
            )
    models.append(model)

View Models

[30]:
model.view_model()
from IPython.display import Image, display
display(Image(filename="causal_model.png"))
../_images/example_notebooks_dowhy_refuter_notebook_16_0.png

Identify Effect

[31]:
identified_estimands = []
for model in models:
    identified_estimand = model.identify_effect(proceed_when_unidentifiable=True)
    identified_estimands.append(identified_estimand)

Identified Estimands

[32]:
estimand_count = 1
for estimand in identified_estimands:
    print("####### Identified Estimand {}#####################################################################################".format(estimand_count))
    print(estimand)
    print("###################################################################################################################")
    estimand_count += 1
####### Identified Estimand 1#####################################################################################
Estimand type: nonparametric-ate

### Estimand : 1
Estimand name: backdoor
Estimand expression:
  d
─────(Expectation(y|W0,W1,W4,W3,W2))
d[v₀]
Estimand assumption 1, Unconfoundedness: If U→{v0} and U→y then P(y|v0,W0,W1,W4,W3,W2,U) = P(y|v0,W0,W1,W4,W3,W2)

### Estimand : 2
Estimand name: iv
Estimand expression:
Expectation(Derivative(y, [Z1, Z0, Z2])*Derivative([v0], [Z1, Z0, Z2])**(-1))
Estimand assumption 1, As-if-random: If U→→y then ¬(U →→{Z1,Z0,Z2})
Estimand assumption 2, Exclusion: If we remove {Z1,Z0,Z2}→{v0}, then ¬({Z1,Z0,Z2}→y)

### Estimand : 3
Estimand name: frontdoor
No such variable(s) found!

###################################################################################################################

Estimate Effect

[33]:
estimate_list = []
for i in range(len(identified_estimands)):
    for j in range(len(estimator_list)):
        estimate = model.estimate_effect(
                        identified_estimands[i],
                        method_name=estimator_list[j],
                        method_params=method_params[j]
                  )
        estimate_list.append(estimate)

Estimate Values

[34]:
estimand_count = 1
if inspect_estimates is True:
    for estimand in estimate_list:
        print("####### Estimand {}#######################################################################################".format(estimand_count))
        print("*** Class Name ***")
        print()
        print(estimand.params['estimator_class'])
        print()
        print(estimand)
        print("########################################################################################################")
        print()
        estimand_count += 1
####### Estimand 1#######################################################################################
*** Class Name ***

<class 'dowhy.causal_estimators.propensity_score_matching_estimator.PropensityScoreMatchingEstimator'>

*** Causal Estimate ***

## Identified estimand
Estimand type: nonparametric-ate

### Estimand : 1
Estimand name: backdoor
Estimand expression:
  d
─────(Expectation(y|W0,W1,W4,W3,W2))
d[v₀]
Estimand assumption 1, Unconfoundedness: If U→{v0} and U→y then P(y|v0,W0,W1,W4,W3,W2,U) = P(y|v0,W0,W1,W4,W3,W2)

## Realized estimand
b: y~v0+W0+W1+W4+W3+W2
Target units: ate

## Estimate
Mean value: 8.974926096306975

########################################################################################################

####### Estimand 2#######################################################################################
*** Class Name ***

<class 'dowhy.causal_estimators.propensity_score_weighting_estimator.PropensityScoreWeightingEstimator'>

*** Causal Estimate ***

## Identified estimand
Estimand type: nonparametric-ate

### Estimand : 1
Estimand name: backdoor
Estimand expression:
  d
─────(Expectation(y|W0,W1,W4,W3,W2))
d[v₀]
Estimand assumption 1, Unconfoundedness: If U→{v0} and U→y then P(y|v0,W0,W1,W4,W3,W2,U) = P(y|v0,W0,W1,W4,W3,W2)

## Realized estimand
b: y~v0+W0+W1+W4+W3+W2
Target units: ate

## Estimate
Mean value: 12.408983841921629

########################################################################################################

####### Estimand 3#######################################################################################
*** Class Name ***

<class 'dowhy.causal_estimators.econml.Econml'>

*** Causal Estimate ***

## Identified estimand
Estimand type: nonparametric-ate

### Estimand : 1
Estimand name: backdoor
Estimand expression:
  d
─────(Expectation(y|W0,W1,W4,W3,W2))
d[v₀]
Estimand assumption 1, Unconfoundedness: If U→{v0} and U→y then P(y|v0,W0,W1,W4,W3,W2,U) = P(y|v0,W0,W1,W4,W3,W2)

## Realized estimand
b: y~v0+W0+W1+W4+W3+W2 | X0,X1
Target units: ate

## Estimate
Mean value: 9.858256590293788
Effect estimates: [11.0297145   9.78699228 10.30838788 ...  9.46308525  9.64756645
 10.80259596]

########################################################################################################

Refute Estimate

[35]:
refutation_list = []
for estimand in identified_estimands:
    for estimate in estimate_list:
        for refuter in refuter_list:
            ref = model.refute_estimate(estimand, estimate,method_name=refuter)
            refutation_list.append(ref)

Refutation Values

[36]:
refuter_count = 1
if inspect_refutations is True:
    for refutation in refutation_list:
        print("####### Refutation {}#######################################################################################".format(refuter_count))
        print("*** Class Name ***")
        print()
        print(refutation.refutation_type)
        print()
        print(refutation)
        print("########################################################################################################")
        print()
        refuter_count += 1
####### Refutation 1#######################################################################################
*** Class Name ***

Refute: Bootstrap Sample Dataset

Refute: Bootstrap Sample Dataset
Estimated effect:8.974926096306975
New effect:9.710002131986627
p value:0.25

########################################################################################################

####### Refutation 2#######################################################################################
*** Class Name ***

Refute: Use a subset of data

Refute: Use a subset of data
Estimated effect:8.974926096306975
New effect:9.859343600595292
p value:0.1

########################################################################################################

####### Refutation 3#######################################################################################
*** Class Name ***

Refute: Bootstrap Sample Dataset

Refute: Bootstrap Sample Dataset
Estimated effect:12.408983841921629
New effect:12.497225598094587
p value:0.31

########################################################################################################

####### Refutation 4#######################################################################################
*** Class Name ***

Refute: Use a subset of data

Refute: Use a subset of data
Estimated effect:12.408983841921629
New effect:12.414222770840858
p value:0.46

########################################################################################################

####### Refutation 5#######################################################################################
*** Class Name ***

Refute: Bootstrap Sample Dataset

Refute: Bootstrap Sample Dataset
Estimated effect:9.858256590293788
New effect:9.904506002270809
p value:0.29

########################################################################################################

####### Refutation 6#######################################################################################
*** Class Name ***

Refute: Use a subset of data

Refute: Use a subset of data
Estimated effect:9.858256590293788
New effect:9.896534434335736
p value:0.28

########################################################################################################