示例#1
0
 def test_get_multiplied(self):
     factor1 = Factor([self.random_variables[0], self.random_variables[1]])
     factor2 = Factor([self.random_variables[1], self.random_variables[2]])
     factor1.add_value([1, 3], 10).add_value([1, 4], 20).add_value([2, 4],
                                                                   30)
     factor2.add_value([3, 2], 5).add_value([4, 2], 2)
     product_factor = factor1.get_multiplied(factor2)
     self.assertEqual(product_factor.get_value({
         'x': 1,
         'y': 3,
         'z': 2
     }), 50)
     self.assertEqual(product_factor.get_value({
         'x': 1,
         'y': 4,
         'z': 2
     }), 40)
     self.assertEqual(product_factor.get_value({
         'x': 2,
         'y': 4,
         'z': 2
     }), 60)
     self.assertEqual(product_factor.get_value({'x': 1, 'y': 5, 'z': 2}), 0)
     self.assertEqual(product_factor.get_value({'x': 2, 'y': 5, 'z': 2}), 0)
     self.assertEqual(product_factor.get_value({'x': 2, 'y': 5, 'z': 2}), 0)
示例#2
0
def generate_complete(nb_vars, delta):
    model = GraphicalModel()
    interaction = delta * np.random.uniform(
        -1.0, 1.0, nb_vars*(nb_vars-1))
    bias = np.random.uniform(-0.1, 0.1, [nb_vars])

    for i in range(nb_vars):
        model.add_variable(ith_object_name('V', i))

    for i in range(nb_vars):
        for j in range(i+1, nb_vars):
            beta = interaction[i * nb_vars + j ]
            log_values = np.array([beta, -beta, -beta, beta]).reshape([2,2])
            factor = Factor(
                name = ijth_object_name('F', i, j),
                variables = [ith_object_name('V', i), ith_object_name('V', j)],
                log_values = log_values)
            model.add_factor(factor)

    for i in range(nb_vars):
        factor = Factor(
            name = ith_object_name('B', i),
            variables = [ith_object_name('V', i)],
            log_values = np.array([bias[i], -bias[i]]))
        model.add_factor(factor)

    return model
示例#3
0
 def test_add_factors(self):
     graphical_model = GraphicalModel()
     factor1 = Factor([RandomVariable('x', (1, 2))])
     factor2 = Factor(
         [RandomVariable('y', (2, 3, 4)),
          RandomVariable('z', (2, ))])
     factor3 = Factor(
         [RandomVariable('x', (1, 2)),
          RandomVariable('z', (2, ))])
     graphical_model.add_factor(factor1).add_factor(factor2).add_factor(
         factor3)
     print(graphical_model.random_variables)
 def test_cycle(self):
     xy_factor = Factor(
         [self.random_variables[0], self.random_variables[1]])
     xz_factor = Factor(
         [self.random_variables[0], self.random_variables[2]])
     yz_factor = Factor(
         [self.random_variables[1], self.random_variables[2]])
     graphical_model = GraphicalModel()
     graphical_model.add_factor(xy_factor).add_factor(xz_factor).add_factor(
         yz_factor)
     marginal_inference = MpMarginalInference(graphical_model)
     marginal_inference.get_marginal_factor([self.random_variables[0]], {})
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.random_variables = [
         RandomVariable('a', (1, 2)),
         RandomVariable('b', (3, 4, 5)),
         RandomVariable('c', (2, )),
         RandomVariable('d', (1, 2, 3, 4, 5, 6)),
     ]
     self.factors = [
         Factor([self.random_variables[0]]),
         Factor([self.random_variables[0], self.random_variables[1]]),
         Factor([self.random_variables[1], self.random_variables[2]])
     ]
 def _generate_two_variables_model(self):
     x_factor = Factor([self.random_variables[0]])
     x_factor.add_value([1], 1).add_value([2], 2)
     y_factor = Factor([self.random_variables[1]])
     y_factor.add_value([3], 5).add_value([4], 10).add_value([5], 15)
     xy_factor = Factor(
         [self.random_variables[0], self.random_variables[1]])
     xy_factor.add_value([1, 3], 10).add_value([1, 4], 10).add_value([2, 5],
                                                                     20)
     graphical_model = GraphicalModel()
     graphical_model.add_factor(x_factor).add_factor(y_factor).add_factor(
         xy_factor)
     return graphical_model
 def _generate_three_variables_model(self):
     xy_factor = Factor(
         [self.random_variables[0], self.random_variables[1]])
     xy_factor.add_value([1, 3], 5).add_value([1, 4], 20).add_value([2, 5],
                                                                    30)
     xz_factor = Factor(
         [self.random_variables[0], self.random_variables[2]])
     xz_factor.add_value([1, 2], 10).add_value([2, 2], 20)
     yz_factor = Factor(
         [self.random_variables[1], self.random_variables[2]])
     yz_factor.add_value([3, 2], 10).add_value([4, 2], 20).add_value([5, 2],
                                                                     30)
     graphical_model = GraphicalModel()
     graphical_model.add_factor(xy_factor).add_factor(xz_factor).add_factor(
         yz_factor)
     return graphical_model
示例#8
0
def _get_clique_factors(jt_cliques, factors):
    """
    Assign node factors to cliques in the junction tree and derive the clique factors.

    Args:
        jt_cliques: list of junction tree maximal cliques e.g. [[x1, x2, x3], [x2, x3], ... ]
        factors: list of factors from the original graph

    Returns:
        list of clique factors where the factor(jt_cliques[i]) = clique_factors[i]
    """
    clique_factors = [Factor() for _ in jt_cliques]
    """ YOUR CODE HERE """
    for i in range(len(clique_factors)):
        jt_clique = jt_cliques[i]
        temp_factor = factors.copy()
        for factor in temp_factor:
            ret = list(set(jt_clique).intersection(list(factor.var)))
            if sorted(ret) == sorted(list(factor.var)):
                clique_factors[i] = factor_product(clique_factors[i], factor)
                factors.remove(factor)
    """ END YOUR CODE HERE """

    assert len(clique_factors) == len(
        jt_cliques
    ), 'there should be equal number of cliques and clique factors'
    return clique_factors
示例#9
0
    def _update_reparameterization_for_(self, variable):
        belief_from_ = dict()
        log_average_belief = 0.0
        average_weight = 0.0
        for rvar in self.variables_replicated_from_[variable]:
            belief_from_[rvar] = self.get_marginals_upper_to_(rvar)
            belief_from_[rvar].marginalize_except_([rvar])
            belief_from_[rvar].variables = [variable]
            belief_from_[rvar].normalize()
            log_average_belief = (
                log_average_belief +
                self.holder_weights_for_[rvar] * belief_from_[rvar].log_values)

        converge_flag = True
        for rvar in self.variables_replicated_from_[variable]:
            if np.sum(
                    np.abs(-belief_from_[rvar].log_values +
                           log_average_belief)) > 1e-2:
                converge_flag = False
                temp_log_val = (self.holder_weights_for_[rvar]) * (
                    -belief_from_[rvar].log_values + log_average_belief)
                temp = Factor("", [rvar], log_values=temp_log_val)
                self.factor_upper_to_[rvar].product(temp)

        return converge_flag
示例#10
0
def factor_marginalize(factor, var):
    """Sums over a list of variables.

    Args:
        factor (Factor): Input factor
        var (List): Variables to marginalize out

    Returns:
        out: Factor with variables in 'var' marginalized out.
    """
    out = Factor()
    """ YOUR CODE HERE
    Marginalize out the variables given in var
    """

    out.var = np.setxor1d(factor.var, np.array(var))

    for out_var in out.var:
        index = np.where(factor.var == out_var)
        out.card = np.append(out.card, factor.card[index])

    assignment = factor.get_all_assignments()
    index = []
    for single_var in var:
        index.append(np.where(factor.var == single_var))

    assignment = np.delete(assignment, index, axis=1)

    out.val = np.zeros(np.prod(out.card))
    for i in np.unique(assignment, axis=0):
        index_set = np.array(np.where(np.all(i == assignment, axis=1)))
        single_assignment = assignment_to_index(i, out.card)
        out.val[single_assignment] = np.sum(factor.val[index_set])
    return out
示例#11
0
def factor_sum(A, B):
    """Same as factor_product, but sums instead of multiplies
    """
    if A.is_empty():
        return B
    if B.is_empty():
        return A

    # Create output factor. Variables should be the union between of the
    # variables contained in the two input factors
    out = Factor()
    out.var = np.union1d(A.var, B.var)

    # Compute mapping between the variable ordering between the two factors
    # and the output to set the cardinality
    out.card = np.zeros(len(out.var), np.int64)
    mapA = np.argmax(out.var[None, :] == A.var[:, None], axis=-1)
    mapB = np.argmax(out.var[None, :] == B.var[:, None], axis=-1)
    out.card[mapA] = A.card
    out.card[mapB] = B.card

    # For each assignment in the output, compute which row of the input factors
    # it comes from
    out.val = np.zeros(np.prod(out.card))
    assignments = out.get_all_assignments()
    idxA = assignment_to_index(assignments[:, mapA], A.card)
    idxB = assignment_to_index(assignments[:, mapB], B.card)
    """ YOUR CODE HERE
    You should populate the .val field with the factor sum. The code for this
    should be very similar to the factor_product().
    """
    out.val = A.val[idxA] + B.val[idxB]

    return out
示例#12
0
 def test_get_max_marginalized(self):
     init_factor = Factor(self.random_variables)
     init_factor.add_value([1, 3, 2], 10).add_value([1, 4, 2],
                                                    5).add_value([1, 5, 2],
                                                                 2)
     init_factor.add_value([2, 4, 2], 20).add_value([2, 5, 2], 30)
     factor, assignment = init_factor.get_max_marginalized(
         [self.random_variables[0]])
     marginalized_variables = [
         self.random_variables[1], self.random_variables[2]
     ]
     self.assertEqual(20, factor.get_value({'y': 4, 'z': 2}))
     self.assertEqual(30, factor.get_value({'y': 5, 'z': 2}))
     self.assertEqual(10, factor.get_value({'y': 3, 'z': 2}))
     variable_permutation = list(
         map(lambda x: factor.random_variables.index(x),
             marginalized_variables))
     mapped_assignment = {}
     for key, value in assignment.items():
         mapped_key = tuple(
             map(lambda x: key[variable_permutation[x]], range(len(key))))
         mapped_assignment[mapped_key] = value
     self.assertEqual({
         (3, 2): (1, ),
         (4, 2): (2, ),
         (5, 2): (2, )
     }, mapped_assignment)
     factor, assignment = init_factor.get_max_marginalized(
         self.random_variables)
     self.assertEqual(30, factor.get_value([]))
     self.assertEqual({(): (2, 5, 2)}, assignment)
示例#13
0
def _sample_step(nodes, proposal_factors):
    """
    Performs one iteration of importance sampling where it should sample a sample for each node. The sampling should
    be done in topological order.

    Args:
        nodes: numpy array of nodes. nodes are sampled in the order specified in nodes
        proposal_factors: dictionary of proposal factors where proposal_factors[1] returns the
                sample distribution for node 1

    Returns:
        dictionary of node samples where samples[1] return the scalar sample for node 1.
    """
    samples = {}
    """ YOUR CODE HERE: Use np.random.choice """

    evidence = {}
    fac = Factor()
    for node in nodes:
        fac = factor_evidence(proposal_factors[node], evidence)
        n = np.random.choice(fac.card[0], 1, p=fac.val)
        samples[node] = n
        evidence[node] = n
    """ END YOUR CODE HERE """

    assert len(samples.keys()) == len(nodes)
    return samples
 def test_two_variables(self):
     x_factor = Factor([self.random_variables[0]])
     x_factor.add_value([1], 1).add_value([2], 2)
     y_factor = Factor([self.random_variables[1]])
     y_factor.add_value([3], 5).add_value([4], 10).add_value([5], 15)
     xy_factor = Factor(
         [self.random_variables[0], self.random_variables[1]])
     xy_factor.add_value([1, 3], 10).add_value([1, 4], 10).add_value([2, 5],
                                                                     20)
     graphical_model = GraphicalModel()
     graphical_model.add_factor(x_factor).add_factor(y_factor).add_factor(
         xy_factor)
     marginal_inference = MpMarginalInference(graphical_model)
     marginal_factor = marginal_inference.get_marginal_factor(
         self.random_variables[0])
     self.assertAlmostEqual(0.2, marginal_factor.get_value([1]))
     self.assertAlmostEqual(0.8, marginal_factor.get_value([2]))
示例#15
0
 def test_get_value(self):
     factor = Factor(self.random_variables)
     factor.add_value([1, 3, 2], 10).add_value([2, 4, 2],
                                               20).add_value([2, 5, 2], 30)
     self.assertEqual(factor.get_value([1, 3, 2]), 10)
     self.assertEqual(factor.get_value([2, 4, 2]), 20)
     self.assertEqual(factor.get_value([2, 5, 2]), 30)
     self.assertEqual(factor.get_value([1, 4, 2]), 0)
     self.assertEqual(factor.get_value([2, 3, 2]), 0)
示例#16
0
    def _makeFactor(self, node, observed, log):
        nodes = np.array([node] + self.network.parents[node])
        probs = self.network.probabilities[node].values

        nodes_in_observed = nodes[np.in1d(nodes, observed.keys())]
        if nodes_in_observed.size > 0:
            if nodes.size > nodes_in_observed.size:
                factor = Factor(nodes, probs, self.network)

                log.write("\nReduce\n")
                log.write(str(factor))
                log.write("Evidence: " + str(observed) + "\n\n")

                return factor.reduce(nodes_in_observed, observed)
            else:
                return Factor()
        else:
            return Factor(nodes, probs, self.network)
 def test_marginal_y_three_variables(self):
     x_factor = Factor([self.random_variables[0]])
     x_factor.add_value([1], 1).add_value([2], 2)
     xy_factor = Factor(
         [self.random_variables[0], self.random_variables[1]])
     xy_factor.add_value([1, 3], 5).add_value([1, 4], 20).add_value([2, 5],
                                                                    30)
     xz_factor = Factor(
         [self.random_variables[0], self.random_variables[2]])
     xz_factor.add_value([1, 2], 12).add_value([2, 2], 20)
     graphical_model = GraphicalModel()
     graphical_model.add_factor(x_factor).add_factor(xy_factor).add_factor(
         xz_factor)
     marginal_inference = MpMarginalInference(graphical_model)
     marginal_factor = marginal_inference.get_marginal_factor(
         self.random_variables[1])
     self.assertAlmostEqual(0.04, marginal_factor.get_value([3]))
     self.assertAlmostEqual(0.16, marginal_factor.get_value([4]))
     self.assertAlmostEqual(0.8, marginal_factor.get_value([5]))
示例#18
0
 def test_get_constant_multiplied(self):
     factor = Factor(self.random_variables)
     factor.add_value([1, 3, 2], 10).add_value([2, 4, 2],
                                               20).add_value([2, 5, 2], 30)
     factor = factor.get_constant_multiplied(2)
     self.assertEqual(factor.get_value([1, 3, 2]), 20)
     self.assertEqual(factor.get_value([2, 4, 2]), 40)
     self.assertEqual(factor.get_value([2, 5, 2]), 60)
     self.assertEqual(factor.get_value([1, 4, 2]), 0)
     self.assertEqual(factor.get_value([2, 3, 2]), 0)
示例#19
0
def generate_grid(nb_vars, delta):
    model = GraphicalModel()

    grid_size = int(nb_vars**0.5)
    interaction = delta * np.random.uniform(-1.0, 1.0, 2*grid_size*(grid_size-1))
    bias = np.random.uniform(-0.1, 0.1, [grid_size,grid_size])

    for i in range(grid_size):
        for j in range(grid_size):
            model.add_variable(ijth_object_name('V', i,j))

    edge_set = []
    for x in range(grid_size*grid_size):
        q, m = divmod(x, grid_size)
        if m != grid_size-1:
            edge_set.append([x,x+1])

        if q != grid_size-1:
            edge_set.append([x,x+grid_size])

    for i, e in enumerate(edge_set):
        beta = interaction[i]

        q1, m1 = divmod(e[0], grid_size)
        V1 = ijth_object_name('V', q1,m1)

        q2, m2 = divmod(e[1],grid_size)
        V2 = ijth_object_name('V', q2,m2)

        log_values = np.array([beta, -beta, -beta, beta]).reshape([2,2])
        factor = Factor(name = ith_object_name('F', i),
                        variables = [V1, V2],
                        log_values = log_values)
        model.add_factor(factor)

    for i in range(grid_size):
        for j in range(grid_size):
            log_values = np.array([bias[i,j], -bias[i,j]])
            model.add_factor(Factor(name = ith_object_name('B', i*grid_size + j),
                                 variables = [ijth_object_name('V', i,j)],
                                 log_values = log_values))

    return model
示例#20
0
 def test_get_inverse(self):
     factor = Factor(self.random_variables)
     factor.add_value([1, 3, 2], 10).add_value([2, 4, 2],
                                               20).add_value([2, 5, 2], 30)
     factor = factor.get_inverse()
     self.assertEqual(factor.get_value([1, 3, 2]), 1 / 10)
     self.assertEqual(factor.get_value([2, 4, 2]), 1 / 20)
     self.assertEqual(factor.get_value([2, 5, 2]), 1 / 30)
     self.assertEqual(factor.get_value([1, 4, 2]), float("inf"))
     self.assertEqual(factor.get_value([2, 3, 2]), float("inf"))
示例#21
0
def compute_marginals_naive(V, factors, evidence):
    """Computes the marginal over a set of given variables

    Args:
        V (int): Single Variable to perform inference on
        factors (List[Factor]): List of factors representing the graphical model
        evidence (Dict): Observed evidence. evidence[k] = v indicates that
          variable k has the value v.

    Returns:
        Factor representing the marginals
    """

    output = Factor()

    # compute the joint distribution
    joint_distribution = compute_joint_distribution(factors)
    variables = factors[0].var
    for factor_index in range(1, len(factors)):
        variables = np.union1d(variables, factors[factor_index].var)

    evidence_keys = list(evidence.keys())
    evidence_keys.append(V)
    variables_need_marginalize = np.setxor1d(variables,
                                             np.array(evidence_keys))
    after_marginalize = factor_marginalize(joint_distribution,
                                           variables_need_marginalize)

    after_observe = observe_evidence([after_marginalize], evidence)[0]
    ##Normalize
    normalize_sum = np.sum(after_observe.val)
    after_observe.val /= normalize_sum

    # delete evidence, evidence value inequal to evidence needs to be delete, also card, also var
    assignment = after_observe.get_all_assignments()
    for evid in evidence:
        temp_value = evidence[evid]
        delete_index = np.array(np.where(after_observe.var == evid))[0][0]
        assignment_delete_index = np.array(
            np.where(assignment[:, delete_index] != temp_value))
        after_observe.var = np.delete(after_observe.var, delete_index)
        after_observe.card = np.delete(after_observe.card, delete_index)
        after_observe.val = np.delete(after_observe.val,
                                      assignment_delete_index,
                                      axis=0)
        assignment = np.delete(assignment, assignment_delete_index, axis=0)
        assignment = np.delete(assignment, delete_index, axis=1)

    output = after_observe
    """ YOUR CODE HERE
    Compute the marginal. Output should be a factor.
    Remember to normalize the probabilities!
    """

    return output
示例#22
0
 def test_get_normalized(self):
     factor = Factor(self.random_variables)
     factor.add_value([1, 3, 2], 10).add_value([2, 4, 2],
                                               20).add_value([2, 5, 2], 30)
     factor = factor.get_normalized()
     self.assertAlmostEquals(1 / 6, factor.get_value([1, 3, 2]))
     self.assertAlmostEquals(1 / 3, factor.get_value([2, 4, 2]))
     self.assertAlmostEquals(1 / 2, factor.get_value([2, 5, 2]))
     self.assertAlmostEquals(0, factor.get_value([1, 4, 2]))
     self.assertAlmostEquals(0, factor.get_value([1, 5, 2]))
     self.assertAlmostEquals(0, factor.get_value([2, 3, 2]))
示例#23
0
 def test_get_sum_marginalized(self):
     init_factor = Factor(self.random_variables)
     init_factor.add_value([1, 3, 2], 10).add_value([1, 4, 2],
                                                    5).add_value([1, 5, 2],
                                                                 2)
     init_factor.add_value([2, 4, 2], 20).add_value([2, 5, 2], 30)
     factor = init_factor.get_sum_marginalized([self.random_variables[0]])
     self.assertEqual(25, factor.get_value({'y': 4, 'z': 2}))
     self.assertEqual(32, factor.get_value({'y': 5, 'z': 2}))
     self.assertEqual(10, factor.get_value({'y': 3, 'z': 2}))
     factor = init_factor.get_sum_marginalized(self.random_variables)
     self.assertEqual(67, factor.get_value([]))
示例#24
0
def cal_prop_dist(nodes, proposal_factors):
    # I choose factors in the following way: factor.var = [0,1,2] means p(x2|x0, x1). So when we want to choose q(x2), \
    # we just need to find p(x2|x0, x1) = q(x2), we use factor.var[-1] == node
    fac = Factor()
    factors = proposal_factors.copy()
    for node in nodes:
        for index in factors:
            if node == factors[index].var[-1]:
                fac = factor_product(fac, factors[index])
                factors.pop(index)
                break
    return fac
示例#25
0
def ComputeMarginal(jt_cliques, jt_edges, jt_clique_factors, msg):
    output = []
    for i in range(len(jt_cliques)):
        Neighbors_i = Find_Neighbors(jt_edges, i)
        msg_product = Factor()
        for j in range(len(Neighbors_i)):
            msg_product = factor_product(msg_product, msg[Neighbors_i[j]][i])
        msg_product = factor_product(jt_clique_factors[i], msg_product)
        normalize_sum = np.sum(msg_product.val)
        msg_product.val = msg_product.val / (normalize_sum * 1.0)
        output.append(msg_product)
    return output
示例#26
0
def main():
    f1 = Factor(['Trav'], [['t', 'f']], [0.05, 0.95])
    f2 = Factor(['Fraud', 'Trav'],
                [['t', 't', 'f', 'f'], ['t', 'f', 't', 'f']],
                [0.01, 0.004, 0.99, 0.996])
    f3 = Factor(['FP', 'Fraud', 'Trav'],
                [['t', 't', 't', 't', 'f', 'f', 'f', 'f'],
                 ['t', 't', 'f', 'f', 't', 't', 'f', 'f'],
                 ['t', 'f', 't', 'f', 't', 'f', 't', 'f']],
                [0.9, 0.1, 0.9, 0.01, 0.1, 0.9, 0.1, 0.99])
    f4 = Factor(['IP', 'Fraud', 'OC'],
                [['t', 't', 't', 't', 'f', 'f', 'f', 'f'],
                 ['t', 't', 'f', 'f', 't', 't', 'f', 'f'],
                 ['t', 'f', 't', 'f', 't', 'f', 't', 'f']],
                [0.02, 0.011, 0.01, 0.001, 0.98, 0.989, 0.99, 0.999])
    f5 = Factor(['CRP', 'OC'], [['t', 't', 'f', 'f'], ['t', 'f', 't', 'f']],
                [0.1, 0.001, 0.9, 0.999])
    f6 = Factor(['OC'], [['t', 'f']], [0.6, 0.4])
    factorList = [f1, f2, f3, f4, f5, f6]
    quaryList = ['Fraud']
    hiddenVariables = ['Trav', 'FP', 'Fraud', 'IP', 'OC', 'CRP']
    evidenceList1 = dict(IP='t')
    evidenceList2 = dict(IP='t', CRP='t')
    Factor.inference(factorList, quaryList, hiddenVariables, evidenceList1)
    Factor.inference(factorList, quaryList, hiddenVariables, evidenceList2)
示例#27
0
def generate_uai(model_name):
    model = GraphicalModel()
    model.name=model_name

    with open(UAI_PATH+model_name+'.uai') as f:
        a = f.readlines()

    content = []
    for c in a:
        content.extend(c.split())

    cnt = 1
    nb_vars = int(content[cnt])
    cardinalities = dict()
    for t in range(nb_vars):
        cnt += 1
        newvar = 'V' + str(t)
        model.add_variable(newvar)
        cardinalities[newvar] = int(content[cnt])

    cnt += 1
    nfactors = int(content[cnt])

    factor_variables = dict()
    for t in range(nfactors):
        cnt += 1
        newfac_name = 'F' + str(t)
        factor_size = int(content[cnt])
        factor_variables[newfac_name] = []
        for t2 in range(factor_size):
            cnt += 1
            factor_variables[newfac_name].append('V' + str(content[cnt]))

    for t in range(nfactors):
        cnt += 1
        value_num = int(content[cnt])
        newfac_name = 'F' + str(t)
        values = []
        for vt2 in range(value_num):
            cnt += 1
            values.append(float(content[cnt]))

        values = np.reshape(
            values,
            [cardinalities[var] for var in factor_variables[newfac_name]])
        factor = Factor(
            name = newfac_name,
            variables = factor_variables[newfac_name],
            values = values)
        model.add_factor(factor)

    return model
示例#28
0
def _get_conditional_probability(nodes, edges, factors, evidence, initial_samples, num_iterations, num_burn_in):
    """
    Returns the conditional probability p(Xf | Xe) where Xe is the set of observed nodes and Xf are the query nodes
    i.e. the unobserved nodes. The conditional probability is approximated using Gibbs sampling.

    Args:
        nodes: numpy array of nodes e.g. [x1, x2, ...].
        edges: numpy array of edges e.g. [i, j] implies that nodes[i] is the parent of nodes[j].
        factors: dictionary of Factors e.g. factors[x1] returns the conditional probability of x1 given all other nodes.
        evidence: dictionary of evidence e.g. evidence[x4] returns the provided evidence for x4.
        initial_samples: dictionary of initial samples to initialize Gibbs sampling.
        num_iterations: number of sampling iterations
        num_burn_in: number of burn-in iterations

    Returns:
        returns Factor of conditional probability.
    """
    assert num_iterations > num_burn_in
    conditional_prob = Factor()

    """ YOUR CODE HERE """
    for factor_index in factors:
        factors[factor_index] = factor_evidence(factors[factor_index],evidence)
    remove_nodes = list(evidence.keys())
    for node in remove_nodes:
        initial_samples.pop(node)
        index = np.argwhere(nodes == node)
        nodes = np.delete(nodes,index)

    total_run = num_burn_in + num_iterations
    sample_result = np.zeros([total_run, len(nodes)])
    for i in range(total_run):
        initial_samples = _sample_step(nodes, factors, initial_samples)
        sample_result[i] = np.array(list(initial_samples.values()))

    # set freq dict
    freq = {}
    for i in range(len(factors[0].val)):
        freq[i] = 0
    card = factors[0].card
    for i in range(num_burn_in,num_iterations):
        index = assignment_to_index(sample_result[i],card)
        freq[index] += 1

    freq_arr = np.array(list(freq.values()))
    freq_arr = freq_arr/np.sum(freq_arr)
    conditional_prob.var = factors[0].var
    conditional_prob.card = card
    conditional_prob.val = freq_arr
    """ END YOUR CODE HERE """

    return conditional_prob
    def _update_mean_fields(self):
        variable_order = np.random.permutation(self.model.variables)
        for var in variable_order:
            next_mean_field = Factor.full_like_(self.mean_fields[var], 0.0)
            for fac in self.model.get_adj_factors(var):
                tmp = Factor(name = 'tmp', variables = [var], values = np.ones(self.model.get_cardinality_for_(var)))
                tmp = product_over_(tmp, *[self.mean_fields[var1] for var1 in fac.variables if var1 != var])
                tmp.transpose_by_(fac.variables)
                tmp.log_values = fac.log_values * tmp.values
                next_mean_field = next_mean_field + tmp.marginalize_except_([var], inplace = False)

            self.mean_fields[var] = next_mean_field.exp(inplace = False).normalize(inplace = False)
            self.mean_fields[var].log_values = np.nan_to_num(self.mean_fields[var].log_values)
示例#30
0
def factor_product(A, B):
    """
    Computes the factor product of A and B e.g. A = f(x1, x2); B = f(x1, x3); out=f(x1, x2, x3) = f(x1, x2)f(x1, x3)
    Args:
        A: first Factor
        B: second Factor
    Returns:
        Returns the factor product of A and B
    """
    out = Factor()
    """ YOUR CODE HERE,     HINT: copy from lab2 part 1! """
    if A.is_empty():
        return B
    if B.is_empty():
        return A

    out = Factor()

    # Set the variables of the output
    out.var = np.union1d(A.var, B.var)

    # Set the cardinality of the output
    out.card = np.zeros(len(out.var), np.int64)
    mapA = np.argmax(out.var[None, :] == A.var[:, None], axis=-1)
    mapB = np.argmax(out.var[None, :] == B.var[:, None], axis=-1)
    out.card[mapA] = A.card
    out.card[mapB] = B.card

    # Initialize the factor values to zero
    out.val = np.zeros(np.prod(out.card))
    assignments = out.get_all_assignments()
    idxA = assignment_to_index(assignments[:, mapA], A.card)
    idxB = assignment_to_index(assignments[:, mapB], B.card)

    # Populate the factor values
    out.val = A.val[idxA] * B.val[idxB]
    """ END YOUR CODE HERE """
    return out