Example #1
0
    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
Example #2
0
    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()
Example #4
0
    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
Example #5
0
    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}))
Example #6
0
    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})])

Example #8
0
    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
Example #9
0
    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)