Code Snippets
This notebook contains all code snippets that appear in the forthcoming paper submission, available at [TODO].
[1]:
from ananke import graphs, identification
from ananke.models import binary_nested
from ananke.estimation import CausalEffect
from ananke.datasets import load_wisconsin_health_study, load_frontdoor_data
Identification
[2]:
vertices = ["A", "M", "Y"]
di_edges = [("A", "M"), ("M", "Y")]
bi_edges = [("A", "Y")]
front_door = graphs.ADMG(vertices, di_edges, bi_edges)
treatments = ["A"]
outcomes = ["Y"]
id_front_door = identification.OneLineID(graph=front_door, treatments=treatments, outcomes=outcomes)
print('Identifed =', id_front_door.id(), '; Functional =', id_front_door.functional())
{('Y',): ['M', 'A'], ('M',): ['Y', 'A']}
Identifed = True ; Functional = ΣM ΦAY(p(V);G) ΦAM(p(V);G)
Estimation through Mobius Parameterization
[3]:
df = load_wisconsin_health_study().rename(columns={"E": "A"}).groupby(["A", "M", "Y"])["count"].sum().reset_index()
bnm = binary_nested.BinaryNestedModel(front_door)
bnm = bnm.fit(X=df, tol=1e-12)
theta_M0_A0 = bnm.fitted_params[(frozenset({'M'}), ('A',), (0,))]
theta_M0_A1 = bnm.fitted_params[(frozenset({'M'}), ('A',), (1,))]
theta_Y0_M0 = bnm.fitted_params[(frozenset({'Y'}), ('M',), (0,))]
theta_Y0_M1 = bnm.fitted_params[(frozenset({'Y'}), ('M',), (1,))]
pY1_A0 = bnm.estimate(treatment_dict={"A": 0}, outcome_dict={"Y": 1})
pY1_A1 = bnm.estimate(treatment_dict={"A": 1}, outcome_dict={"Y": 1})
print("ACE: ", pY1_A1 - pY1_A0)
# ACE: 0.004
/Users/jaron/Projects/ananke/ananke/models/binary_nested.py:507: RuntimeWarning: invalid value encountered in log
logger.debug(np.log(A @ x - b))
/Users/jaron/Projects/ananke/ananke/models/binary_nested.py:508: RuntimeWarning: invalid value encountered in log
lld = np.sum(counts * np.log(A @ x - b))
ACE: 0.004727830873286432
Estimation using Efficient Semiparametric Methods
[4]:
data = load_frontdoor_data().rename(columns={"T": "A", "ViralLoad2": "M", "CD4": "Y"})[["A", "M", "Y"]]
[5]:
ace_obj = CausalEffect(graph=front_door, treatment='A', outcome='Y') # setting up the ACE object
ace = ace_obj.compute_effect(data, "eff-apipw")
print("ace = ", ace)
Treatment is p-fixable and graph is mb-shielded.
Available estimators are:
1. Primal IPW (p-ipw)
2. Dual IPW (d-ipw)
3. APIPW (apipw)
4. Efficient APIPW (eff-apipw)
Suggested estimator is Efficient APIPW
ace = -0.9020293902163798