def setup_titanic(): # Build a model of the titanic disaster global titanic_network, passenger, gender, tclass # Passengers on the Titanic either survive or perish passenger = DiscreteDistribution({'survive': 0.6, 'perish': 0.4}) # Gender, given survival data gender = ConditionalProbabilityTable( [['survive', 'male', 0.0], ['survive', 'female', 1.0], ['perish', 'male', 1.0], ['perish', 'female', 0.0]], [passenger]) # Class of travel, given survival data tclass = ConditionalProbabilityTable( [['survive', 'first', 0.0], ['survive', 'second', 1.0], ['survive', 'third', 0.0], ['perish', 'first', 1.0], ['perish', 'second', 0.0], ['perish', 'third', 0.0]], [passenger]) # State objects hold both the distribution, and a high level name. s1 = State(passenger, name="passenger") s2 = State(gender, name="gender") s3 = State(tclass, name="class") # Create the Bayesian network object with a useful name titanic_network = BayesianNetwork("Titanic Disaster") # Add the three nodes to the network titanic_network.add_nodes(s1, s2, s3) # Add transitions which represent conditional dependencies, where the # second node is conditionally dependent on the first node (Monty is # dependent on both guest and prize) titanic_network.add_edge(s1, s2) titanic_network.add_edge(s1, s3) titanic_network.bake()
def setup_monty(): # Build a model of the Monty Hall Problem global monty_network, monty_index, prize_index, guest_index random.seed(0) # Friends emissions are completely random guest = DiscreteDistribution({'A': 1. / 3, 'B': 1. / 3, 'C': 1. / 3}) # The actual prize is independent of the other distributions prize = DiscreteDistribution({'A': 1. / 3, 'B': 1. / 3, 'C': 1. / 3}) # Monty is dependent on both the guest and the prize. monty = ConditionalProbabilityTable( [['A', 'A', 'A', 0.0], ['A', 'A', 'B', 0.5], ['A', 'A', 'C', 0.5], ['A', 'B', 'A', 0.0], ['A', 'B', 'B', 0.0], ['A', 'B', 'C', 1.0], ['A', 'C', 'A', 0.0], ['A', 'C', 'B', 1.0], ['A', 'C', 'C', 0.0], ['B', 'A', 'A', 0.0], ['B', 'A', 'B', 0.0], ['B', 'A', 'C', 1.0], ['B', 'B', 'A', 0.5], ['B', 'B', 'B', 0.0], ['B', 'B', 'C', 0.5], ['B', 'C', 'A', 1.0], ['B', 'C', 'B', 0.0], ['B', 'C', 'C', 0.0], ['C', 'A', 'A', 0.0], ['C', 'A', 'B', 1.0], ['C', 'A', 'C', 0.0], ['C', 'B', 'A', 1.0], ['C', 'B', 'B', 0.0], ['C', 'B', 'C', 0.0], ['C', 'C', 'A', 0.5], ['C', 'C', 'B', 0.5], ['C', 'C', 'C', 0.0]], [guest, prize]) # Make the states s1 = State(guest, name="guest") s2 = State(prize, name="prize") s3 = State(monty, name="monty") # Make the bayes net, add the states, and the conditional dependencies. monty_network = BayesianNetwork("test") monty_network.add_nodes(s1, s2, s3) monty_network.add_edge(s1, s3) monty_network.add_edge(s2, s3) monty_network.bake() monty_index = monty_network.states.index(s3) prize_index = monty_network.states.index(s2) guest_index = monty_network.states.index(s1)
def __init__(self): Pollution = DiscreteDistribution({'F': 0.9, 'T': 0.1}) Smoker = DiscreteDistribution({'T': 0.3, 'F': 0.7}) print(Smoker) Cancer = ConditionalProbabilityTable([ ['T', 'T', 'T', 0.05], ['T', 'T', 'F', 0.95], ['T', 'F', 'T', 0.02], ['T', 'F', 'F', 0.98], ['F', 'T', 'T', 0.03], ['F', 'T', 'F', 0.97], ['F', 'F', 'T', 0.001], ['F', 'F', 'F', 0.999], ], [Pollution, Smoker]) print(Cancer) XRay = ConditionalProbabilityTable([ ['T', 'T', 0.9], ['T', 'F', 0.1], ['F', 'T', 0.2], ['F', 'F', 0.8], ], [Cancer]) Dyspnoea = ConditionalProbabilityTable([ ['T', 'T', 0.65], ['T', 'F', 0.35], ['F', 'T', 0.3], ['F', 'F', 0.7], ], [Cancer]) s1 = Node(Pollution, name="Pollution") s2 = Node(Smoker, name="Smoker") s3 = Node(Cancer, name="Cancer") s4 = Node(XRay, name="XRay") s5 = Node(Dyspnoea, name="Dyspnoea") model = BayesianNetwork("Lung Cancer") model.add_states(s1, s2, s3, s4, s5) model.add_edge(s1, s3) model.add_edge(s2, s3) model.add_edge(s3, s4) model.add_edge(s3, s5) model.bake() self.model = model meta = [] name_mapper = ["Pollution", "Smoker", "Cancer", "XRay", "Dyspnoea"] for i in range(self.model.node_count()): meta.append({ "name": name_mapper[i], "type": "categorical", "size": 2, "i2s": ['T', 'F'] }) self.meta = meta
def __init__(self): A = DiscreteDistribution({'1': 1. / 3, '2': 1. / 3, '3': 1. / 3}) B = ConditionalProbabilityTable([ ['1', '1', 0.5], ['1', '2', 0.5], ['1', '3', 0], ['2', '1', 0], ['2', '2', 0.5], ['2', '3', 0.5], ['3', '1', 0.5], ['3', '2', 0], ['3', '3', 0.5], ], [A]) C = ConditionalProbabilityTable([ ['1', '4', 0.5], ['1', '5', 0.5], ['1', '6', 0], ['2', '4', 0], ['2', '5', 0.5], ['2', '6', 0.5], ['3', '4', 0.5], ['3', '5', 0], ['3', '6', 0.5], ], [A]) s1 = Node(A, name="A") s2 = Node(B, name="B") s3 = Node(C, name="C") model = BayesianNetwork("tree") model.add_states(s1, s2, s3) model.add_edge(s1, s2) model.add_edge(s1, s3) model.bake() self.model = model meta = [] for i in range(self.model.node_count() - 1): meta.append({ "name": chr(ord('A') + i), "type": "categorical", "size": 3, "i2s": ['1', '2', '3'] }) meta.append({ "name": "C", "type": "categorical", "size": 3, "i2s": ['4', '5', '6'] }) self.meta = meta
def test_io_fit(): d1 = DiscreteDistribution({True: 0.6, False: 0.4}) d2 = ConditionalProbabilityTable([ [True, 'A', 0.2], [True, 'B', 0.8], [False, 'A', 0.3], [False, 'B', 0.7]], [d1]) d3 = ConditionalProbabilityTable([ ['A', 0, 0.3], ['A', 1, 0.7], ['B', 0, 0.8], ['B', 1, 0.2]], [d2]) n1 = Node(d1) n2 = Node(d2) n3 = Node(d3) model1 = BayesianNetwork() model1.add_nodes(n1, n2, n3) model1.add_edge(n1, n2) model1.add_edge(n2, n3) model1.bake() model1.fit(X, weights=weights) d1 = DiscreteDistribution({True: 0.2, False: 0.8}) d2 = ConditionalProbabilityTable([ [True, 'A', 0.7], [True, 'B', 0.2], [False, 'A', 0.4], [False, 'B', 0.6]], [d1]) d3 = ConditionalProbabilityTable([ ['A', 0, 0.9], ['A', 1, 0.1], ['B', 0, 0.0], ['B', 1, 1.0]], [d2]) n1 = Node(d1) n2 = Node(d2) n3 = Node(d3) model2 = BayesianNetwork() model2.add_nodes(n1, n2, n3) model2.add_edge(n1, n2) model2.add_edge(n2, n3) model2.bake() model2.fit(data_generator) logp1 = model1.log_probability(X) logp2 = model2.log_probability(X) assert_array_almost_equal(logp1, logp2)
def __init__(self): Rain = DiscreteDistribution({'T': 0.2, 'F': 0.8}) Sprinkler = ConditionalProbabilityTable([ ['F', 'T', 0.4], ['F', 'F', 0.6], ['T', 'T', 0.1], ['T', 'F', 0.9], ], [Rain]) Wet = ConditionalProbabilityTable([ ['F', 'F', 'T', 0.01], ['F', 'F', 'F', 0.99], ['F', 'T', 'T', 0.8], ['F', 'T', 'F', 0.2], ['T', 'F', 'T', 0.9], ['T', 'F', 'F', 0.1], ['T', 'T', 'T', 0.99], ['T', 'T', 'F', 0.01], ], [Sprinkler, Rain]) s1 = Node(Rain, name="Rain") s2 = Node(Sprinkler, name="Sprinkler") s3 = Node(Wet, name="Wet") model = BayesianNetwork("Simple fully connected") model.add_states(s1, s2, s3) model.add_edge(s1, s2) model.add_edge(s1, s3) model.add_edge(s2, s3) model.bake() self.model = model meta = [] for i in range(self.model.node_count()): meta.append({ "name": None, "type": "categorical", "size": 2, "i2s": ['T', 'F'] }) meta[0]['name'] = 'Rain' meta[1]['name'] = 'Sprinkler' meta[2]['name'] = 'Wet' self.meta = meta
def pomegranate_User_pref(): door_lock = DiscreteDistribution({'True': 0.7, 'False': 0.3}) thermostate = ConditionalProbabilityTable( [['True', 'True', 0.2], ['True', 'False', 0.8], ['False', 'True', 0.01], ['False', 'False', 0.99]], [door_lock]) clock_alarm = DiscreteDistribution({'True': 0.8, 'False': 0.2}) light = ConditionalProbabilityTable( [['True', 'True', 'True', 0.96], ['True', 'True', 'False', 0.04], ['True', 'False', 'True', 0.89], ['True', 'False', 'False', 0.11], ['False', 'True', 'True', 0.96], ['False', 'True', 'False', 0.04], ['False', 'False', 'True', 0.89], ['False', 'False', 'False', 0.11]], [door_lock, clock_alarm]) coffee_maker = ConditionalProbabilityTable( [['True', 'True', 0.92], ['True', 'False', 0.08], ['False', 'True', 0.03], ['False', 'False', 0.97]], [clock_alarm]) window = ConditionalProbabilityTable( [['True', 'True', 0.885], ['True', 'False', 0.115], ['False', 'True', 0.04], ['False', 'False', 0.96]], [thermostate]) s0_door_lock = State(door_lock, name="door_lock") s1_clock_alarm = State(clock_alarm, name="clock_alarm") s2_light = State(light, name="light") s3_coffee_maker = State(coffee_maker, name="coffee_maker") s4_thermostate = State(thermostate, name="thermostate") s5_window = State(window, name="Window") network = BayesianNetwork("User_pref") network.add_nodes(s0_door_lock, s1_clock_alarm, s2_light, s3_coffee_maker, s4_thermostate, s5_window) network.add_edge(s0_door_lock, s2_light) network.add_edge(s0_door_lock, s4_thermostate) network.add_edge(s1_clock_alarm, s3_coffee_maker) network.add_edge(s1_clock_alarm, s2_light) network.add_edge(s4_thermostate, s5_window) network.bake() return network
def get_bayesnet(self): door_lock = DiscreteDistribution({'d1': 0.7, 'd2': 0.3}) clock_alarm = DiscreteDistribution( { 'a1' : 0.8, 'a2' : 0.2} ) light = ConditionalProbabilityTable( [[ 'd1', 'a1', 'l1', 0.96 ], ['d1', 'a1', 'l2', 0.04 ], [ 'd1', 'a2', 'l1', 0.89 ], [ 'd1', 'a2', 'l2', 0.11 ], [ 'd2', 'a1', 'l1', 0.96 ], [ 'd2', 'a1', 'l2', 0.04 ], [ 'd2', 'a2', 'l1', 0.89 ], [ 'd2', 'a2', 'l2', 0.11 ]], [door_lock, clock_alarm]) coffee_maker = ConditionalProbabilityTable( [[ 'a1', 'c1', 0.92 ], [ 'a1', 'c2', 0.08 ], [ 'a2', 'c1', 0.03 ], [ 'a2', 'c2', 0.97 ]], [clock_alarm] ) s_door_lock = State(door_lock, name="door_lock") s_clock_alarm = State(clock_alarm, name="clock_alarm") s_light = State(light, name="light") s_coffee_maker = State(coffee_maker, name="coffee_maker") network = BayesianNetwork("User_pref") network.add_nodes(s_door_lock, s_clock_alarm, s_light, s_coffee_maker) network.add_edge(s_door_lock,s_light) network.add_edge(s_clock_alarm,s_coffee_maker) network.add_edge(s_clock_alarm,s_light) network.bake() return network
def __get_bayesian_network_model( self, symptom_distributions: List, symptom_states: List, file_name: str, disease_name: str, ): disease_conditional_distribution = list() for (s1, s2, s3, s4, s5, d, p) in get_from_csv(file_name): disease_conditional_distribution.append( [s1, s2, s3, s4, s5, d, float(p)]) disease_distribution = ConditionalProbabilityTable( disease_conditional_distribution, symptom_distributions, ) disease = Node(disease_distribution, name=disease_name) model = BayesianNetwork(disease_name) model.add_state(disease) for symptom_state in symptom_states: model.add_state(symptom_state) model.add_edge(symptom_state, disease) model.bake() return model
class User_model: def __init__(self, is_gen_task, n_alter_dev_per_func): self.is_gen_task = is_gen_task self.n_alter_dev_per_func = n_alter_dev_per_func self.task_dict = {} # BN self.BN_node_orders = [] self.devices = None self.nodes = None self.func_alter_devices = None def build_model(self, req_task_len): # 1,2 are based on montcarlo experimnet for tasklen(2 to 10) # which return a DAG with less than 100 triels. #1-req_task_len is 20% of total fucntions. n_nodes = 5 * req_task_len #2- edges three times the task len n_edges = req_task_len * 3 min_dev_caps = 2 # number of funcitons for each device self.devices, self.nodes, self.func_alter_devices = get_dev_funcs(n_nodes, \ min_dev_caps, self.n_alter_dev_per_func ) # pprint(self.func_alter_devices,width=1 ) rand_dag = RandomDAG(self.nodes, n_edges) DAG, child_parent = rand_dag.get_custom_DAG(req_task_len) # print("Child_parents returns by custom DAG: ") # pprint(child_parent, width=1) for f in rand_dag.dag_longest_path(DAG): self.task_dict[f] = '' # check if we get the task length the at we want for f in self.task_dict.keys(): func_devices = self.func_alter_devices[f] self.task_dict[f] = random.choice(func_devices) self.task_fucs = self.task_dict.keys() # print(self.task_dict) self.network = self.get_BN(DAG, child_parent) self.network.bake() def get_score(self, cand_list): can_dev = self.build_BN_query(cand_list) # try: return self.network.probability(can_dev), def build_BN_query(self, cand_list): # first cand_list for first func in task can_dev = [None for f in self.nodes] # the order of nodes and cand_list should be same for f, d in zip(self.task_fucs, cand_list): f_idx = self.BN_node_orders.index(f) can_dev[f_idx] = d return can_dev def get_nodes_prob_dist(self, node_without_parents, child_parent): node_prob_dict = {} for node in node_without_parents: n_alters = len(self.func_alter_devices[node]) dist = {} # node not in the user preference nodes # give random probability for all if node not in self.task_dict.keys(): p = np.random.random(n_alters) p /= p.sum() # now the sum of p is 1 # randomly map p to alter devices dist = dict(zip(self.func_alter_devices[node], p)) else: # set max prob to the perfered alter pref_alter = self.task_dict[node] x = 1.7 / n_alters y = 1.0 / len(self.task_dict) maxp_for_best_alter = pow(x, y) dist[pref_alter] = maxp_for_best_alter alt_list = list(self.func_alter_devices[node]) alt_list.remove(pref_alter) # generate random prob for the rest of alter if n_alters == 2: dist.update(dict(zip(alt_list, [1 - maxp_for_best_alter]))) # print([1.0-maxp_for_best_alter]) else: rand_rest = np.random.random(n_alters - 1) # to make the maxp+sum(rand_rest) = 1 rand_prob = [ e / sum(rand_rest) * maxp_for_best_alter for e in rand_rest ] #np.delete(p, np.amax(p)) dist.update(dict(zip(alt_list, rand_prob))) # save node with its prob node_prob_dict[node] = dist # these nodes have parents, generate CPT for them for node, parent_lst in child_parent.items(): # parents + this node condProbTable condProbTable = self.getCondProbTable(node, parent_lst) # save node with its prob node_prob_dict[node] = condProbTable # print("child node: ", node, " table:", condProbTable) return node_prob_dict def get_BN(self, DAG, child_parent): #1. get DAG structure as an arguments ################################################ node_without_parents = [ e for e in self.nodes if e not in child_parent.keys() ] # 2 Build BN probability model # 2.1 get probabilityDist or conditional prob table # bais the prob to task_dict choices node_prob_dict = self.get_nodes_prob_dist(node_without_parents, child_parent) self.npd = node_prob_dict # 2.2 Create nodes linked to its parent, parent should be processed first. # all node state saved to be added to the BN later nodes_state = {} # all node dist or CPT saved to link child to parents when building child CPT nodes_dist = {} # start with root nodes (don't have parents then link child to them) # list the list to copy it, otherwise it will point to the self.nodes remaining_nodes_list = list(self.nodes) for node in node_without_parents: prob_dist = node_prob_dict[node] # print("Parent", node, prob_dist) node_dist = DiscreteDistribution(prob_dist) nodes_dist[node] = node_dist nodes_state[node] = State(node_dist, name=node) # remove from nodes_list remaining_nodes_list.remove(node) # rest of the node should have parents while len(remaining_nodes_list) > 0: for node, parent_lst in child_parent.items(): # if node's parents already created then it can be created now if set(parent_lst).issubset(nodes_state.keys()) and \ node in remaining_nodes_list: # print("parent child", parent_lst, node, node_prob_dict[node]) node_dist = ConditionalProbabilityTable(node_prob_dict[node], \ [nodes_dist[i] for i in parent_lst]) nodes_dist[node] = node_dist nodes_state[node] = State(node_dist, name=node) # remove from the node_list remaining_nodes_list.remove(node) # 3 Create BN and add the nodes_state self.network = BayesianNetwork("User_pref") for node, state in nodes_state.items(): self.network.add_node(state) #print("node ", node, " is added!") self.BN_node_orders.append(node) # 4 Link nodes with edges using nodes_state and DAG.edge for a, bs in DAG.edge.items(): for b in bs.keys(): self.network.add_edge(nodes_state[a], nodes_state[b]) # print("Netwoerk:", a, b) # print("Network has ", self.network.node_count() , " nodes and ", self.network.edge_count(), " edges") return self.network def get_permutation_groups(self, parent_node_lst): # print("Parents,node", parent_node_lst) alter_dev = [] for n in parent_node_lst: alter_dev.append(self.func_alter_devices[n]) # list(range(n_att)) # print("dev for all ", alter_dev) alter_perm = itertools.product(*alter_dev) # print("alter_perm:", alter_perm) permutation = list(dict(zip(parent_node_lst, x)) for x in alter_perm) # print("permutation") # print(permutation) # Gruop the permutation of node alter node n_func_dev = len(self.func_alter_devices[parent_node_lst[-1]]) n_prob_groups = int(len(permutation) / n_func_dev) perm_groups = [[] for i in range(n_prob_groups)] c = 0 for perm in permutation: # add to the begining perm_groups[c // n_func_dev].append(perm) c += 1 return perm_groups def getCondProbTable(self, node, parent_lst): parent_node_lst = [] parent_node_lst.extend(parent_lst) parent_node_lst.append(node) perm_groups_prob = self.get_permutation_groups(parent_node_lst) condProbTable = [] n_func_dev = len(self.func_alter_devices[node]) #p^(1/N) maxp_for_best_alter = pow(1.7 / n_func_dev, 1 / len(self.task_dict)) if maxp_for_best_alter < 0.2: maxp_for_best_alter = 0.2 if self.is_gen_task: # check if this child_parent or indp node are in the user prefered devices intersect_dict = {k: v for k, v in self.task_dict.items() \ if k in parent_node_lst} #print("intersect_dict:", intersect_dict) # for each permutation generate prob such that the sum of each node CDP is = 1 for perm_group_prob in perm_groups_prob: if self.is_gen_task and len(intersect_dict) > 1 and \ [True for j in range(n_func_dev) \ if intersect_dict.items() <= perm_group_prob[j].items()]: # print(intersect_dict) # generate p such that one value is rem_alt = n_func_dev - 1 rest_prob = np.random.random(rem_alt) rest_prob /= sum(rest_prob) rest_prob *= (1 - maxp_for_best_alter) # the sum of maxp_for_best_alter and rest_prob = 1 for j in range(n_func_dev): # alter_idx = i * n_att + j condProbRow = list(perm_group_prob[j].values()) if intersect_dict.items() <= perm_group_prob[j].items(): # print("Best candidate ", perm_group_prob[j], " prob:", maxp_for_best_alter) condProbRow.append(maxp_for_best_alter) else: rem_alt -= 1 #print("NOT candidate ", perm_group_prob[j], " prob:", rest_prob[rem_alt]) condProbRow.append(rest_prob[rem_alt]) condProbTable.append(condProbRow) else: # to gurantee best alter, no others should have prob> maxp a = np.random.random(n_func_dev) a /= a.sum() while self.is_gen_task and np.amax(a) >= maxp_for_best_alter: a = np.random.random(n_func_dev) a /= a.sum() # to make sum of alter prob = 1 for j in range(n_func_dev): condProbRow = list(perm_group_prob[j].values()) condProbRow.append(a[j]) #print(condProbRow) condProbTable.append(condProbRow) return condProbTable
states['Peer_Pressure'] = State(Peer_Pressure, name="Peer_Pressure") states['Smoking'] = State(Smoking, name="Smoking") states['Yellow_Fingers'] = State(Yellow_Fingers, name="Yellow_Fingers") states['Genetics'] = State(Genetics, name="Genetics") states['Lung_cancer'] = State(Lung_cancer, name="Lung_cancer") states['Attention_Disorder'] = State(Attention_Disorder, name="Attention_Disorder") states['Allergy'] = State(Allergy, name="Allergy") states['Coughing'] = State(Coughing, name="Coughing") states['Born_an_Even_Day'] = State(Born_an_Even_Day, name="Born_an_Even_Day") states['Fatigue'] = State(Fatigue, name="Fatigue") states['Car_Accident' ] = State(Car_Accident, name="Car_Accident") network = BayesianNetwork("Monty hall problem") network.add_states(*states.values()) network.add_edge(states["Peer_Pressure"],states["Smoking"]) network.add_edge(states["Anxiety"],states["Smoking"]) network.add_edge(states["Smoking"],states["Yellow_Fingers"]) network.add_edge(states["Genetics"],states["Lung_cancer"]) network.add_edge(states["Smoking"],states["Lung_cancer"]) network.add_edge(states["Genetics"],states["Attention_Disorder"]) network.add_edge(states['Lung_cancer'], states["Coughing"]) network.add_edge(states['Allergy'], states["Coughing"]) network.add_edge(states['Coughing'], states["Fatigue"]) network.add_edge(states['Lung_cancer'], states["Fatigue"]) network.add_edge(states["Fatigue"], states["Car_Accident"]) network.add_edge(states["Attention_Disorder"], states["Car_Accident"]) import ast network.bake() beliefs = network.predict_proba({"Genetics":"T"},max_iterations=100000) # print(beliefs)
["none", "no", "delayed", 0.1], ["light", "yes", "on time", 0.6], ["light", "yes", "delayed", 0.4], ["light", "no", "on time", 0.7], ["light", "no", "delayed", 0.3], ["heavy", "yes", "on time", 0.4], ["heavy", "yes", "delayed", 0.6], ["heavy", "no", "on time", 0.5], ["heavy", "no", "delayed", 0.5], ], [rain.distribution, maintenance.distribution]), name="train") # Appointment node is conditional on train appointment = Node(ConditionalProbabilityTable( [["on time", "attend", 0.9], ["on time", "miss", 0.1], ["delayed", "attend", 0.6], ["delayed", "miss", 0.4]], [train.distribution]), name="appointment") # Create a bayesian network and add the states model = BayesianNetwork() model.add_states(rain, maintenance, train, appointment) # Add edges connecting nodes model.add_edge(rain, maintenance) model.add_edge(rain, train) model.add_edge(maintenance, train) model.add_edge(train, appointment) # Finalize model model.bake()
def __init__(self, filename): with open(filename) as f: bif = f.read() vars = re.findall(r"variable[^\{]+{[^\}]+}", bif) probs = re.findall(r"probability[^\{]+{[^\}]+}", bif) var_nodes = {} var_index_to_name = [] edges = [] self.meta = [] todo = set() for v, p in zip(vars, probs): m = re.search(r"variable\s+([^\{\s]+)\s+", v) v_name = m.group(1) m = re.search(r"type\s+discrete\s+\[\s*(\d+)\s*\]\s*\{([^\}]+)\}", v) v_opts_n = int(m.group(1)) v_opts = m.group(2).replace(',', ' ').split() assert v_opts_n == len(v_opts) # print(v_name, v_opts_n, v_opts) m = re.search(r"probability\s*\(([^)]+)\)", p) cond = m.group(1).replace('|', ' ').replace(',', ' ').split() assert cond[0] == v_name # print(cond) self.meta.append({ "name": v_name, "type": "categorical", "size": v_opts_n, "i2s": v_opts }) if len(cond) == 1: m = re.search(r"table([e\-\d\.\s,]*);", p) margin_p = m.group(1).replace(',', ' ').split() margin_p = [float(x) for x in margin_p] assert abs(sum(margin_p) - 1) < 1e-6 assert len(margin_p) == v_opts_n margin_p = dict(zip(v_opts, margin_p)) var_index_to_name.append(v_name) tmp = DiscreteDistribution(margin_p) # print(tmp) var_nodes[v_name] = tmp else: m_iter = re.finditer(r"\(([^)]*)\)([\s\d\.,\-e]+);", p) cond_p_table = [] for m in m_iter: cond_values = m.group(1).replace(',', ' ').split() cond_p = m.group(2).replace(',', ' ').split() cond_p = [float(x) for x in cond_p] assert len(cond_values) == len(cond) - 1 assert len(cond_p) == v_opts_n assert abs(sum(cond_p) - 1) < 1e-6 for opt, opt_p in zip(v_opts, cond_p): cond_p_table.append(cond_values + [opt, opt_p]) var_index_to_name.append(v_name) tmp = (cond_p_table, cond) # print(tmp) var_nodes[v_name] = tmp for x in cond[1:]: edges.append((x, v_name)) todo.add(v_name) while len(todo) > 0: # print(todo) for v_name in todo: # print(v_name, type(var_nodes[v_name])) cond_p_table, cond = var_nodes[v_name] flag = True for y in cond[1:]: if y in todo: flag = False break if flag: cond_t = [var_nodes[x] for x in cond[1:]] var_nodes[v_name] = ConditionalProbabilityTable( cond_p_table, cond_t) todo.remove(v_name) break for x in var_index_to_name: var_nodes[x] = Node(var_nodes[x], name=x) var_nodes_list = [var_nodes[x] for x in var_index_to_name] # print(var_nodes_list) model = BayesianNetwork("tmp") model.add_states(*var_nodes_list) for edge in edges: model.add_edge(var_nodes[edge[0]], var_nodes[edge[1]]) model.bake() # print(model.to_json()) self.model = model
def get_BN(self, n_nodes, n_alters, n_edges): # 1 Build BN DAG structure DAG, child_parent = RandomDAG().random_dag(n_nodes, n_edges) for a, bs in DAG.edge.items(): for b in bs.keys(): print(a, "->", b) print("Key node, value: parents",child_parent) # 2 Build BN probability model # 2.1 get probabilityDist or conditional prob table node_prob_dict = {} # these nodes have parents, generate CPT for them for node, parent_lst in child_parent.items(): # parents + this node condProbTable condProbTable = self.getCondProbTable(len(parent_lst)+1, n_alters) # save node with its prob node_prob_dict[str(node)] = condProbTable #print("Conditional Probability Table: \n", condProbTable) nodes_list = list(range(n_nodes)) node_with_parent_lst = child_parent.keys() node_without_parents = [e for e in nodes_list if e not in node_with_parent_lst] # these nodes have no parents so create random prob for them only no conditional here for node in node_without_parents: p = np.random.random(n_alters) p /= p.sum() dist = {} for j in range(n_alters): dist[j] = p[j] # save node with its prob node_prob_dict[str(node)] = dist #print("Root node: ", node, " dist: ", dist) # 2.2 Create nodes linked to its parent, parent should be processed first. # all node state saved to be added to the BN later nodes_state = {} # all node dist or CPT saved to link child to parents when building child CPT nodes_dist = {} # start with root nodes (don't have parents then link child to them) for node in node_without_parents: prob_dist = node_prob_dict[str(node)] node_dist = DiscreteDistribution(prob_dist) nodes_dist[node] = node_dist nodes_state[node] = State(node_dist, name = str(node)) # remove from nodes_list nodes_list.remove(node) # rest of the node should have parents count = 100 while len(nodes_list) > 0 and count > 0: count -= 1 for node, parent_lst in child_parent.items(): # if node's parents already created then it can be created now if set(parent_lst).issubset(nodes_state.keys()) and node in nodes_list: node_dist = ConditionalProbabilityTable(node_prob_dict[str(node)] \ , [nodes_dist[i] for i in parent_lst ]) nodes_dist[node] = node_dist nodes_state[node] = State(node_dist, name = str(node)) # remove from the node_list nodes_list.remove(node) if not nodes_list: print("States created for all nodes!") # 3 Create BN and add the nodes_state network = BayesianNetwork("User_pref") for node, state in nodes_state.items(): network.add_node(state) print("Network has ", network.node_count() , " nodes") # 4 Link nodes with edges using nodes_state and DAG.edge for a, bs in DAG.edge.items(): for b in bs.keys(): network.add_edge(nodes_state[a], nodes_state[b]) print("Network has ", network.edge_count(), " edges") return network
sAllergy = Node(allergy, name="Allergy") model = BayesianNetwork("Smoking Risk") model.add_nodes( sAnxiety, sPeerPressure, sSmoking, sGenetics, sLungCancer, sAllergy, sCoughing, sFatigue, sAttentionDisorder, sCarAccident, ) model.add_edge(sAnxiety, sSmoking) model.add_edge(sPeerPressure, sSmoking) model.add_edge(sSmoking, sLungCancer) model.add_edge(sGenetics, sLungCancer) model.add_edge(sGenetics, sAttentionDisorder) model.add_edge(sAllergy, sCoughing) model.add_edge(sLungCancer, sCoughing) model.add_edge(sCoughing, sFatigue) model.add_edge(sLungCancer, sFatigue) model.add_edge(sFatigue, sCarAccident) model.add_edge(sAttentionDisorder, sCarAccident) model.bake() prediction = model.predict_proba({}) states = [ "Anxiety",
from pomegranate import DiscreteDistribution from pomegranate import ConditionalProbabilityTable from pomegranate import BayesianNetwork from pomegranate import Node guest = DiscreteDistribution({'A': 1. / 3, 'B': 1. / 3, 'C': 1. / 3}) prize = DiscreteDistribution({'A': 1. / 3, 'B': 1. / 3, 'C': 1. / 3}) monty = ConditionalProbabilityTable( [['A', 'A', 'A', 0.0], ['A', 'A', 'B', 0.5], ['A', 'A', 'C', 0.5], ['A', 'B', 'A', 0.0], ['A', 'B', 'B', 0.0], ['A', 'B', 'C', 1.0], ['A', 'C', 'A', 0.0], ['A', 'C', 'B', 1.0], ['A', 'C', 'C', 0.0], ['B', 'A', 'A', 0.0], ['B', 'A', 'B', 0.0], ['B', 'A', 'C', 1.0], ['B', 'B', 'A', 0.5], ['B', 'B', 'B', 0.0], ['B', 'B', 'C', 0.5], ['B', 'C', 'A', 1.0], ['B', 'C', 'B', 0.0], ['B', 'C', 'C', 0.0], ['C', 'A', 'A', 0.0], ['C', 'A', 'B', 1.0], ['C', 'A', 'C', 0.0], ['C', 'B', 'A', 1.0], ['C', 'B', 'B', 0.0], ['C', 'B', 'C', 0.0], ['C', 'C', 'A', 0.5], ['C', 'C', 'B', 0.5], ['C', 'C', 'C', 0.0]], [guest, prize]) s1 = Node(guest, name="guest") s2 = Node(prize, name="prize") s3 = Node(monty, name="monty") model = BayesianNetwork("Monty Hall Problem") model.add_states(s1, s2, s3) model.add_edge(s1, s3) model.add_edge(s2, s3) model.bake()
ashwin = ConditionalProbabilityTable( returnConditionalProbability(df, 'Location', 'Ashwin'), [location]) batting = ConditionalProbabilityTable( returnConditionalProbability(df, 'Toss', 'Bat'), [toss]) result = ConditionalProbabilityTable( returnConditionalProbability(df, 'Bat', 'Result'), [batting]) sLocation = State(location, name="Location") sToss = State(toss, name="Toss") sBatting = State(batting, name="Batting") sAshwin = State(ashwin, name="Ashwin") sResult = State(result, name="Result") # Create the Bayesian network object with a useful name model = BayesianNetwork("Ashwin Playing Problem") # Add the three states to the network model.add_states(sLocation, sToss, sBatting, sAshwin, sResult) model.add_edge(sLocation, sAshwin) model.add_edge(sToss, sBatting) model.add_edge(sBatting, sResult) model.bake() model.predict_proba([None, None, '2nd', 'Y', 'won'])[1] model.predict_proba([None, None, '2nd', 'N', 'won'])[0] model.predict_proba([None, None, '2nd', 'Y', 'lost'])[1] model.predict_proba([None, None, '2nd', 'N', 'lost'])[0]