def __init__(self, fh): "Loads problem from opened file object fh and creates a Bayesian Network" self.R = [] # Rooms self.C = {} # Connections self.S = {} # Sensors self.P = float() # Propagation Probability self.M = {} # Measurements self.RoomProbs = {} # Probability of fire in each room self.NB = probability.BayesNet() # Bayesian Network self.load(fh) # load data from input file self.createBayes() # create Bayesian Network
def gen_net(self): nodes = [] for i, r in enumerate(self.room_names): X = r + "1" parents = "" p = 0.5 # The problem says "no prior information" nodes.append((X, parents, p)) for t in range(1, self.T): for r in range(self.N): X = self.room_names[r] + str(t + 1) parents = " ".join([ self.room_names[r] + str(t) for r in self.rooms[r].conns_idx ]) combs = combinations_with_replacement( [True, False], len(self.rooms[r].conns_idx)) perms = [item for comb in combs for item in permutations(comb)] p = {i: 0 for i in perms} for i in perms: if any(i): p[i] = self.P if i[-1]: p[i] = 1 nodes.append((X, parents, p)) for t in range(1, self.T + 1): for measurement in self.measurements[t]: sens_name = measurement[0] sens = self.sensors[sens_name] parents = sens.room + str(t) node_name = sens_name + "t" + str(t) cpt = {True: sens.tpr, False: sens.fpr} nodes.append((node_name, parents, cpt)) # for j in range(self.M): # Does not work with varying amount of measurements # sens_name = self.measurements[t][j][0] # sens = self.sensors[sens_name] # parents = sens.room + str(t) # # node_name = sens_name + "t" + str(t) # # cpt = {True : sens.tpr, False: sens.fpr} # nodes.append((node_name, parents, cpt)) self.net = probability.BayesNet(nodes)
def __init__(self, fh): # Place here your code to load problem from opened file object fh # and use probability.BayesNet() to create the Bayesian network T, F = True, False self.rooms = {} self.connections = {} self.sensors = {} self.propagation_probability=0.0 self.time = {} self.T = 0 self.evidence={} self.load(fh) net = self.create_network() self.network = pb.BayesNet(net) room, likelihood = self.solve()
def create_bayes_net(self, R, S, M, parents, cond_prob, sensor_prob, P_F): """Creates the Bayesian network for the museum fire problem, as implemented in the AIMA repository. Each node has a unique name, where the time instant is explicited by the ending '@<time instant>'. For example, the room 'history' at time instant 0 will have a node named 'history@0'. Each 'level' of the Bayes net corresponds to a time instant. Suppose two connected rooms 'artificial' and 'intelligence'. The room intelligence has a sensor 's1'. There are measurements for two time instants The Bayesian network would be: ______________ ________________ | artificial@0 | | intelligence@0 | ______ |______________| |________________|----->| s1@0 | | \_______ / | |______| | ______\_______/ | | / \_______ | | / \ | _______v_v____ ______v_v_______ | artificial@1 | | intelligence@1 | ______ |______________| |________________|----->| s1@1 | |______| Parameters ---------- R : list List containing the room names. S : dictionary of dictionaries Dictionary where the keys are the sensors name. The values are dictionaries containing the keys 'room', 'TPR', and 'FPR'. M : list of lists of dictionaries Each dictionary is a measurement at a given time instant where the key is the sensor name and the value the measurement. All the measurements of that time (dictionaries) are stored in a list. The lists of measurements at given time instants are stored in a list. parents : dictionary of lists A dictionary containing the parents of each room node. The key is the room name and the value is a lists of its connections plus itself. cond_prob : dictionary of dictinaries A dictionary containing the the conditional probabilities of the room nodes. The keys are the room names and the values are another dictionary containing the conditional probabilities. The keys of this other dictionary are the entries of the truth table as boolean lists and the values are the (conditional) probabilities of that truth table. sensor_prob : dictionary of dictinaries A dictionary containing the the conditional probabilities of the sensor nodes. The keys are the sensors' names and the values are another dictionary containing the FPR for False and TPR for True. P_F : float Fire propagation probability Returns ------- bayes_net : probability.BayesNet A Bayesian network as implemented in the AIMA repository. This network will represent the museum fire problem (as illustrated above). """ # Initialize Bayes net bayes_net = probability.BayesNet() # Add nodes of rooms at time instant 0 (and probability of fire of 50%) for room in R: bayes_net.add((room + '@0', '', P_F)) # Add nodes of rooms at the following time steps (the amount of time steps correspond to the number of instants of the measurements) for i in range(1, len(M)): for room in R: # Getting parents name at step i-1 parents_i = [parent + f'@{i-1}' for parent in parents[room]] # Adding node to the net. Name is the name of the room plus @<time instant>, parents is a string of all # the parents_i separated by spaces, and the conditional probability depends on the fire propagation law bayes_net.add( (room + f'@{i}', ' '.join(parents_i), cond_prob[room])) # Add measurements nodes at all time steps for i, measurements in enumerate(M): for m in measurements: # Sensor name sensor = m['sensor'] # Adding node to the net. Name is the sensor name plus @<time instant>, parent is the room where # it is installed plus @<time instant> and conditional probability corresponds to the FPR and TPR. bayes_net.add((sensor + f'@{i}', S[sensor]['room'] + f'@{i}', sensor_prob[sensor])) return bayes_net
def __init__(self, fh): # Place here your code to load problem from opened file object fh # and use probability.BayesNet() to create the Bayesian network # split the file into lines lines = fh.read().splitlines() # removes blank lines file = list(filter(None, lines)) rooms, connections = (() for i in range(2)) sensors, measurements = ([] for i in range(2)) self.nb_measurements = 0 # Separates the file information according to the first letter in each line for string in file: if string[0] == "R": # Set of Rooms R rooms = tuple(string[2:].split()) elif string[0] == "C": # The set of connection if not string[2:]: connections = [] else: connections = tuple(string[2:].split(" ")) elif string[0] == "S": # The set of sensors sensors = string[2:].split() elif string[0] == "P": # The propagation probability prob = string[2:] elif string[0] == "M": # A measurement self.nb_measurements += 1 measurements.append(string[2:]) self.connections = [] self.sensors = {} self.measurements = [[] for i in range(self.nb_measurements)] # split connection by , for i in connections: aux1 = i.split(",") self.connections.append(tuple(aux1)) # split sensor info by : for j in sensors: aux2 = j.split(":") self.sensors.update({aux2[0]: tuple([aux2[1], float(aux2[2]), float(aux2[3])])}) # split measurements info for idx, k in enumerate(measurements): aux2 = k.split() for l in aux2: aux3 = l.split(":") self.measurements[idx].append(tuple(aux3)) # Saves the problem information in problem attributes self.rooms = rooms self.connections = tuple(self.connections) self.prob = float(prob) self.measurements = tuple(self.measurements) self.map = {} # Map - Adjacent rooms of each room # Dictionary with rooms connections for room in self.rooms: self.map.update({room:[]}) # Map - Adjacent rooms of each room if self.connections: for connect in self.connections: self.map[connect[0]].append(connect[1]) self.map[connect[1]].append(connect[0]) self.T = self.nb_measurements self.nb_sensors = len(self.sensors) #number of sensores #Create Baysean Network self.BNet = probability.BayesNet() # Creates the Baysean Network taking into account each timestamp for time in range(self.T): time = time + 1 # Time starts at 1 if time == 1: # in T = 1, rooms don't have parents for room in self.map: # add rooms as parent nodes roomT = None roomT = room + '_t' + str(time) self.BNet.add((roomT,'',0.5)) # Initially all rooms are parents else: #if time > 1 -> rooms have parents -> rooms in the previous time and adjacent rooms for room in self.map: roomT = None nb_parents = 0 room_parents = None roomT = room + '_t' + str(time) room_parents = room + '_t' + str(time-1) nb_parents += 1 if self.map[room]: for room_index in range(len(self.map[room])): room_adjacent = self.map[room][room_index] room_parents = room_parents +" " + room_adjacent + '_t' + str(time-1) nb_parents +=1 if nb_parents == 1: self.BNet.add((roomT, room_parents, {True:1.0, False:0.0})) #generate truth table based on the number of parents elif nb_parents > 1: lst = [] lst = list(itertools.product([True, False], repeat=nb_parents)) logic_table = {} logic_table = dict((i,0) for i in lst) for key in logic_table: if key[0] == True: logic_table[key] = 1.0 elif key[0] == False and all(key): logic_table[key] = 0.0 elif key[0] == False: if True in key: logic_table[key] = self.prob #print(logic_table) self.BNet.add((roomT,room_parents,logic_table)) for meas in self.measurements[time-1]: # add sensor nodes as childs of the room where the sensor is located in the current timestamp sensor = meas[0] parent_room = self.sensors[sensor][0] # Parent node of the sensor TPR = self.sensors[sensor][1] # True Positive Rate FPR = self.sensors[sensor][2] # False Positive Rate self.BNet.add((sensor+'_t'+str(time),parent_room + '_t'+ str(time),{True: TPR, False: FPR}))
def __init__(self, fh): """ Place here your code to load problem from opened file object fh and use probability.BayesNet() to create the Bayesian network""" self.building = {} self.alarms = {} self.evidence = {} self.p = 1 # Reasonable default self.measurements = [] self.net = probability.BayesNet() self.meas_cnt = 0 for ln in (ln for ln in fh.readlines() if len(ln.split()) > 0): l_array = ln.split() # Set of Rooms if l_array[0] == 'R': for room in l_array[1:]: self.building[room] = Room() # Set of connections elif l_array[0] == 'C': for word in l_array[1:]: connection = word.split(',') self.building[connection[0]].connections.add(connection[1]) self.building[connection[1]].connections.add(connection[0]) # Set of sensors elif l_array[0] == 'S': for info in l_array[1:]: sensor = info.split(':') self.alarms[sensor[0]] = sensor[1:] # Propagation Probabilities elif l_array[0] == 'P': self.p = float(l_array[1]) # Measurement elif l_array[0] == 'M': self.meas_cnt += 1 meas_t = [] for meas in l_array[1:]: aux = meas.split(':') meas_t.append(aux) self.measurements.append(meas_t) else: raise RuntimeError("Bad Format Error") t = 0 # for each time instant for meas_t in self.measurements: t += 1 for room_name, room in self.building.items(): parents = [] # unknown prior at start if t == 1: self.net.add((room_name + '_1', '', 0.5)) else: # Add previous room to parents nodes parents.append(room_name + '_' + str(t - 1)) # Adds adjacent rooms for adj_room in room.connections: parents.append(adj_room + '_' + str(t - 1)) # Build truth table truth_table = {} for p in product((True, False), repeat=len(parents)): # previous room on fire if p[0] is True: truth_table[p] = 1 else: truth_table[p] = self.p if p.count(True) > 0 else 0 # Add room to net self.net.add( (room_name + '_' + str(t), parents, truth_table)) # Inserts sensor and adds measurement to evidence pool for meas in meas_t: sensor_room = self.alarms[meas[0]][0] + '_' + str(t) # True: TPR , False: FPR self.net.add((meas[0] + '_' + str(t), sensor_room, { True: float(self.alarms[meas[0]][1]), False: float(self.alarms[meas[0]][2]) })) self.evidence[meas[0] + '_' + str(t)] = True if meas[1] == 'T' else False
fire = probability.BayesNet([ ('R02_0', '', 0.5000000000000000), ('R03_0', '', 0.5000000000000000), ('R03_1', 'R02_0 R03_0', {(T, T): 1, (T, F): 0.07549526619046759, (F, T): 1, (F, F): 0}), ('R02_1', 'R02_0 R03_0', {(T, T): 1, (T, F): 1, (F, T): 0.07549526619046759, (F, F): 0}), ('S01_1', 'R03_1', {T: 0.9423140000000000, F: 0.1215520000000000}), ('R03_2', 'R02_1 R03_1', {(T, T): 1, (T, F): 0.07549526619046759, (F, T): 1, (F, F): 0}), ('R02_2', 'R02_1 R03_1', {(T, T): 1, (T, F): 1, (F, T): 0.07549526619046759, (F, F): 0}), ('S01_2', 'R03_2', {T: 0.9423140000000000, F: 0.1215520000000000}), ('R03_3', 'R02_2 R03_2', {(T, T): 1, (T, F): 0.07549526619046759, (F, T): 1, (F, F): 0}), ('R02_3', 'R02_2 R03_2', {(T, T): 1, (T, F): 1, (F, T): 0.07549526619046759, (F, F): 0}), ('S01_3', 'R03_3', {T: 0.9423140000000000, F: 0.1215520000000000}), ('R03_4', 'R02_3 R03_3', {(T, T): 1, (T, F): 0.07549526619046759, (F, T): 1, (F, F): 0}), ('R02_4', 'R02_3 R03_3', {(T, T): 1, (T, F): 1, (F, T): 0.07549526619046759, (F, F): 0}), ('S01_4', 'R03_3', {T: 0.9423140000000000, F: 0.1215520000000000})])
def solve(self): T, F = True, False net = probability.BayesNet() # time 0 i = 0 for room in self.R: net.add((room + str(i), '', 0.5)) for sensor in self.S: a = float(sensor[2]) b = float(sensor[3]) net.add((sensor[0] + str(i), sensor[1] + '0', {T: a, F: b})) # as many time samples as measurements for k in range(len(self.M) - 1): #ordem dos for esta a tornar o programa lento i = i + 1 node_specs = [] for room in self.R: #room's nodes parents = room + str( i - 1 ) #first parent is always the room at the previous sample time X = room + str(i) for p in self.adjDict[room]: parents = parents + ' ' + p + str(i - 1) # probability table cpt = {} n = len(self.adjDict[room]) + 1 matrix = self.truthtable(n) for element in matrix: key = tuple(element) value = 0 #confirm this value if key[0] is T: value = 1 else: if len(key) > 1: #safety for bl in key[1:]: if bl is True: value = self.P break cpt.update({key: value}) net.add((X, parents, cpt)) for sensor in self.S: #sensor nodes --> fazer dicionario com estes valores de TPR e FPR? a = float(sensor[2]) b = float(sensor[3]) net.add(((sensor[0]) + str(i), (sensor[1] + str(i)), { T: a, F: b })) evidences = {} for i in range(len(self.M)): for sensor in self.M[i]: evidences.update({sensor[0] + str(i): sensor[1] is 'T'}) p = {} for room in self.R: p.update({ room: probablity.elimination_ask(room + str(len(self.M) - 1), evidences, net)[1] }) room = max(p, key=p.get) answer = (room, p[room]) #print(answer) #name = self.R[0] + '0' """"name = 'S010' node = net.variable_node(name) print(node.variable, node.parents)""" "" return answer
def __init__(self, fh): # Place here your code to load problem from opened file object fh # and use probability.BayesNet() to create the Bayesian network self.BN,self.vars,self.R,self.C,self.S,self.P,self.M=[],[],[],[],[],[],[] f1 = fh.readlines() edges = [] node_specs = [] parents = {} T = True F = False for i in f1: if i[0] == 'R': self.R = i.rstrip()[2:].split() for j in self.R: self.vars.append(j) elif i[0] == 'C': self.C = i.rstrip()[2:].split() elif i[0] == 'S': self.S = i.rstrip()[2:].split() elif i[0] == 'P': self.P.append(i.rstrip()[2:]) elif i[0] == 'M': self.M.append(i.rstrip()[2:]) for i in self.C: edges.append(i.split(',')) #creates node_specs vector for root nodes and template parents dictionary (will serve the purpose of building the remaining node_specs vector) for i in self.vars: parents[i] = [i] for j in edges: for k in j: if k == i: a = [x for x in j if x != k] parents[i].append(''.join(a)) if i not in node_specs: node_specs.append((i, '', 0.5)) parentes = {} #Creates dict with ammount of parents per variable (useful for cpt tables creation) prnt_num = {} tm = 0 for i in parents: prnt_num.update({i: len(parents[i])}) tm = max(prnt_num[i], tm) #Generates different size tables for cpt tt = [] table = {} for i in range(tm): if i == 0: table[i + 1] = {T: 1, F: 0} else: for j in range(2**(i + 1)): booltuple = tuple( list( map( bool, list( map( int, list( format(j, '#0' + str(i + 1 + 2) + 'b').split('b')[1])))))) power = sum(list(map(int, booltuple[1:len(booltuple)]))) prob = 1 - (1 - float(''.join(self.P)))**(power) if booltuple[0]: tt = {booltuple: 1} else: tt = {booltuple: prob} if (i + 1) not in table.keys(): table[i + 1] = tt else: table[i + 1].update(tt) #creates the node_specs vector for BayesNet excluding evidence nodes (sensors) for j in range(len(self.M)): for i in self.vars: if j == 1: node_specs.append( (i + '_t+1', ' '.join(parents[i]), table[prnt_num[i]])) if j > 1: parentes = [] for k in parents[i]: parentes.append(k + '_t+' + str(j - 1)) node_specs.append((i + '_t+' + str(j), ' '.join(parentes), table[prnt_num[i]])) # Sensor: True | Variable: True - TPR # Sensor: True | Variable: False - FPR # Sensor: False | Variable: True - FNR # Sensor: False | Variable: False - TNR # P(S01=T|parent=T) =TPR (given) # P(S01=T|parent=F) = FPR (given) #creates evidence nodes node_specs remaining for the BayesNet for i in self.S: temp = i.split(':') TPR = float(temp[2]) FPR = float(temp[3]) for j in range(len(self.M)): if temp[0] in self.M[j]: if j == 0: node_specs.append((temp[0], temp[1], {T: TPR, F: FPR})) if j >= 1: node_specs.append((temp[0] + '_t+' + str(j), temp[1] + '_t+' + str(j), { T: TPR, F: FPR })) #build BayesNet self.BN = probability.BayesNet(node_specs)