def __init__(self, breaks, densities, bin_repr_points, scope=None, type_=None, meta_type=MetaType.DISCRETE): Leaf.__init__(self, scope=scope) self.type = type(self).type if not type_ else type_ self.meta_type = meta_type self.breaks = breaks self.densities = densities self.bin_repr_points = bin_repr_points
def test_sum_one_dimension(self): add_node_likelihood(Leaf, identity_ll) # test that we get basic computations right spn = 0.5 * Leaf(scope=0) + 0.5 * Leaf(scope=0) data = np.random.rand(10, 1) self.assert_correct(spn, data, data) spn = 0.1 * Leaf(scope=0) + 0.9 * Leaf(scope=0) data = np.random.rand(10, 1) self.assert_correct(spn, data, data) # test that we can pass whatever dataset, and the scopes are being respected # this is important for inner nodes spn = 0.1 * Leaf(scope=0) + 0.9 * Leaf(scope=0) data = np.random.rand(10, 3) r = 0.1 * data[:, 0] + 0.9 * data[:, 0] r = r.reshape(-1, 1) self.assert_correct(spn, data, r) # test that it fails if the weights are not normalized spn = 0.1 * Leaf(scope=0) + 0.9 * Leaf(scope=0) spn.weights[1] = 0.2 data = np.random.rand(10, 3) with self.assertRaises(AssertionError): l = likelihood(spn, data) with self.assertRaises(AssertionError): log_likelihood(spn, data) # test the log space spn = 0.1 * Leaf(scope=0) + 0.9 * Leaf(scope=0) data = np.random.rand(10, 3) r = 0.1 * data[:, 0] + 0.9 * data[:, 0] r = r.reshape(-1, 1) self.assert_correct(spn, data, r)
def test_bfs(self): D = Leaf(scope=[0]) E = Leaf(scope=[0]) F = Leaf(scope=[0]) B = 0.5 * D + 0.5 * E C = 0.5 * E + 0.5 * F A = 0.5 * B + 0.5 * C result = [] def add_node(node): result.append(node) bfs(A, add_node) self.assertEqual(result[0], A) self.assertEqual(result[1], B) self.assertEqual(result[2], C) self.assertEqual(result[3], D) self.assertEqual(result[4], E) self.assertEqual(result[5], F) self.assertEqual(len(result), 6)
def __init__(self, scope=None, data=None): self._type = Type.BINARY Leaf.__init__(self, scope=scope) assert data is not None self.n_features = data.shape[1]
def __init__(self, unique_vals, mean, inverted_mean, square_mean, inverted_square_mean, prob_sum, null_value_prob, scope=None): """ Instead of histogram remember individual values. :param unique_vals: all possible values in leaf :param mean: mean of not null values :param inverted_mean: inverted mean of not null values :param square_mean: mean of squared not null values :param inverted_square_mean: mean of 1/squared not null values :param prob_sum: cumulative sum of probabilities :param null_value_prob: proportion of null values in the leaf :param scope: """ Leaf.__init__(self, scope=scope) self.unique_vals = unique_vals self.mean = mean self.inverted_mean = inverted_mean self.square_mean = square_mean self.inverted_square_mean = inverted_square_mean self.prob_sum = prob_sum # ok, err = is_valid_prob_sum(self, self.unique_vals, n.cardinality) # assert ok, err self.null_value_prob = null_value_prob
def __init__(self, x_range, y_range, bin_repr_points, scope=None): Leaf.__init__(self, scope=scope) self._type = type self.x_range = x_range self.y_range = y_range self.bin_repr_points = bin_repr_points
def test_sum_multiple_dimension(self): add_node_likelihood(Leaf, identity_ll) # test basic computations in multiple dimensions spn = 0.5 * Leaf(scope=[0, 1]) + 0.5 * Leaf(scope=[0, 1]) data = np.random.rand(10, 2) l = likelihood(spn, data) self.assert_correct(spn, data, data[:, 0] * data[:, 1])
def test_prod_multiple_dimension(self): add_node_likelihood(Leaf, sums_ll) # test basic computations in multiple dimensions spn = Leaf(scope=[0, 1]) * Leaf(scope=[2, 3]) data = np.random.rand(10, 4) r = (data[:, 0] + data[:, 1]) * (data[:, 2] + data[:, 3]) self.assert_correct(spn, data, r)
def setUp(self): self.D = Leaf(scope=[0]) self.E = Leaf(scope=[0]) self.F = Leaf(scope=[0]) self.B = 0.5 * self.D + 0.5 * self.E self.C = 0.5 * self.E + 0.5 * self.F self.A = 0.5 * self.B + 0.5 * self.C
def test_topological_order_for_tree(self): D = Leaf(scope=[0]) E = Leaf(scope=[0]) F = Leaf(scope=[0]) B = 0.5 * D + 0.5 * E C = 0.5 * E + 0.5 * F A = 0.5 * B + 0.5 * C A.aname = "A" B.aname = "B" C.aname = "C" D.aname = "D" E.aname = "E" F.aname = "F" result = get_topological_order(A) self.assertEqual(result[0], D) self.assertEqual(result[1], E) self.assertEqual(result[2], F) self.assertEqual(result[3], B) self.assertEqual(result[4], C) self.assertEqual(result[5], A) self.assertEqual(len(result), 6)
def __init__(self, breaks, densities, bin_repr_points, scope=None, meta_type=MetaType.REAL): Leaf.__init__(self, scope=scope) self.meta_type = meta_type self.breaks = breaks self.densities = densities self.bin_repr_points = bin_repr_points
def test_type(self): add_node_likelihood(Leaf, identity_ll) # test that we get basic computations right spn = 0.5 * Leaf(scope=[0, 1]) + 0.5 * (Leaf(scope=0) * Leaf(scope=1)) data = np.random.rand(10, 4) l = likelihood(spn, data, dtype=np.float32) self.assertEqual(l.dtype, np.float32) l = likelihood(spn, data, dtype=np.float128) self.assertEqual(l.dtype, np.float128)
def test_prod_one_dimension(self): add_node_likelihood(Leaf, identity_ll) # test basic product spn = Leaf(scope=0) * Leaf(scope=1) data = np.random.rand(10, 2) self.assert_correct(spn, data, data[:, 0] * data[:, 1]) # test respecting the scopes spn = Leaf(scope=0) * Leaf(scope=1) data = np.random.rand(10, 3) self.assert_correct(spn, data, data[:, 0] * data[:, 1])
def test_hierarchical_sum_multiple_dimension(self): add_node_likelihood(Leaf, identity_ll) # test basic computations in a hierarchy spn = 0.3 * (0.2 * Leaf(scope=[0, 1]) + 0.8 * Leaf(scope=[0, 1])) + 0.7 * ( 0.4 * Leaf(scope=[0, 1]) + 0.6 * Leaf(scope=[0, 1]) ) data = np.random.rand(10, 3) self.assert_correct(spn, data, data[:, 0] * data[:, 1]) add_node_likelihood(Leaf, multiply_ll) # test different node contributions spn = 0.3 * (0.2 * Leaf(scope=[0, 1]) + 0.8 * Leaf(scope=[0, 1])) + 0.7 * ( 0.4 * Leaf(scope=[0, 1]) + 0.6 * Leaf(scope=[0, 1]) ) spn.children[0].children[0].multiplier = 2 spn.children[0].children[1].multiplier = 3 spn.children[1].children[0].multiplier = 4 spn.children[1].children[1].multiplier = 5 data = np.random.rand(10, 3) dprod = data[:, 0] * data[:, 1] r = 0.3 * (0.2 * 2 * dprod + 0.8 * 3 * dprod) + 0.7 * (0.4 * 4 * dprod + 0.6 * 5 * dprod) self.assert_correct(spn, data, r)
def test_correct_parameters(self): node_1_2_2 = Leaf(0) node_1_2_1 = Leaf(1) node_1_1 = Leaf([0, 1]) node_1_2 = node_1_2_1 * node_1_2_2 spn = 0.1 * node_1_1 + 0.9 * node_1_2 node_1_2.id = 0 rand_gen = RandomState(1234) with self.assertRaises(AssertionError): mpe(spn, rand_gen.rand(10, 3)) assign_ids(spn) node_1_2_2.id += 1 with self.assertRaises(AssertionError): mpe(spn, rand_gen.rand(10, 3))
def test_sum(self): spn = Product() for s in range(7): spn.children.append(Leaf(scope=s)) new_spn = SPN_Reshape(spn, 2) print(spn)
def test_sum(self): spn = Product() for s in range(7): spn.children.append(Leaf(scope=s)) assign_ids(spn) rebuild_scopes_bottom_up(spn) new_spn = SPN_Reshape(spn, 2) print(spn)
def test_topological_order_for_non_tree(self): D = Leaf(scope=[0]) E = Leaf(scope=[0]) F = Leaf(scope=[0]) B = 0.5 * D + 0.5 * E C = 0.5 * E + 0.5 * F H = 0.5 * D + 0.5 * E I = 0.5 * D + 0.5 * E G = 0.5 * H + 0.5 * I A = 0.5 * B + 0.5 * C Z = 0.5 * A + 0.5 * G Z.aname = "Z" A.aname = "A" B.aname = "B" C.aname = "C" D.aname = "D" E.aname = "E" F.aname = "F" G.aname = "G" H.aname = "H" I.aname = "I" result = get_topological_order(Z) self.assertEqual(result[0], D) self.assertEqual(result[1], E) self.assertEqual(result[2], F) self.assertEqual(result[3], B) self.assertEqual(result[4], H) self.assertEqual(result[5], I) self.assertEqual(result[6], C) self.assertEqual(result[7], G) self.assertEqual(result[8], A) self.assertEqual(result[9], Z) self.assertEqual(len(result), 10) layers = get_topological_order_layers(Z) self.assertEqual(set(layers[0]), set([D, E, F])) self.assertEqual(set(layers[1]), set([I, H, B, C])) self.assertEqual(set(layers[2]), set([G, A])) self.assertEqual(set(layers[3]), set([Z]))
def test_hierarchical_prod_multiple_dimension(self): add_node_likelihood(Leaf, identity_ll) # test basic computations in a hierarchy spn = (Leaf(scope=[0, 1]) * Leaf(scope=[2, 3])) * (Leaf(scope=[4, 5]) * Leaf(scope=[6, 7])) data = np.random.rand(10, 8) self.assert_correct(spn, data, np.prod(data, axis=1)) add_node_likelihood(Leaf, sums_ll) # test different node contributions spn = (Leaf(scope=[0, 1]) * Leaf(scope=[2, 3])) * (Leaf(scope=[4, 5]) * Leaf(scope=[6, 7])) data = np.random.rand(10, 10) dprod = (data[:, 0] + data[:, 1]) * (data[:, 2] + data[:, 3]) * (data[:, 4] + data[:, 5]) * ( data[:, 6] + data[:, 7]) self.assert_correct(spn, data, dprod)
def __init__(self, unique_vals, probabilities, null_value, scope, cardinality=0): """ Instead of histogram remember individual values. :param unique_vals: all possible values in leaf :param mean: mean of not null values :param inverted_mean: inverted mean of not null values :param square_mean: mean of squared not null values :param inverted_square_mean: mean of 1/squared not null values :param prob_sum: cumulative sum of probabilities :param null_value_prob: proportion of null values in the leaf :param scope: """ Leaf.__init__(self, scope=scope) if not isinstance(unique_vals, np.ndarray): unique_vals = np.array(unique_vals) self.unique_vals = unique_vals self.cardinality = cardinality self.null_value = null_value self.unique_vals_idx = None self.update_unique_vals_idx() # will be updated later self.prob_sum = None self.null_value_prob = None self.mean = None self.inverted_mean = None self.square_mean = None self.inverted_square_mean = None if not isinstance(probabilities, np.ndarray): probabilities = np.array(probabilities) self.update_from_new_probabilities(probabilities)
def test_hierarchical_sum_one_dimension(self): add_node_likelihood(Leaf, identity_ll) # test basic computations in a hierarchy + respecting the scopes spn = 0.3 * (0.2 * Leaf(scope=0) + 0.8 * Leaf(scope=0)) + 0.7 * ( 0.4 * Leaf(scope=0) + 0.6 * Leaf(scope=0)) data = np.random.rand(10, 3) self.assert_correct(spn, data, data[:, 0]) add_node_likelihood(Leaf, multiply_ll) # test that the different nodes contribute differently spn = 0.3 * (0.2 * Leaf(scope=0) + 0.8 * Leaf(scope=0)) + 0.7 * ( 0.4 * Leaf(scope=0) + 0.6 * Leaf(scope=0)) spn.children[0].children[0].multiplier = 2 spn.children[0].children[1].multiplier = 3 spn.children[1].children[0].multiplier = 4 spn.children[1].children[1].multiplier = 5 data = np.random.rand(10, 3) r = 0.3 * (0.2 * 2 * data[:, 0] + 0.8 * 3 * data[:, 0]) + 0.7 * ( 0.4 * 4 * data[:, 0] + 0.6 * 5 * data[:, 0]) self.assert_correct(spn, data, r)
def __init__(self, breaks, densities, bin_repr_points, scope=None): Leaf.__init__(self, scope=scope) self.breaks = breaks self.densities = densities self.bin_repr_points = bin_repr_points
def __init__(self, vals, mean, scope=None): Leaf.__init__(self, scope=scope) self.vals = vals self.mean = mean
def leaf(scope, multiplier): l = Leaf(scope=scope) l.multiplier = multiplier return l
def __init__(self, type, scope=None): Leaf.__init__(self, scope=scope) self._type = type
def __init__(self, type, scope=None, weights=None, evidence_size=None): Leaf.__init__(self, scope=scope) self._type = type self.evidence_size = evidence_size self.weights = weights
def __init__(self, val, scope=None): Leaf.__init__(self, scope=scope) self.val = val