def test_is_id_chain(self): vertices = ["A", "X", "W", "Y"] di_edges = [("A", "X"), ("X", "W"), ("W", "Y")] bi_edges = [("X", "W"), ("W", 'Y')] G = ADMG(vertices, di_edges, bi_edges) interventions = ["A"] outcomes = ["Y"] ol = identification.OneLineGID(G, interventions, outcomes) status = ol.id([{"A", "X"}, {"A", "Y"}]) self.assertFalse(status) vertices = ["A", "X", "Y"] di_edges = [("A", "X"), ("X", "Y")] bi_edges = [("X", "Y")] G = ADMG(vertices, di_edges, bi_edges) interventions = ["A"] outcomes = ["Y"] ol = identification.OneLineGID(G, interventions, outcomes) status = ol.id([{"A", "X"}, {"A", "Y"}]) self.assertFalse(status) vertices = ["A", "W", "Y"] di_edges = [("A", "W"), ("W", "Y")] bi_edges = [("A", "W"), ("W", "Y")] G = ADMG(vertices, di_edges, bi_edges) interventions = ["A"] outcomes = ["Y"] ol = identification.OneLineGID(G, interventions, outcomes) status = ol.id([{"A"}, {"A", "Y"}]) self.assertTrue(status)
def test_oneline_aid(self): vertices = ["X1", "X2", "W", "Y"] di_edges = [("X1", "W"), ("W", "Y"), ("X2", "Y")] bi_edges = [("X1", "X2"), ("X1", "W"), ("X2", "Y")] G = ADMG(vertices, di_edges, bi_edges) vertices = ["X1", "W"] di_edges = [("X1", "W")] bi_edges = [("X1", "W")] G1 = ADMG(vertices, di_edges, bi_edges) G1.fix(["X1"]) vertices = ["X1", "X2", "W", "Y"] di_edges = [("X1", "W"), ("W", "Y"), ("X2", "Y")] bi_edges = [("X1", "X2"), ("X1", "W"), ("X2", "Y")] G2 = ADMG(vertices, di_edges, bi_edges) G2.fix(["X2"]) interventions = ["X1", "X2"] outcomes = ["Y"] ol = identification.OnelineAID(G, interventions, outcomes) experiments = [G1, G2] self.assertTrue(ol.id(experiments=experiments)) self.assertEqual("ΣW p(W | do(X1))ΦX1,W p(W,X1,Y | do(X2))", ol.functional(experiments))
def test_p_fixable_continuousY_inML(self): np.random.seed(0) vertices = ['T', 'M', 'Y'] di_edges = [('T', 'M'), ('M', 'Y')] bi_edges_1 = [('T', 'Y')] bi_edges_2 = [('M', 'Y')] # First graph: Y \in L (front-door), mb-shielded G_1 = ADMG(vertices, di_edges, bi_edges_1) # Second graph: Y \in M, not mb-shielded G_2 = ADMG(vertices, di_edges, bi_edges_2) size = 5000 U1 = np.random.binomial(1, 0.4, size) U2 = np.random.uniform(0, 1.5, size) p_t = expit(0.8 + 0.4 * U1 - 0.8 * U2) T = np.random.binomial(1, p_t, size) M = -0.3 + 0.8 * T + np.random.normal(0, 1, size) Y = 1 + 1 * M + 0.5 * U1 + 0.3 * U2 + np.random.normal(0, 1, size) data = pd.DataFrame({'T': T, 'M': M, 'Y': Y}) # Compute the true ACE = (coefficient of T in M)*(coefficient of M in L) ace_truth = 0.8 # Test on the first graph ace_1 = CausalEffect(G_1, 'T', 'Y') ace_1_pipw, _, _ = ace_1.compute_effect(data, "p-ipw", n_bootstraps=1) ace_1_dipw = ace_1.compute_effect(data, "d-ipw") ace_1_apipw = ace_1.compute_effect(data, "apipw") ace_1_eff = ace_1.compute_effect(data, "eff-apipw") self.assertTrue(ace_1.is_mb_shielded) self.assertTrue(abs(ace_1_pipw - ace_truth) < TOL) self.assertTrue(abs(ace_1_dipw - ace_truth) < TOL) self.assertTrue(abs(ace_1_apipw - ace_truth) < TOL) self.assertTrue(abs(ace_1_eff - ace_truth) < TOL) # Test on the second graph ace_2 = CausalEffect(G_2, 'T', 'Y') ace_2_pipw = ace_2.compute_effect(data, "p-ipw") ace_2_dipw = ace_2.compute_effect(data, "d-ipw") ace_2_apipw = ace_2.compute_effect(data, "apipw") self.assertFalse(ace_2.is_mb_shielded) self.assertTrue(abs(ace_2_pipw - ace_truth) < TOL) self.assertTrue(abs(ace_2_dipw - ace_truth) < TOL) self.assertTrue(abs(ace_2_apipw - ace_truth) < TOL)
def test_nested_fixable_and_notid(self): G_bowarc = ADMG(vertices=['T', 'Y'], di_edges=[('T', 'Y')], bi_edges=[('T', 'Y')]) with self.assertRaises(RuntimeError): AutomatedIF(G_bowarc, 'T', 'Y') vertices = ['C1', 'C2', 'T', 'M', 'Z', 'R1', 'R2', 'Y'] di_edges = [('C1', 'T'), ('C1', 'Y'), ('C2', 'T'), ('C2', 'Y'), ('R2', 'Y'), ('Z', 'T'), ('T', 'R1'), ('T', 'Y'), ('R1', 'M'), ('M', 'Y')] bi_edges = [('Z', 'R2'), ('T', 'R2'), ('Z', 'R1'), ('C1', 'M'), ('C1', 'Y'), ('C2', 'M'), ('C2', 'Y')] G_nfixable = ADMG(vertices, di_edges, bi_edges) with self.assertRaises(NotImplementedError): AutomatedIF(G_nfixable, 'T', 'Y')
def test_full_id_cross_pattern(self): vertices = ['X_1', 'X_2', 'R_1', 'R_2'] di_edges = [('X_1', 'R_2'), ('X_2', 'R_1'), ('R_2', 'R_1')] mdag = ADMG(vertices, di_edges) full_id = MissingFullID(mdag) self.assertFalse(full_id.id())
def test_nested_fixable_conditional_ignorability(self): np.random.seed(0) vertices = ['C', 'T', 'Y'] di_edges = [('C', 'Y'), ('T', 'Y')] bi_edges = [('C', 'T')] G = ADMG(vertices, di_edges, bi_edges) size = 2000 U1 = np.random.binomial(1, 0.4, size) U2 = np.random.uniform(0, 1.5, size) C = -1 + 0.4 * U1 + 0.8 * U2 + np.random.normal(0, 1, size) p_t = expit(0.2 + 0.2 * U1 + 0.5 * U2) T = np.random.binomial(1, p_t, size) p_y = expit(1 + 1.5 * T - 0.6 * C) Y = np.random.binomial(1, p_y, size) data = pd.DataFrame({'C': C, 'T': T, 'Y': Y}) ace_truth = 1.5 ace = CausalEffect(G, 'T', 'Y') ace_nipw = ace.compute_effect(data, "n-ipw") ace_anipw = ace.compute_effect(data, "anipw") self.assertTrue(abs(ace_nipw - ace_truth) < TOL) self.assertTrue(abs(ace_anipw - ace_truth) < TOL)
def test_nested_fixable_Y_in_DT_continuousZ(self): np.random.seed(0) vertices = ['C', 'Z1', 'Z2', 'T', 'Y'] di_edges = [('C', 'T'), ('C', 'Y'), ('Z1', 'Z2'), ('Z2', 'T'), ('T', 'Y')] bi_edges = [('Z1', 'T'), ('Z1', 'Y')] G = ADMG(vertices, di_edges, bi_edges) size = 2000 U1 = np.random.binomial(1, 0.4, size) U2 = np.random.uniform(0, 1.5, size) U3 = np.random.binomial(1, 0.3, size) U4 = np.random.uniform(0, 0.5, size) C = np.random.normal(0, 1, size) Z1 = U1 - U2 + 0.5 * U3 + U4 + np.random.normal(1, 1, size) Z2 = 0.4 - 0.4 * Z1 + np.random.normal(0, 1, size) p_t = expit(0.2 + 0.2 * C + 0.5 * Z2 + U1 - U2) T = np.random.binomial(1, p_t, size) Y = 1 + T - 0.6 * C + U3 + U4 + np.random.normal(0, 1, size) data = pd.DataFrame({'Z1': Z1, 'Z2': Z2, 'C': C, 'T': T, 'Y': Y}) ace_truth = 1 ace = CausalEffect(G, 'T', 'Y') ace.n_order = ['C', 'Z1', 'Z2', 'T', 'Y'] ace_nipw = ace.compute_effect(data, "n-ipw") ace_anipw = ace.compute_effect(data, "anipw") self.assertTrue(abs(ace_nipw - ace_truth) < TOL) self.assertTrue(abs(ace_anipw - ace_truth) < TOL)
def test_model_creation(self): vertices = ["A", "B", "C", "D"] di_edges = [("A", "B"), ("B", "C"), ("C", "D")] bi_edges = [("B", "D")] G = ADMG(vertices, di_edges=di_edges, bi_edges=bi_edges) model = LinearGaussianSEM(G) self.assertEqual(8, model.n_params)
def test_BMAY_graph(self): vertices = ["B", "M", "A", "Y"] di_edges = [("B", "M"), ("M", "A"), ("A", "Y")] bi_edges = [("B", "A"), ("B", "Y")] G = ADMG(vertices, di_edges, bi_edges) one_id = OneLineID(G, ["A"], ["Y"]) one_id.draw_swig() self.assertTrue(one_id.id())
def test_two_var_id_graph(self): vertices = ["A", "D", "C", "Y"] di_edges = [('D', 'Y'), ('D', 'A'), ('A', 'Y'), ('C', 'A'), ('C', 'Y')] bi_edges = [] G = ADMG(vertices, di_edges, bi_edges) one_id = OneLineID(G, ['A'], ['Y', 'D']) self.assertEqual({"C", "D", "Y"}, one_id.ystar) self.assertTrue(one_id.id())
def test_functional(self): vertices = ["M", "A", "Y"] di_edges = [("A", "M"), ("M", "Y")] bi_edges = [("A", "Y")] G = ADMG(vertices, di_edges, bi_edges) one_id = OneLineID(G, ['A'], ['Y']) functional = one_id.functional() self.assertEqual("ΣM ΦAY(p(V);G) ΦAM(p(V);G) ", functional)
def test_p_fixable_binaryY_inML(self): np.random.seed(0) vertices = ['T', 'M', 'Y'] di_edges = [('T', 'M'), ('M', 'Y')] bi_edges_1 = [('T', 'Y')] bi_edges_2 = [('M', 'Y')] # First graph: Y \in L (front-door) G_1 = ADMG(vertices, di_edges, bi_edges_1) # Second graph: Y \in M G_2 = ADMG(vertices, di_edges, bi_edges_2) size = 5000 U1 = np.random.binomial(1, 0.4, size) U2 = np.random.uniform(0, 1.5, size) p_t = expit(0.5 - 0.4 * U1 + 0.4 * U2) T = np.random.binomial(1, p_t, size) M = -0.3 + 0.8 * T + np.random.normal(0, 1, size) p_y = expit(-1 + 0.4 * M + 0.5 * U1 + 0.3 * U2) Y = np.random.binomial(1, p_y, size) data = pd.DataFrame({'T': T, 'M': M, 'Y': Y}) # Compute the true ACE (log of odds ratio) ace_truth = 0.32 # Test the first graph ace_1 = CausalEffect(G_1, 'T', 'Y') ace_1_pipw = ace_1.compute_effect(data, "p-ipw") ace_1_dipw = ace_1.compute_effect(data, "d-ipw") self.assertTrue(abs(ace_1_pipw - ace_truth) < TOL) self.assertTrue(abs(ace_1_dipw - ace_truth) < TOL) # Test the second graph ace_2 = CausalEffect(G_2, 'T', 'Y') ace_2_pipw, _, _ = ace_2.compute_effect(data, "p-ipw", n_bootstraps=1) ace_2_dipw = ace_2.compute_effect(data, "d-ipw") self.assertTrue(abs(ace_2_pipw - ace_truth) < TOL) self.assertTrue(abs(ace_2_dipw - ace_truth) < TOL)
def test_p_fixability_continuousML(self): np.random.seed(0) vertices = ['C1', 'C2', 'Z1', 'Z2', 'T', 'M', 'L', 'Y'] di_edges = [('C1', 'T'), ('C1', 'L'), ('C2', 'T'), ('C2', 'M'), ('C2', 'L'), ('C2', 'Y'), ('T', 'M'), ('M', 'L'), ('L', 'Y')] bi_edges = [('Z1', 'C1'), ('Z2', 'C2'), ('T', 'L')] G = ADMG(vertices, di_edges, bi_edges) size = 5000 U1 = np.random.binomial(1, 0.4, size) U2 = np.random.uniform(0, 1.5, size) U3 = np.random.binomial(1, 0.6, size) U4 = np.random.uniform(-1, 0.2, size) U5 = np.random.binomial(1, 0.3, size) U6 = np.random.uniform(0.5, 1.5, size) p_z1 = expit(0.4 - U1 + U2) Z1 = np.random.binomial(1, p_z1, size) p_c1 = expit(-0.1 + U1 - U2) C1 = np.random.binomial(1, p_c1, size) C2 = 1 + U3 - U4 + np.random.normal(0, 1, size) Z2 = -0.5 + U3 - U4 + np.random.normal(0, 1, size) p_t = expit(0.5 + 0.5 * C1 - 0.4 * C2 - 0.4 * U5 + 0.4 * U6) T = np.random.binomial(1, p_t, size) M = -0.3 + 0.8 * T - 0.3 * C2 + np.random.normal(0, 1, size) L = 0.75 - 1.5 * M - 0.4 * C1 - 0.3 * C2 - 0.4 * U5 + 0.5 * U6 + np.random.normal( 0, 1, size) Y = 1 + 1 * L + C2 + np.random.normal(0, 1, size) data = pd.DataFrame({ 'C1': C1, 'C2': C2, 'Z1': Z1, 'Z2': Z2, 'T': T, 'M': M, 'L': L, 'Y': Y }) # Compute the true ACE = (coefficient of T in M)*(coefficient of M in L) ace_truth = -1.2 ace = CausalEffect(G, 'T', 'Y') ace_pipw = ace.compute_effect(data, "p-ipw") ace_dipw = ace.compute_effect(data, "d-ipw") print(ace_pipw) print(ace_dipw) self.assertTrue(abs(ace_pipw - ace_truth) < TOL) self.assertTrue(abs(ace_dipw - ace_truth) < TOL)
def test_init(self): vertices = ["A", "B", "C"] di_edges = [("A", "B")] bi_edges = [("B", "C"), ("A", "C")] admg = ADMG(vertices=vertices, bi_edges=bi_edges, di_edges=di_edges) ig = IG(admg=admg) print(ig.bi_edges)
def test_a_fixability_compute_ace(self): np.random.seed(0) vertices = ['Z1', 'Z2', 'C1', 'C2', 'T', 'M', 'Y'] di_edges = [('C1', 'Z1'), ('C1', 'T'), ('C1', 'M'), ('C2', 'Z1'), ('C2', 'T'), ('C2', 'M'), ('Z1', 'Z2'), ('Z2', 'T'), ('T', 'M'), ('M', 'Y')] bi_edges = [('Z1', 'T'), ('Z2', 'C1'), ('C2', 'Y')] G = ADMG(vertices, di_edges, bi_edges) size = 2000 U1 = np.random.binomial(1, 0.4, size) U2 = np.random.uniform(0, 1.5, size) U3 = np.random.binomial(1, 0.6, size) U4 = np.random.uniform(-1, 0.2, size) U5 = np.random.binomial(1, 0.3, size) U6 = np.random.uniform(0.5, 1.5, size) C1 = U3 + U4 + np.random.normal(0, 1, size) C2 = U5 * U6 + np.random.normal(0, 1, size) p_z1 = expit(0.4 + 0.3 * C1 - 0.4 * C2 - 0.5 * U1 * U2) Z1 = np.random.binomial(1, p_z1, size) Z2 = 1 + Z1 + U3 + U4 + np.random.normal(0, 1, size) p_t1 = expit(0.5 - 0.3 * C1 - 0.4 * C2 + 0.3 * U1 - 0.3 * U2) T = np.random.binomial(1, p_t1, size) M = 1 + 0.5 * C1 - 0.8 * C2 - 0.5 * T + np.random.normal(0, 1, size) Y = 1 + 1 * M + U5 + U6 + np.random.normal(0, 1, size) data = pd.DataFrame({ 'C1': C1, 'C2': C2, 'Z1': Z1, 'Z2': Z2, 'T': T, 'M': M, 'Y': Y }) ace_truth = -0.5 ace = CausalEffect(G, 'T', 'Y') ace_ipw = ace.compute_effect(data, "ipw") ace_gformula = ace.compute_effect(data, "gformula") ace_aipw = ace.compute_effect(data, "aipw") ace_eff = ace.compute_effect(data, "eff-aipw") self.assertTrue(abs(ace_ipw - ace_truth) < TOL) self.assertTrue(abs(ace_gformula - ace_truth) < TOL) self.assertTrue(abs(ace_aipw - ace_truth) < TOL) self.assertTrue(abs(ace_eff - ace_truth) < TOL)
def test_conditionally_ignorable_model(self): vertices = ['A', 'C', 'Y'] di_edges = [('C', 'A'), ('C', 'Y'), ('A', 'Y')] G = ADMG(vertices, di_edges) influence = AutomatedIF(G, 'A', 'Y') print(influence.beta_primal_) print(influence.beta_dual_) print(influence.nonparametric_if_) print(influence.eff_if_) self.assertEqual(influence.eff_if_, influence.nonparametric_if_)
def test_full_id_chain(self): vertices = ['X_1', 'X_2', 'X_3', 'R_1', 'R_2', 'R_3'] di_edges = [('X_1', 'R_2'), ('X_2', 'R_3'), ('X_3', 'R_1'), ('R_3', 'R_2'), ('R_2', 'R_1')] mdag = ADMG(vertices, di_edges) full_id = MissingFullID(mdag) self.assertTrue(full_id.id()) mdag.add_diedge('X_1', 'R_3') full_id = MissingFullID(mdag) self.assertTrue(full_id.id())
def test_functional(self): vertices = ["X_1", "X_2", "W", "Y"] di_edges = [("X_1", "W"), ("W", "Y"), ("X_2", "Y")] bi_edges = [("X_1", "W"), ("X_2", "Y"), ("X_1", "X_2")] G = ADMG(vertices, di_edges, bi_edges) interventions = ["X_1", "X_2"] outcomes = ["Y"] ol = identification.OneLineGID(G, interventions, outcomes) functional = ol.functional([{"X_1"}, {"X_2"}]) self.assertEqual( "ΣW ΦX_2,Y p(V \\ X_1 | do(X_1))ΦX_1,W p(V \\ X_2 | do(X_2))", functional)
def test_frontdoor_model(self): vertices = ['A', 'M', 'Y'] di_edges = [('A', 'M'), ('M', 'Y')] bi_edges = [('A', 'Y')] G = ADMG(vertices, di_edges, bi_edges) influence = AutomatedIF(G, 'A', 'Y') print(influence.beta_primal_) print(influence.beta_dual_) print(influence.nonparametric_if_) print(influence.eff_if_) self.assertEqual(influence.eff_if_, influence.nonparametric_if_)
def test_verma_pfixable(self): vertices = ['T', 'M', 'L', 'Y'] di_edges = [('T', 'M'), ('M', 'L'), ('L', 'Y')] bi_edges = [('M', 'Y'), ('T', 'L')] G = ADMG(vertices, di_edges, bi_edges) influence = AutomatedIF(G, 'T', 'Y') print(influence.beta_primal_) print(influence.beta_dual_) print(influence.nonparametric_if_) print(influence.eff_if_) self.assertEqual(influence.eff_if_, "Cannot compute, graph is not mb-shielded.")
def test_get_intrinsic_sets_in_cadmg(self): vertices = ["A", "B", "C"] di_edges = [("A", "B")] bi_edges = [("B", "C"), ("A", "C")] admg = ADMG(vertices=vertices, bi_edges=bi_edges, di_edges=di_edges) admg.fix(["B"]) ig = IG(admg=admg) intrinsic_sets = ig.get_intrinsic_sets() self.assertEqual( {frozenset(["A"]), frozenset(["C"]), frozenset(["A", "C"])}, intrinsic_sets)
def test_check_fixing_order(self): vertices = ["A", "B", "C"] di_edges = [("A", "B")] bi_edges = [("B", "C"), ("A", "C")] admg = ADMG(vertices=vertices, bi_edges=bi_edges, di_edges=di_edges) ig = IG(admg=admg) intrinsic_sets = ig.get_intrinsic_sets() print(intrinsic_sets) fixing_order = ig.iset_fixing_order_map print(fixing_order) self.assertEqual(["C", "A"], fixing_order[frozenset(["B"])])
def test_non_id_graph(self): """ Test that Y(a,b) is not identified """ # non ID test vertices = ['A', 'B', 'C', 'D', 'Y'] di_edges = [('A', 'B'), ('A', 'D'), ('B', 'C'), ('C', 'Y'), ('B', 'D'), ('D', 'Y')] bi_edges = [('A', 'C'), ('B', 'Y'), ('B', 'D')] G = ADMG(vertices, di_edges, bi_edges) one_id = OneLineID(G, ['A', 'B'], ['Y']) self.assertFalse(one_id.id())
def test_p_fixability(self): # First graph: mb-shielded vertices_1 = ['C', 'T', 'M', 'L', 'Y'] di_edges_1 = [('C', 'T'), ('C', 'M'), ('C', 'L'), ('C', 'Y'), ('T', 'M'), ('M', 'L'), ('M', 'Y'), ('L', 'Y')] bi_edges_1 = [('T', 'L'), ('T', 'Y')] G_1 = ADMG(vertices_1, di_edges_1, bi_edges_1) ace_1 = CausalEffect(G_1, 'T', 'Y') self.assertTrue(ace_1.is_mb_shielded) self.assertEqual(ace_1.strategy, "p-fixable") # Second graph: mb-shielded vertices_2 = ['C', 'T', 'M', 'L', 'Y'] di_edges_2 = [('C', 'T'), ('C', 'M'), ('C', 'L'), ('C', 'Y'), ('T', 'M'), ('M', 'L'), ('T', 'Y'), ('L', 'Y')] bi_edges_2 = [('T', 'L'), ('M', 'Y')] G_2 = ADMG(vertices_2, di_edges_2, bi_edges_2) ace_2 = CausalEffect(G_2, 'T', 'Y') self.assertTrue(ace_2.is_mb_shielded) self.assertEqual(ace_2.strategy, "p-fixable") # Third graph: not mb-shielded vertices_3 = ['C1', 'C2', 'Z1', 'Z2', 'T', 'M', 'L', 'Y'] di_edges_3 = [('C1', 'T'), ('C1', 'L'), ('C2', 'M'), ('C2', 'L'), ('C2', 'Y'), ('T', 'M'), ('M', 'L'), ('L', 'Y')] bi_edges_3 = [('Z1', 'C1'), ('Z2', 'C2'), ('T', 'L')] G_3 = ADMG(vertices_3, di_edges_3, bi_edges_3) data = pd.DataFrame() ace_3 = CausalEffect(G_3, 'T', 'Y') self.assertFalse(ace_3.is_mb_shielded) self.assertEqual(ace_3.strategy, "p-fixable") with self.assertRaises(RuntimeError): ace_3.compute_effect(data, "eff-apipw")
def test_is_id(self): vertices = ["X_1", "X_2", "W", "Y"] di_edges = [("X_1", "W"), ("W", "Y"), ("X_2", "Y")] bi_edges = [("X_1", "W"), ("X_2", "Y"), ("X_1", "X_2")] G = ADMG(vertices, di_edges, bi_edges) interventions = ["X_1", "X_2"] outcomes = ["Y"] ol = identification.OneLineGID(G, interventions, outcomes) status = ol.id() self.assertFalse(status) second = ol.id([{"X_1"}, {"X_2"}]) self.assertTrue(second)
def test_bow_arc(self): vertices = ['C', 'T', 'Y'] di_edges = [('C', 'T'), ('C', 'Y'), ('T', 'Y')] bi_edges = [('T', 'Y')] G = ADMG(vertices, di_edges, bi_edges) data = pd.DataFrame() ace = CausalEffect(G, 'T', 'Y') self.assertEqual(ace.strategy, "Not ID") with self.assertRaises(RuntimeError): ace.compute_effect(data, "n-ipw") with self.assertRaises(RuntimeError): ace.compute_effect(data, "anipw")
def run_cauper_loop(CM, df, tabu_edges, columns, options, NUM_PATHS): """This function is used to run cauper in a loop""" # NOTEARS causal model hyperparmas _, notears_edges = CM.learn_notears(df, tabu_edges, 0.75) # get bayesian network from DAG obtained by NOTEARS # bn = BayesianNetwork(sm) fci_edges = CM.learn_fci(df, tabu_edges) # resolve notears_edges and fci_edges and update di_edges, bi_edges = CM.resolve_edges(notears_edges, fci_edges, columns, tabu_edges) # construct mixed graph ADMG G = ADMG(columns, di_edges = di_edges, bi_edges = bi_edges) return G, di_edges, bi_edges
def test_mbshielded_pfixable(self): vertices = ['C1', 'C2', 'Z1', 'Z2', 'T', 'M', 'L', 'Y'] di_edges = [('C1', 'T'), ('C1', 'L'), ('C2', 'T'), ('C2', 'M'), ('C2', 'L'), ('C2', 'Y'), ('T', 'M'), ('M', 'L'), ('L', 'Y')] bi_edges = [('Z1', 'C1'), ('Z2', 'C2'), ('T', 'L')] G = ADMG(vertices, di_edges, bi_edges) influence = AutomatedIF(G, 'T', 'Y') print(influence.beta_primal_) print(influence.beta_dual_) print(influence.nonparametric_if_) print(influence.eff_if_) self.assertNotEqual(influence.eff_if_, influence.nonparametric_if_)
def test_id_graph(self): """ Test that ADMG Y(a) is identified """ vertices = ['A', 'B', 'C', 'D', 'Y'] di_edges = [('A', 'B'), ('A', 'D'), ('B', 'C'), ('C', 'Y'), ('B', 'D'), ('D', 'Y')] bi_edges = [('A', 'C'), ('B', 'Y'), ('B', 'D')] G = ADMG(vertices, di_edges, bi_edges) one_id = OneLineID(G, ['A'], ['Y']) one_id.draw_swig() self.assertTrue(one_id.id()) self.assertEqual({'Y', 'C', 'D', 'B'}, one_id.ystar) one_id.export_intermediates()
def test_a_fixability(self): vertices = ['Z1', 'Z2', 'C1', 'C2', 'T', 'M', 'Y', 'D1', 'D2'] di_edges = [('C1', 'Z1'), ('C1', 'T'), ('C1', 'M'), ('C2', 'Z1'), ('C2', 'T'), ('C2', 'M'), ('Z1', 'Z2'), ('Z2', 'T'), ('T', 'M'), ('M', 'Y'), ('M', 'D1'), ('Y', 'D2'), ('D1', 'D2')] bi_edges = [('Z1', 'T'), ('Z2', 'C1'), ('C2', 'Y'), ('D1', 'Y')] G = ADMG(vertices, di_edges, bi_edges) data = pd.DataFrame() ace = CausalEffect(G, 'T', 'Y') self.assertFalse(ace.is_mb_shielded) self.assertEqual(ace.strategy, "a-fixable") with self.assertRaises(RuntimeError): ace.compute_effect(data, "eff-aipw")