def baby_model(): d1 = DiscreteDistribution({'0': 0.6, '1': 0.4}) d2 = DiscreteDistribution({'0': 0.6, '1': 0.4}) d3 = ConditionalProbabilityTable( [['1', '1', 0.1], ['1', '0', 0.9], ['0', '1', 0.9], ['0', '0', 0.1]], [d1]) d4 = ConditionalProbabilityTable( [['1', '1', '1', 0.1], ['1', '1', '0', 0.9], ['1', '0', '1', 0.1], ['1', '0', '0', 0.9], ['0', '1', '1', 0.9], ['0', '1', '0', 0.1], ['0', '0', '1', 0.9], ['0', '0', '0', 0.1]], [d1, d2]) d5 = ConditionalProbabilityTable( [['1', '1', 0.1], ['1', '0', 0.9], ['0', '1', 0.9], ['0', '0', 0.1]], [d2]) s1 = State(d1, name=BOREDOM) s2 = State(d2, name=MOTOR_HYPO) s3 = State(d3, name=DESIRE) s4 = State(d4, name=MOBILE) s5 = State(d5, name=LEFT_ARM) model = BayesianNetwork() model.add_states(s1, s2, s3, s4, s5) model.add_edge(s1, s3) model.add_edge(s1, s4) model.add_edge(s2, s4) model.add_edge(s2, s5) model.bake() return model
def generate_bayesian(self): """ Generates the bayesian network with pomegranate """ conditional_dict = {} state_dict = {} self.bayes_net(conditional_dict, self.harm.top_layer.target) model = BayesianNetwork('B-Harm') host_list = [] for index, node in enumerate(conditional_dict.keys()): state_dict[node] = State(conditional_dict[node], name=str(node)) if node == self.harm.top_layer.target: target_index = index model.add_state(state_dict[node]) host_list.append(node) for edge in self.harm.top_layer.edges(): s, t = edge source = state_dict.get(s, None) target = state_dict.get(t, None) model.add_transition(source, target) model.bake() total = 0 risk = 0 roa = 0 total_ac = 0 for i in itertools.product([True, False], repeat=len(state_dict) - 1): scenario = list(i) scenario.insert(target_index, True) probability = model.probability(scenario) if probability <= 1e-4: continue total_impact = 0 attack_cost = 0 total_roa = 0 for i, val in enumerate(scenario): if val is True: total_impact += host_list[i].impact attack_cost += host_list[i].cost total_roa += host_list[i].impact / host_list[i].cost total_ac += probability * attack_cost total += probability risk += probability * total_impact roa += probability * total_roa return { 'total': total, 'ag_risk': risk, 'roa': roa, 'total_ac': total_ac }
def main(): train_path = Path('./data/train.csv') train_data, val_data = read_data(train_path) bayesian_network = BayesianNetwork.from_samples(train_data.values, state_names=train_data.columns) classification_report_train = error(train_data, bayesian_network) classification_report_val = error(val_data, bayesian_network) print("train\n{}".format(classification_report_train)) print("validation\n{}".format(classification_report_val))
def error(input_data_frame: pd.DataFrame, network: BayesianNetwork) -> str: input_data_frame_copy = input_data_frame.copy() input_data_frame_copy['Survived'] = [None] * input_data_frame_copy.shape[0] pred = network.predict(input_data_frame_copy.values, check_input=False) pred = np.array(pred) y_pred = pred[:, 0] y_real = input_data_frame['Survived'].values return classification_report(y_true=y_real.astype(int), y_pred=y_pred.astype(int))
['T', 'F', 'F', 0.3], ['F', 'T', 'T', 0.9], ['F', 'T', 'F', 0.1], ['F', 'F', 'T', 0.0], ['F', 'F', 'F', 1.0]], [arid_rain, arid_sprinkler]) # Next we need to create the states for our "arid" bayesian network. # In[5]: s1 = State(arid_rain, name="rain") s2 = State(arid_sprinkler, name="sprinkler") s3 = State(arid_grass, name="grass") # Then the bayesian network itself, along with its states and transitions between them. # In[6]: arid = BayesianNetwork("arid") arid.add_states(s1, s2, s3) arid.add_transition(s1, s2) arid.add_transition(s1, s3) arid.add_transition(s2, s3) # Finally we need to "bake" our bayesian network to finalize its structure. # In[7]: arid.bake() # Now that we've created a bayesian network for an arid city, we can create our bayesian network for our wet city. We can think of a wet city as a place like Seattle, Washington, which has a high probability of rainfall. # # The bayesian network is the same as before, just with different probabilities. So we will start with similar probability distributions.
['C', 'C', 'A', 0.5], ['C', 'C', 'B', 0.5], ['C', 'C', 'C', 0.0]], [guest, prize]) # Now lets create the states for the bayesian network. # In[4]: s1 = State(guest, name="guest") s2 = State(prize, name="prize") s3 = State(monty, name="monty") # Then the bayesian network itself, adding the states in after. # In[5]: network = BayesianNetwork("test") network.add_states(s1, s2, s3) # Then the transitions. # In[6]: network.add_transition(s1, s3) network.add_transition(s2, s3) # With a "bake" to finalize the structure of our network. # In[7]: network.bake()
def to_pomegranate(self): if self.cpds: distributions = OrderedDict() for node in self.get_nodes(): if len(self.get_incoming_edges(node)) == 0: cpd = DiscreteDistribution(dict(enumerate(self.cpds[node]))) distributions.update({node: cpd}) else: parents = [parent for parent, child in self.edges if child == node] parent_cpds = [distributions[key] for key in parents] cardinalities = [self.cardinality_map[key] for key in parents] cardinalities.append(self.cardinality_map[node]) states = get_index_matrix(cardinalities) original_cpd = np.array(self.cpds[node]) probabilities = [] for col in range(0, original_cpd.shape[1]): for row in range(0, original_cpd.shape[0]): probabilities.append(original_cpd[row, col]) stacked = np.vstack([states, probabilities]) cpd = ConditionalProbabilityTable(stacked.T.tolist(), parent_cpds) distributions.update({node: cpd}) states = OrderedDict() for key, value in distributions.items(): states.update({key: State(value, name=key)}) pm_net = BayesianNetwork() for state in states.values(): pm_net.add_state(state) for edge in self.edges: pm_net.add_edge(states[edge[0]], states[edge[1]]) pm_net.bake() return pm_net elif self.train_data: structure = [] nodes = self.get_nodes() for node in nodes: parents = [] for edge in self.edges: if node == edge[1]: parents.append(nodes.index(edge[0])) structure.append(tuple(parents)) pm_net = BayesianNetwork.from_structure(X=self.train_data, structure=tuple(structure), state_names=nodes) for i, state in enumerate(pm_net.states): state.name = nodes[i] if isinstance(state.distribution, DiscreteDistribution): cpd = [] parameter = state.distribution.parameters[0] for x in range(0, self.cardinality_map[state.name]): if x in parameter: cpd.append(parameter[x]) else: raise ValueError('Pomegranate dropped some values during fitting. Most likely because ' 'it contains a zero probability. Check your training data.') else: cardinality_values = [] for key, _ in state.distribution.keymap.items(): c = key[state.distribution.m] if c in cardinality_values: break cardinality_values.append(c) cardinality = len(cardinality_values) if cardinality != self.cardinality_map[state.name]: raise ValueError('Pomegranate cardinality does not match expected cardinality of node %s', state.name) parameters = state.distribution.parameters[0] param_len = len(parameters) matrix = np.empty(shape=(cardinality, int(param_len / cardinality))) for x in range(0, param_len, cardinality): for y in range(0, cardinality): row = parameters[x + y] matrix[y, int(x / cardinality)] = row[len(row) - 1] cpd = matrix.tolist() self.add_cpd(state.name, cpd) return pm_net
# Now we can create the states for our bayesian network. # In[19]: s0 = State(friend, name="friend") s1 = State(guest, name="guest") s2 = State(prize, name="prize") s3 = State(monty, name="monty") s4 = State(remaining, name="remaining") s5 = State(randomize, name="randomize") # Now we'll create our bayesian network with an instance of BayesianNetwork, then add the possible states. # In[20]: network = BayesianNetwork("test") network.add_states(s0, s1, s2, s3, s4, s5) # Then the possible transitions. # In[21]: network.add_transition(s0, s1) network.add_transition(s1, s3) network.add_transition(s2, s3) network.add_transition(s4, s5) network.add_transition(s5, s2) network.add_transition(s0, s2) # With a "bake" to finalize the structure of our network.
['T', 'F', 'F', 0.1], ['F', 'T', 'T', 0.7], ['F', 'T', 'F', 0.3], ['F', 'F', 'T', 0.1], ['F', 'F', 'F', 0.9]], [dist_rain, dist_fog]) # Now that we have our distributions, we can create states for our bayesian network out of them. # In[43]: rain = State(dist_rain, 'rain') fog = State(dist_fog, 'fog') grass = State(dist_grass, 'grass') # And finally we can create our bayesian network in which fog is dependent upon rain. We add the states in and the possible transitions as well. # In[44]: rain2fog = BayesianNetwork('rain2fog') rain2fog.add_states(rain, fog, grass) rain2fog.add_transition(rain, fog) rain2fog.add_transition(rain, grass) rain2fog.add_transition(fog, grass) # Finally we bake it in order to finalize it's structure. # In[45]: rain2fog.bake() # Now let's create our bayesian network in which fog influencesthe occurrence of rain. This process is similar to the creation of our last bayesian network. However instead this time we start by creating a discrete distribution for the occurrence of fog. # In[46]:
# In[11]: a_s = State(a, "a") b_s = State(b, "b") c_s = State(c, "c") d_s = State(d, "d") e_s = State(e, "e") f_s = State(f, "f") g_s = State(g, "g") # Now that we have our states created, we can finally start making our bayesian network. # In[12]: model = BayesianNetwork("derp") model.add_nodes(a_s, b_s, c_s, d_s, e_s, f_s, g_s) # Then we define the edges. # In[13]: model.add_edge(a_s, c_s) model.add_edge(b_s, c_s) model.add_edge(c_s, d_s) model.add_edge(c_s, f_s) model.add_edge(b_s, e_s) model.add_edge(e_s, f_s) model.add_edge(c_s, g_s) model.add_edge(e_s, g_s)