Exemplo n.º 1
0
 def test_delete_operator_3(self):
     G = 100
     p = 20
     for i in range(G):
         A = sempler.generators.dag_avg_deg(p, 3, 1, 1)
         cpdag = utils.dag_to_cpdag(A)
         for x in range(p):
             # Can only apply the operator to X -> Y or X - Y
             for y in np.where(cpdag[x, :] != 0)[0]:
                 for H in utils.subsets(utils.na(y, x, cpdag)):
                     output = ges.delete(x, y, H, cpdag)
                     # Verify the new vstructures
                     vstructs = utils.vstructures(output)
                     for h in H:
                         vstruct = (x, h, y) if x < y else (y, h, x)
                         self.assertIn(vstruct, vstructs)
                     # Verify whole connectivity
                     truth = cpdag.copy()
                     # Remove edge
                     truth[x, y], truth[y, x] = 0, 0
                     # Orient y -> h
                     truth[list(H), y] = 0
                     truth[list(utils.neighbors(x, cpdag) & H), x] = 0
                     self.assertTrue((output == truth).all())
     print("\nExhaustively checked delete operator on %i CPDAGS" % (i + 1))
Exemplo n.º 2
0
 def test_pdag_to_cpdag(self):
     # Now construct PDAGs whose extensions belong to the true MEC,
     # and test that the true CPDAG is recovered
     G = 500
     p = 32
     for g in range(G):
         A = sempler.generators.dag_avg_deg(p, 3, 1, 1)
         # Construct PDAG by undirecting random edges which do not
         # belong to a v-structure.
         # NOTE: I'm proceeding in this awkward way to avoid
         # using functions from the pipeline I'm testing,
         # i.e. ges.utils.order_edges and ges.utils.label_edges
         pdag = A.copy()
         mask_vstructs = np.zeros_like(A)
         for (i, c, j) in utils.vstructures(A):
             mask_vstructs[i, c] = 1
             mask_vstructs[j, c] = 1
         flippable = np.logical_and(A, np.logical_not(mask_vstructs))
         fros, tos = np.where(flippable)
         for (x, y) in zip(fros, tos):
             # Undirect approximately 2/3 of the possible edges
             if np.random.binomial(1, 2 / 3):
                 pdag[y, x] = 1
         # Run and assert
         self.assertTrue(utils.is_consistent_extension(A, pdag))
         truth = utils.dag_to_cpdag(A)
         output = ges.utils.pdag_to_cpdag(pdag)
         self.assertTrue((output == truth).all())
     print("\nChecked PDAG to CPDAG conversion for %d PDAGs" % (g + 1))
Exemplo n.º 3
0
 def test_insert_2(self):
     G = 100
     p = 20
     for i in range(G):
         A = sempler.generators.dag_avg_deg(p, 3, 1, 1)
         cpdag = utils.dag_to_cpdag(A)
         for x in range(p):
             # Can only apply the operator to non-adjacent nodes
             adj_x = utils.adj(x, cpdag)
             Y = set(range(p)) - adj_x
             for y in Y:
                 for T in utils.subsets(utils.neighbors(y, cpdag) - adj_x):
                     # print(x,y,T)
                     output = ges.insert(x, y, T, cpdag)
                     # Verify the new vstructures
                     vstructs = utils.vstructures(output)
                     for t in T:
                         vstruct = (x, y, t) if x < t else (t, y, x)
                         self.assertIn(vstruct, vstructs)
                     # Verify whole connectivity
                     truth = cpdag.copy()
                     # Add edge x -> y
                     truth[x, y] = 1
                     # Orient t -> y
                     truth[list(T), y] = 1
                     truth[y, list(T)] = 0
                     self.assertTrue((output == truth).all())
     print("\nExhaustively checked insert operator on %i CPDAGS" % (i + 1))
Exemplo n.º 4
0
 def test_cpdag_to_cpdag(self):
     # Test by checking that applying the whole pipeline to a CPDAG
     # returns the same CPDAG
     G = 500
     p = 30
     for i in range(G):
         A = sempler.generators.dag_avg_deg(p, 3, 1, 1)
         cpdag = utils.dag_to_cpdag(A)
         # Run and assert
         output = ges.utils.pdag_to_cpdag(cpdag)
         self.assertTrue((output == cpdag).all())
     print("\nChecked CPDAG to CPDAG conversion for %d CPDAGs" % (i + 1))
Exemplo n.º 5
0
 def test_label_edges_2(self):
     # With randomly generated DAGs
     # np.random.seed(42)
     G = 500
     p = 20
     for i in range(G):
         A = sempler.generators.dag_avg_deg(p, 3, 1, 1)
         # Construct expected output
         cpdag = utils.dag_to_cpdag(A)
         undirected = np.logical_and(cpdag, cpdag.T)
         truth = A.copy()
         truth[np.logical_and(truth, undirected)] = -1
         # Run and assert
         ordered = ges.utils.order_edges(A)
         labelled = ges.utils.label_edges(ordered)
         self.assertTrue((labelled == truth).all())
     print("\nChecked edge labelling for %d DAGs" % (i + 1))
Exemplo n.º 6
0
 def test_valid_turn_operators_10(self):
     # Check that all valid turn operators result in a different
     # essential graph
     G = 10
     p = 20
     for i in range(G):
         A = sempler.generators.dag_avg_deg(p, 3, 1, 1)
         cpdag = utils.dag_to_cpdag(A)
         W = A * np.random.uniform(1, 2, A.shape)
         obs_sample = sempler.LGANM(W, (0, 0), (0.5, 1)).sample(n=1000)
         cache = GaussObsL0Pen(obs_sample)
         fro, to = np.where(cpdag != 0)
         for (x, y) in zip(to, fro):
             valid_operators = ges.score_valid_turn_operators(x, y, cpdag, cache)
             # print(i,len(valid_operators))
             for (_, new_A, _, _, _) in valid_operators:
                 new_cpdag = ges.utils.pdag_to_cpdag(new_A)
                 self.assertFalse((cpdag == new_cpdag).all())
     print("\nChecked that valid turn operators result in different MEC for %i CPDAGs" % (i + 1))
Exemplo n.º 7
0
 def test_valid_delete_operators_3(self):
     # Check symmetry of the delete operator when X - Y
     G = 100
     p = 20
     for i in range(G):
         A = sempler.generators.dag_avg_deg(p, 3, 1, 1)
         cpdag = utils.dag_to_cpdag(A)
         W = A * np.random.uniform(1, 2, A.shape)
         obs_sample = sempler.LGANM(W, (0, 0), (0.5, 1)).sample(n=1000)
         cache = GaussObsL0Pen(obs_sample)
         fro, to = np.where(utils.only_undirected(cpdag))
         # Test the operator to all undirected edges
         for (x, y) in zip(fro, to):
             output_a = ges.score_valid_delete_operators(x, y, cpdag, cache)
             output_b = ges.score_valid_delete_operators(y, x, cpdag, cache)
             for (op_a, op_b) in zip(output_a, output_b):
                 # Check resulting state is the same
                 self.assertTrue((op_a[1] == op_b[1]).all())
                 self.assertAlmostEqual(op_a[0], op_b[0])
     print("\nChecked equality of delete operator on undirected edges in %i CPDAGS" % (i + 1))
Exemplo n.º 8
0
 def test_pdag_to_dag_6(self):
     # Check that the resulting extensions are indeed a consistent
     # extensions
     G = 500
     p = 20
     for i in range(G):
         A = sempler.generators.dag_avg_deg(p, 3, 1, 1)
         cpdag = utils.dag_to_cpdag(A)
         self.assertTrue(utils.is_consistent_extension(A, cpdag))
         extension = ges.utils.pdag_to_dag(cpdag, debug=False)
         is_consistent_extension = utils.is_consistent_extension(
             extension, cpdag)
         if not is_consistent_extension:
             print("DAG\n", A)
             print("CPDAG\n", cpdag)
             print("Extension\n", extension)
             utils.is_consistent_extension(extension, cpdag, debug=True)
             # Rerun with outputs
             assert (extension == ges.utils.pdag_to_dag(cpdag,
                                                        debug=True)).all()
             self.assertTrue(is_consistent_extension)
     print("\nChecked PDAG to DAG conversion for %d PDAGs" % (i + 1))