def test_AddNodeToEdge_names(self): "Filling in name parameters should set hypergraph data names." actual = Hypergraph() AddNodeToEdge(actual, 0, 0, "A", "X") AddNodeToEdge(actual, 1, 0, node_name="B") AddNodeToEdge(actual, 1, 1, edge_name="Y") expected = Hypergraph() node_a = expected.node[0] node_b = expected.node[1] edge_x = expected.edge[0] edge_y = expected.edge[1] node_a.edges.append(0) node_a.name = "A" node_b.edges.append(0) node_b.edges.append(1) node_b.name = "B" edge_x.nodes.append(0) edge_x.nodes.append(1) edge_x.name = "X" edge_y.nodes.append(1) edge_y.name = "Y" self.assertEqual(actual, expected)
def test_keep_hg_name(self): _input = Hypergraph() _input.name = "KEEP_ME" AddNodeToEdge(_input, 0, 0) AddNodeToEdge(_input, 0, 1) AddNodeToEdge(_input, 1, 1) actual_hg, removed_list = RemoveRandomConnections(_input, 0) self.assertEqual(actual_hg.name, "KEEP_ME")
def test_AddNodeToEdge_typical(self): "Adds both the node and the edge reference" actual = Hypergraph() AddNodeToEdge(actual, 1, 2) expected = Hypergraph() expected.node[1].edges.append(2) expected.edge[2].nodes.append(1) self.assertEqual(actual, expected)
def test_AddNodeToEdge_dupl(self): "Duplicate calls to AddNodeToEdge should not effect the structure." actual = Hypergraph() AddNodeToEdge(actual, 1, 2) AddNodeToEdge(actual, 1, 2) expected = Hypergraph() expected.node[1].edges.append(2) expected.edge[2].nodes.append(1) self.assertEqual(actual, expected)
def test_removes_node(self): "Removing an edge should automatically remove degree 0 nodes" actual = Hypergraph() AddNodeToEdge(actual, 0, 0) # remove me AddNodeToEdge(actual, 0, 1) AddNodeToEdge(actual, 1, 0) # remove me RemoveEdge(actual, 0) expected = Hypergraph() AddNodeToEdge(expected, 0, 1) self.assertEqual(actual, expected)
def test_RemoveNodeFromEdge_typical(self): actual = Hypergraph() AddNodeToEdge(actual, 1, 2) AddNodeToEdge(actual, 1, 3) RemoveNodeFromEdge(actual, 1, 3) expected = Hypergraph() AddNodeToEdge(expected, 1, 2) self.assertEqual(actual, expected)
def test_typical(self): actual = Hypergraph() AddNodeToEdge(actual, 0, 0) # remove me AddNodeToEdge(actual, 0, 1) AddNodeToEdge(actual, 1, 0) # remove me AddNodeToEdge(actual, 1, 1) RemoveEdge(actual, 0) expected = Hypergraph() AddNodeToEdge(expected, 0, 1) AddNodeToEdge(expected, 1, 1) self.assertEqual(actual, expected)
def test_compress_range(self): original = Hypergraph() AddNodeToEdge(original, 100, 50) AddNodeToEdge(original, 200, 50) AddNodeToEdge(original, 200, 150) original.name = "KEEP ME" compressed, node_map, edge_map = CompressRange(original) restored = Relabel(compressed, node_map, edge_map) SparseArrayEquals(self, ToCsrMatrix(original), ToCsrMatrix(restored)) self.assertEqual(len(compressed.node), max(compressed.node) + 1) self.assertEqual(len(compressed.node), len(original.node)) self.assertEqual(len(compressed.edge), max(compressed.edge) + 1) self.assertEqual(len(compressed.edge), len(original.edge)) self.assertEqual(compressed.name, "KEEP ME")
def test_unweighted_float_model_to_emb(self): hypergraph = Hypergraph() AddNodeToEdge(hypergraph, 0, 0) AddNodeToEdge(hypergraph, 2, 2) node_map = { 0: 0, 2: 1, } edge_map = { 0: 0, 2: 1, } # should start random? dimension = 5 model = UnweightedFloatModel(hypergraph, dimension, 2) emb = KerasModelToEmbedding(hypergraph, model, node_map, edge_map) self.assertEqual(emb.dim, dimension) for node_idx in hypergraph.node: self.assertTrue(node_map[node_idx] in emb.node) self.assertEqual(len(emb.node[node_map[node_idx]].values), dimension) for edge_idx in hypergraph.edge: self.assertTrue(edge_map[edge_idx] in emb.edge) self.assertEqual(len(emb.edge[edge_map[edge_idx]].values), dimension)
def test_small(self): "Should parse each line as a community." actual = SnapCommunityToHypergraph(StringIO("1 2")) expected = Hypergraph() AddNodeToEdge(expected, 1, 0) AddNodeToEdge(expected, 2, 0) self.assertEqual(actual, expected)
def test_typical(self): hypergraph = Hypergraph() AddNodeToEdge(hypergraph, 0, 1) AddNodeToEdge(hypergraph, 2, 2) AddNodeToEdge(hypergraph, 3, 2) actual_node2weight, actual_edge2weight = UniformWeight(hypergraph) expected_node2weight = csr_matrix( [ [0, 1, 0], # node 0 edge 1 [0, 0, 0], # node 1 not present [0, 0, 1], # node 2 edge 2 [0, 0, 1] # node 3 edge 2 ], dtype=np.float32) expected_edge2weight = csr_matrix( [ [0, 0, 0, 0], # no edge 0 [1, 0, 0, 0], # edge 1 node 0 [0, 0, 1, 1] # edge 2 node 2 and 3 ], dtype=np.float32) self.assertSparseAlmostEqual(actual_node2weight, expected_node2weight) self.assertSparseAlmostEqual(actual_edge2weight, expected_edge2weight)
def test_small(self): "Should load one edge. Indices created in order of occurance." _input = [Paper("T", ["A", "B"])] actual = PapersToHypergraph(_input) expected = Hypergraph() AddNodeToEdge(expected, 0, 0, "A", "T") AddNodeToEdge(expected, 1, 0, "B", "T") self.assertEqual(actual, expected)
def test_typical(self): _input = Hypergraph() AddNodeToEdge(_input, 0, 0) AddNodeToEdge(_input, 0, 1) AddNodeToEdge(_input, 0, 2) # delete me AddNodeToEdge(_input, 1, 0) AddNodeToEdge(_input, 1, 1) # Here node/edge 0/1 each have degree 1 # Edge 2 has degree 1 actual = CleanHypergraph(_input, min_degree=2) expected = Hypergraph() AddNodeToEdge(expected, 0, 0) AddNodeToEdge(expected, 0, 1) AddNodeToEdge(expected, 1, 0) AddNodeToEdge(expected, 1, 1) self.assertEqual(actual, expected) self.assertNotEqual(actual, _input)
def test_generator_small(self): raw_text = ("#* T\n" "#@ A;B\n") _input = ParseAMiner(StringIO(raw_text)) actual = PapersToHypergraph(_input) expected = Hypergraph() AddNodeToEdge(expected, 0, 0, "A", "T") AddNodeToEdge(expected, 1, 0, "B", "T") self.assertEqual(actual, expected)
def test_keeps_names(self): _input = Hypergraph() AddNodeToEdge(_input, 0, 0, "A", "X") AddNodeToEdge(_input, 0, 1, "A", "Y") AddNodeToEdge(_input, 1, 1, "B", "Y") actual_hg, removed_list = RemoveRandomConnections(_input, 0) self.assertEqual(actual_hg, _input) self.checkSubset(actual_hg, _input, [])
def test_two_iterations(self): _input = Hypergraph() AddNodeToEdge(_input, 0, 0) # deleted on iter 1 AddNodeToEdge(_input, 0, 1) # deleted on iter 2 AddNodeToEdge(_input, 1, 1) AddNodeToEdge(_input, 1, 2) AddNodeToEdge(_input, 2, 1) AddNodeToEdge(_input, 2, 2) actual = CleanHypergraph(_input, min_degree=2) expected = Hypergraph() AddNodeToEdge(expected, 1, 1) AddNodeToEdge(expected, 1, 2) AddNodeToEdge(expected, 2, 1) AddNodeToEdge(expected, 2, 2) self.assertEqual(actual, expected) self.assertNotEqual(actual, _input)
def test_remove_none(self): _input = Hypergraph() AddNodeToEdge(_input, 0, 0) AddNodeToEdge(_input, 0, 1) AddNodeToEdge(_input, 1, 1) actual_hg, removed_list = RemoveRandomConnections(_input, 0) self.assertEqual(removed_list, []) self.checkSubset(actual_hg, _input, [])
def test_multi_line(self): actual = SnapCommunityToHypergraph(StringIO("1 2\n1 2 3")) expected = Hypergraph() AddNodeToEdge(expected, 1, 0) AddNodeToEdge(expected, 2, 0) AddNodeToEdge(expected, 1, 1) AddNodeToEdge(expected, 2, 1) AddNodeToEdge(expected, 3, 1) self.assertEqual(actual, expected)
def TestHypergraph(): h = Hypergraph() AddNodeToEdge(h, 0, 0) AddNodeToEdge(h, 1, 0) AddNodeToEdge(h, 1, 1) AddNodeToEdge(h, 2, 1) AddNodeToEdge(h, 2, 2) AddNodeToEdge(h, 3, 2) return h
def test_typical(self): "PapersToHypergraph should handle multiple authors / papers" _input = [Paper("X", ["A", "B"]), Paper("Y", ["A", "C"])] actual = PapersToHypergraph(_input) expected = Hypergraph() AddNodeToEdge(expected, 0, 0, "A", "X") AddNodeToEdge(expected, 1, 0, "B", "X") AddNodeToEdge(expected, 0, 1, "A", "Y") AddNodeToEdge(expected, 2, 1, "C", "Y") self.assertEqual(actual, expected)
def test_disconnected_node(self): "Make sure we don't break if we have a totally disconnected node" dim = 2 hg = Hypergraph() AddNodeToEdge(hg, 0, 0) AddNodeToEdge(hg, 1, 0) AddNodeToEdge(hg, 2, 1) actual = EmbedNode2VecClique(hg, dim, disable_pbar=True) self.checkEmbedding(actual, hg, dim) self.assertEqual(actual.method_name, "N2V5_CLIQUE")
def test_file(self): "Parsing should accept a file description without error" with open("test_data/snap_example.cmty.txt") as ifile: actual = SnapCommunityToHypergraph(ifile) expected = Hypergraph() AddNodeToEdge(expected, 1, 0) AddNodeToEdge(expected, 3, 0) AddNodeToEdge(expected, 5, 0) AddNodeToEdge(expected, 3, 1) AddNodeToEdge(expected, 5, 1) AddNodeToEdge(expected, 7, 1) self.assertEqual(actual, expected)
def test_ToCscMatrix_one(self): "Node i in edge j appears as a 1 in row i and col j" _input = Hypergraph() AddNodeToEdge(_input, 1, 2) actual = ToCscMatrix(_input) expected = csr_matrix( [ [0, 0, 0], # node 0 not listed [0, 0, 1] # node 1 in edge 2 ], dtype=np.bool) SparseArrayEquals(self, actual, expected)
def test_remove_all(self): "shouldn't be able to remove all" _input = Hypergraph() AddNodeToEdge(_input, 0, 0) AddNodeToEdge(_input, 0, 1) AddNodeToEdge(_input, 1, 1) actual_hg, removed_list = RemoveRandomConnections(_input, 1) self.assertTrue(0 in actual_hg.node) self.assertTrue(1 in actual_hg.node) self.assertTrue(0 in actual_hg.edge) self.assertTrue(1 in actual_hg.edge) # better not remove the original self.assertNotEqual(actual_hg, _input)
def test_ToCliqueNxGraph_typical(self): "ToCliqueNxGraph should handle a small typical example" _input = Hypergraph() AddNodeToEdge(_input, 0, 0) AddNodeToEdge(_input, 1, 0) AddNodeToEdge(_input, 1, 1) AddNodeToEdge(_input, 2, 1) actual = ToCliqueNxGraph(_input) expected = nx.Graph() expected.add_edge(0, 1) expected.add_edge(1, 2) self.assertTrue(nx.is_isomorphic(actual, expected))
def test_ToCscMatrix_multiple(self): "Converting to csr handles multple nodes and multiple edges" _input = Hypergraph() AddNodeToEdge(_input, 1, 1) AddNodeToEdge(_input, 1, 2) AddNodeToEdge(_input, 2, 0) actual = ToCscMatrix(_input) expected = csr_matrix( [ [0, 0, 0], # node 0 not listed [0, 1, 1], # node 1 in edge 1 & 2 [1, 0, 0] # node 2 in edge 0 ], dtype=np.bool) SparseArrayEquals(self, actual, expected)
def test_edge_one_node(self): "In this case we only have one connection" hypergraph = Hypergraph() AddNodeToEdge(hypergraph, 0, 1) embedding = HypergraphEmbedding() embedding.node[0].values.extend([0, 0]) embedding.node[1].values.extend([1, 0]) actual = GetPersonalizedClassifiers( hypergraph, embedding, per_edge=True, disable_pbar=True) self.assertEqual(len(actual), len(hypergraph.edge)) for edge_idx in hypergraph.edge: self.assertTrue(edge_idx in actual) self.assertTrue(hasattr(actual[edge_idx], "predict"))
def test_ToBipartideNxGraph_typical(self): "ToBipartideNxGraph should handle a typical example. Edges become nodes" _input = Hypergraph() AddNodeToEdge(_input, 0, 0) AddNodeToEdge(_input, 1, 0) AddNodeToEdge(_input, 1, 1) AddNodeToEdge(_input, 2, 1) actual = ToBipartideNxGraph(_input) expected = nx.Graph() expected.add_edge(0, 3) # community 0 from hypergraph becomes node 3 expected.add_edge(1, 3) expected.add_edge(1, 4) expected.add_edge(2, 4) self.assertTrue(nx.is_isomorphic(actual, expected))
def test_edge_all_nodes(self): "In the case where there exist no negative training examples." "We can't crash" hypergraph = Hypergraph() AddNodeToEdge(hypergraph, 0, 1) AddNodeToEdge(hypergraph, 1, 1) embedding = HypergraphEmbedding() embedding.node[0].values.extend([0, 0]) embedding.node[1].values.extend([1, 0]) embedding.edge[1].values.extend([0, 1]) actual = GetPersonalizedClassifiers( hypergraph, embedding, per_edge=True, disable_pbar=True) self.assertEqual(len(actual), len(hypergraph.edge)) for edge_idx in hypergraph.edge: self.assertTrue(edge_idx in actual) self.assertTrue(hasattr(actual[edge_idx], "predict"))
def test_drop_out_of_bounds(self): "If you supply a node-ege pair that is not in the hg, don't report" class AcceptAll(): def predict(self, embeddings): return [1] * len(embeddings) hypergraph = Hypergraph() AddNodeToEdge(hypergraph, 0, 0) embedding = HypergraphEmbedding() embedding.node[0].values.extend([0]) embedding.edge[0].values.extend([0]) potential_links = [[0, 0], [0, 1], [1, 0], [1, 1]] actual = NodeEdgeEmbeddingPrediction( hypergraph, embedding, potential_links, AcceptAll(), disable_pbar=True) expected = [(0, 0)] self.assertEqual(set(actual), set(expected))