Exemple #1
0
    def pgm_generate(self, target, data, stats, subnodes):
        stats_pd = pd.Series(stats, name='p-values')
        MK_blanket_frame = stats_pd[stats_pd < 0.05]
        MK_blanket = [node for node in MK_blanket_frame.index if node in subnodes]
        subnodes_no_target = [node for node in subnodes if node != target]
        est = HillClimbSearch(data[subnodes_no_target], scoring_method=BicScore(data))
        pgm_no_target = est.estimate()
        for node in MK_blanket:
            if node != target:
                pgm_no_target.add_edge(node,target)

    #   Create the pgm    
        pgm_explanation = BayesianModel()
        for node in pgm_no_target.nodes():
            pgm_explanation.add_node(node)
        for edge in pgm_no_target.edges():
            pgm_explanation.add_edge(edge[0],edge[1])

    #   Fit the pgm
        data_ex = data[subnodes].copy()
        data_ex[target] = data[target].apply(self.generalize_target)
        for node in subnodes_no_target:
            data_ex[node] = data[node].apply(self.generalize_others)
        pgm_explanation.fit(data_ex)

        return pgm_explanation
    def pgm_generate(self, target, data, pgm_stats, subnodes, child=None):

        subnodes = [str(int(node)) for node in subnodes]
        target = str(int(target))
        subnodes_no_target = [node for node in subnodes if node != target]
        data.columns = data.columns.astype(str)

        MK_blanket = self.search_MK(data, target, subnodes_no_target.copy())

        if child == None:
            est = HillClimbSearch(data[subnodes_no_target],
                                  scoring_method=BicScore(data))
            pgm_no_target = est.estimate()
            for node in MK_blanket:
                if node != target:
                    pgm_no_target.add_edge(node, target)

        #   Create the pgm
            pgm_explanation = BayesianModel()
            for node in pgm_no_target.nodes():
                pgm_explanation.add_node(node)
            for edge in pgm_no_target.edges():
                pgm_explanation.add_edge(edge[0], edge[1])

        #   Fit the pgm
            data_ex = data[subnodes].copy()
            data_ex[target] = data[target].apply(self.generalize_target)
            for node in subnodes_no_target:
                data_ex[node] = data[node].apply(self.generalize_others)
            pgm_explanation.fit(data_ex)
        else:
            data_ex = data[subnodes].copy()
            data_ex[target] = data[target].apply(self.generalize_target)
            for node in subnodes_no_target:
                data_ex[node] = data[node].apply(self.generalize_others)

            est = HillClimbSearch(data_ex, scoring_method=BicScore(data_ex))
            pgm_w_target_explanation = est.estimate()

            #   Create the pgm
            pgm_explanation = BayesianModel()
            for node in pgm_w_target_explanation.nodes():
                pgm_explanation.add_node(node)
            for edge in pgm_w_target_explanation.edges():
                pgm_explanation.add_edge(edge[0], edge[1])

            #   Fit the pgm
            data_ex = data[subnodes].copy()
            data_ex[target] = data[target].apply(self.generalize_target)
            for node in subnodes_no_target:
                data_ex[node] = data[node].apply(self.generalize_others)
            pgm_explanation.fit(data_ex)

        return pgm_explanation
def pgmpy_test():

    raw_data = np.array([0] * 30 +
                        [1] * 70)  # Representing heads by 0 and tails by 1
    data = pd.DataFrame(raw_data, columns=['coin'])
    print(data)
    model = BayesianModel()
    model.add_node('coin')

    # Fitting the data to the model using Maximum Likelihood Estimator
    model.fit(data, estimator=MaximumLikelihoodEstimator)
    print(model.get_cpds('coin'))
Exemple #4
0
def make_power_plant_net():
    BayesNet = BayesianModel()
    BayesNet.add_node('temperature')
    BayesNet.add_node('faulty gauge')
    BayesNet.add_node('gauge')
    BayesNet.add_node('faulty alarm')
    BayesNet.add_node('alarm')
    BayesNet.add_edge('temperature', 'faulty gauge')
    BayesNet.add_edge('temperature', 'gauge')
    BayesNet.add_edge('faulty gauge', 'gauge')
    BayesNet.add_edge('gauge', 'alarm')
    BayesNet.add_edge('faulty alarm', 'alarm')
    return BayesNet
def get_game_network():
    """Create a Bayes Net representation of the game problem.
    Name the nodes as "A","B","C","AvB","BvC" and "CvA".  """
    BayesNet = BayesianModel()
    # TODO: fill this out
    BayesNet.add_node("A")  
    BayesNet.add_node("B")
    BayesNet.add_node("C")
    BayesNet.add_node("AvB")
    BayesNet.add_node("BvC")
    BayesNet.add_node("CvA")
    BayesNet.add_edge("A","AvB")
    BayesNet.add_edge("A","CvA")
    BayesNet.add_edge("B","AvB")
    BayesNet.add_edge("B","BvC")
    BayesNet.add_edge("C","BvC")
    BayesNet.add_edge("C","CvA")
    cpd_a = TabularCPD('A', 4, values=[[0.15], [0.45],[0.3],[0.1]])
    cpd_b = TabularCPD('B', 4, values=[[0.15], [0.45],[0.3],[0.1]])
    cpd_c = TabularCPD('C', 4, values=[[0.15], [0.45],[0.3],[0.1]])
    cpd_avb=TabularCPD("AvB",3, values=[[0.1,0.2,0.15,0.05,0.6,0.1,0.2,0.15,0.75,0.6,0.1,0.2,0.9,0.75,0.6,0.1],\
                       [0.1,0.6,0.75,0.9,0.2,0.1,0.6,0.75,0.15,0.2,0.1,0.6,0.05,0.15,0.2,0.1],\
                       [0.8,0.2,0.1,0.05,0.2,0.8,0.2,0.1,0.1,0.2,0.8,0.2,0.05,0.1,0.2,0.8]],\
                       evidence=["A","B"], evidence_card=[4, 4])
    cpd_bvc=TabularCPD("BvC",3, values=[[0.1,0.2,0.15,0.05,0.6,0.1,0.2,0.15,0.75,0.6,0.1,0.2,0.9,0.75,0.6,0.1],\
                       [0.1,0.6,0.75,0.9,0.2,0.1,0.6,0.75,0.15,0.2,0.1,0.6,0.05,0.15,0.2,0.1],\
                       [0.8,0.2,0.1,0.05,0.2,0.8,0.2,0.1,0.1,0.2,0.8,0.2,0.05,0.1,0.2,0.8]],\
                       evidence=["B","C"], evidence_card=[4, 4])
    cpd_cva=TabularCPD("CvA",3, values=[[0.1,0.2,0.15,0.05,0.6,0.1,0.2,0.15,0.75,0.6,0.1,0.2,0.9,0.75,0.6,0.1],\
                       [0.1,0.6,0.75,0.9,0.2,0.1,0.6,0.75,0.15,0.2,0.1,0.6,0.05,0.15,0.2,0.1],\
                       [0.8,0.2,0.1,0.05,0.2,0.8,0.2,0.1,0.1,0.2,0.8,0.2,0.05,0.1,0.2,0.8]],\
                       evidence=["C","A"], evidence_card=[4, 4])
    BayesNet.add_cpds(cpd_a,cpd_b,cpd_c,cpd_avb,cpd_bvc,cpd_cva)
    return BayesNet
Exemple #6
0
def get_game_network():
    """Create a Bayes Net representation of the game problem.
    Name the nodes as "A","B","C","AvB","BvC" and "CvA".  """
    BayesNet = BayesianModel()
    # TODO: fill this out
    BayesNet.add_node("A")
    BayesNet.add_node("B")
    BayesNet.add_node("C")
    BayesNet.add_node("AvB")
    BayesNet.add_node("BvC")
    BayesNet.add_node("CvA")

    BayesNet.add_edge("A", "AvB")
    BayesNet.add_edge("A", "CvA")
    BayesNet.add_edge("B", "AvB")
    BayesNet.add_edge("B", "BvC")
    BayesNet.add_edge("C", "BvC")
    BayesNet.add_edge("C", "CvA")

    skill_dist = [[0.15], [0.45], [0.30], [0.10]]
    a_cpd = TabularCPD("A", 4, values=skill_dist)
    b_cpd = TabularCPD("B", 4, values=skill_dist)
    c_cpd = TabularCPD("C", 4, values=skill_dist)

    game_dist = [[
        0.1, 0.2, 0.15, 0.05, 0.6, 0.1, 0.2, 0.15, 0.75, 0.6, 0.1, 0.2, 0.9,
        0.75, 0.6, 0.1
    ],
                 [
                     0.1, 0.6, 0.75, 0.9, 0.2, 0.1, 0.6, 0.75, 0.15, 0.2, 0.1,
                     0.6, 0.05, 0.15, 0.2, 0.1
                 ],
                 [
                     0.8, 0.2, 0.1, 0.05, 0.2, 0.8, 0.2, 0.1, 0.1, 0.2, 0.8,
                     0.2, 0.05, 0.1, 0.2, 0.8
                 ]]

    # avb_cpd = TabularCPD("AvB", 3, values=game_dist, evidence=["A", "B"], evidence_card=[4, 4])
    avb_cpd = TabularCPD("AvB",
                         3,
                         values=game_dist,
                         evidence=["A", "B"],
                         evidence_card=[4, 4])
    bvc_cpd = TabularCPD("BvC",
                         3,
                         values=game_dist,
                         evidence=["B", "C"],
                         evidence_card=[4, 4])
    cva_cpd = TabularCPD("CvA",
                         3,
                         values=game_dist,
                         evidence=["C", "A"],
                         evidence_card=[4, 4])

    BayesNet.add_cpds(a_cpd, b_cpd, c_cpd, avb_cpd, bvc_cpd, cva_cpd)
    return BayesNet
def make_power_plant_net():
    """Create a Bayes Net representation of the above power plant problem. 
    Use the following as the name attribute: "alarm","faulty alarm", "gauge","faulty gauge", "temperature". (for the tests to work.)
    """
    BayesNet = BayesianModel()
    # TODO: finish this function    
    BayesNet.add_node("alarm")
    BayesNet.add_node("faulty alarm")
    BayesNet.add_node("gauge")
    BayesNet.add_node("faulty gauge")
    BayesNet.add_node("temperature")
    BayesNet.add_edge("gauge","alarm")
    BayesNet.add_edge("temperature","gauge")
    BayesNet.add_edge("temperature","faulty gauge")
    BayesNet.add_edge("faulty gauge","gauge")
    BayesNet.add_edge("faulty alarm","alarm")
    return BayesNet
Exemple #8
0
    def join(reference_bayes, second_bayes, new_dependent_vars,
             new_independent_vars, ref_num_of_records, second_num_of_records):
        final_bayes = BayesianModel()
        #all independent variables should stay the same
        final_bayes.add_nodes_from(new_independent_vars)
        final_bayes.add_cpds(*[
            reference_bayes.get_cpds(node=node) if node in
            reference_bayes.nodes else second_bayes.get_cpds(node=node)
            for node in new_independent_vars
        ])
        for node in new_dependent_vars:
            final_bayes.add_node(node)
            ref_parents = set()
            second_parents = set()
            if node in reference_bayes:
                ref_parents = set(reference_bayes.get_parents(node))
            if node in second_bayes:
                second_parents = set(second_bayes.get_parents(node))

            if (len(ref_parents) == 0):
                final_bayes.add_edges_from([(parent, node)
                                            for parent in second_parents])
                final_bayes.add_cpds(second_bayes.get_cpds(node=node))
            else:
                final_bayes.add_edges_from([(parent, node)
                                            for parent in ref_parents])
                if len(second_parents - ref_parents) > 0:
                    raise ValueError('This join can not be performed since the\
                         second distribution contains new independent variable\
                         (s) for node {}. Please consider dropping these new \
                         dependencies or switching reference distribution. '.
                                     format(str(node)))
                elif ref_parents == second_parents:
                    new_cpd = BayesNetHelper.calculate_weighted_cpds(
                        reference_bayes.get_cpds(node=node),
                        second_bayes.get_cpds(node=node), ref_num_of_records,
                        second_num_of_records)
                    final_bayes.add_cpds(new_cpd)
                else:
                    final_bayes.add_cpds(reference_bayes.get_cpds(node=node))
        return final_bayes
class InferenceEngine:
    def load_file(self, path):
        self.data = pd.read_excel(path)
        self.variables = list(self.data.columns)

        self.model = BayesianModel()
        for var in self.variables:
            self.model.add_node(var)

        self.model.fit(self.data, estimator=BayesianEstimator)

    def load_model(self, model):
        self.data = pd.read_json(model['dataset'])
        self.variables = list(self.data.columns)
        self.model = BayesianModel(model['modelStructure'])
        self.model.fit(self.data, estimator=BayesianEstimator)

    def load_structure(self, model_structure):
        self.model = BayesianModel(model_structure)
        self.model.fit(self.data, estimator=BayesianEstimator)

    def query(self, variables, evidence):
        bp = VariableElimination(self.model)
        return bp.query(variables, evidence=evidence)
def make_power_plant_net():
    BayesNet = BayesianModel()
    # TODO: finish this function
    BayesNet.add_node("A")
    BayesNet.add_node("B")
    BayesNet.add_node("C")
    BayesNet.add_node("D")
    BayesNet.add_node("E")
    BayesNet.add_node("F")
    BayesNet.add_node("J")
    BayesNet.add_edge("A", "C")
    BayesNet.add_edge("B", "C")
    BayesNet.add_edge("C", "D")
    BayesNet.add_edge("C", "E")
    BayesNet.add_edge("E", "J")
    BayesNet.add_edge("F", "J")
    return BayesNet
Exemple #11
0
def get_structure(data):
    """
    Structure of model from data (Loaded RDS)

    Parameters
    ----------
    data :
        RDS data object
    model : BayesianModel
        Empty network

    Returns
    -------
    model : BayesianModel
        Model converted from RDS to python
    """
    model = BayesianModel()
    for k in range(len(data)):
        node = list(data[k][0])[0]
        children = list(data[k][2])
        model.add_node(node)
        for child in children:
            model.add_edge(node, child)
    return model
Exemple #12
0
def make_power_plant_net():
    BayesNet = BayesianModel()
    # TODO: finish this function
    BayesNet.add_node("NI")
    BayesNet.add_node("St")
    BayesNet.add_node("I")
    BayesNet.add_node("S")
    BayesNet.add_node("T")
    BayesNet.add_node("L")
    BayesNet.add_node("B")
    BayesNet.add_edge("NI", "I")
    BayesNet.add_edge("St", "I")
    #BayesNet.add_edge("I","S")
    BayesNet.add_edge("I", "T")
    BayesNet.add_edge("I", "L")
    BayesNet.add_edge("S", "L")
    BayesNet.add_edge("S", "B")
    return BayesNet
Exemple #13
0
class Utilities(object):
    def __init__(self, file):
        ''' no object creation -> opportune  ?'''
        self.keywords = ['BENS', 'MEMS', 'LANS', 'MOTOR', 'WORLD']
        self.standard_nodes = {
            'RONS': {
                'BENS': [],
                'MEMS': []
            },
            'LANS': {
                'LANS': []
            },
            'LENS': {
                'MOTOR': [],
                'WORLD': []
            }
        }
        self.file = file
        self.get_json_path(file)
        self.pgmpy_object = BayesianModel()
        self.networkx_object = nx.DiGraph()
        self.header = ''
        self.dictionary = []

    def get_nodes_in_family(self, family, attributes=False):
        nw_nodes = self.networkx_object.nodes()
        nw_dim = np.asarray(nw_nodes).ndim
        nodes = []
        for i, node in enumerate(nw_nodes):
            if nw_dim > 1:
                node = node[0]
            if family in node:
                nodes.append(node)
        return nodes

    def check_json_path(directory):
        """
        Checks whether the necessary project_repository directory exists.
        If not, creates it

        :param directory: the mother directory to search from downwards

        :type directory: string
        :rtype : none
        """
        if not os.path.exists(directory + '\project_repository\\'):
            os.makedirs(directory + '\project_repository\\')

    def get_json_path(self, file):
        """
        Creates a string containing the full path for the filename passed
        so it will be saved in the project_repository directory

        :param filename: filename without path or extension
        :return: a full path for the file

        :type filename :string
        :rtype : string
        """
        levels = 5
        common = os.path.dirname(os.path.realpath(__file__))
        for i in range(levels + 1):
            common = os.path.dirname(common)
            if 'peepo\peepo' not in common:
                break
        Utilities.check_json_path(common)
        self.file = str(common + '\project_repository\\' + file + '.json')
        print('in get_json_path :', self.file)

    def save_json(self, astring):
        """
        This helping function is only needed to have the json file  formatted in a user friendly way
        as the "dump" method does not provide a lot of possibilities to get it "pretty"

        :param file :the ull path of the json file
        :param astring: the name of the string containing the whole information
        :return: void
        :type file: string
        :type astring : string
        :rtype : void
        """
        text_file = open(str(self.file), "w")
        '''remove all LF written by the dump method'''
        astring = re.sub('\n', '', astring)
        '''For keywords -> insert LF and tabs'''
        astring = re.sub('\"Identification', '\n\"Identification', astring)
        astring = re.sub('\"Date', '\n\"Date', astring)
        astring = re.sub('\"Description', '\n\"Description', astring)
        astring = re.sub('\"Train_from', '\n\"Train_from', astring)
        astring = re.sub('\"Frozen', '\n\"Frozen', astring)
        astring = re.sub('\"Nodes', '\n\n\"Nodes', astring)
        astring = re.sub('\"RONS', '\n\t\t\"RONS', astring)
        astring = re.sub('\"BENS', '\n\t\t\t\"BENS', astring)
        astring = re.sub('\"MEMS', '\n\t\t\t\"MEMS', astring)
        astring = re.sub('\"LANS', '\n\t\t\"LANS', astring)
        astring = re.sub('\"LENS', '\n\t\t\"LENS', astring)
        astring = re.sub('\"MOTOR', '\n\t\t\t\"MOTOR', astring)
        astring = re.sub('\"WORLD', '\n\t\t\t\"WORLD', astring)
        astring = re.sub('\"Edges', '\n\n\"Edges', astring)
        astring = re.sub('\"CPDs', '\n\n\"CPDs', astring)
        astring = re.sub('{', '\n\t\t{', astring)
        text_file.write(astring)
        text_file.write('\n')
        text_file.close()

    def translation(self, astring, from_man_to_machine):
        """
        Given an array of tuples (a,b) in dictionary, returns the second element of the tuple where astring was found
        Is used to not loose the users node names as peepo generates standardized names for the corresponding node

        :param dictionary:an array of tuples -> is created in the method : get_network(file)
        :param astring: the name of the node passsed by the user
        :param from_man_to_machine: an integer -> 0 when we want the translation for the user give name to the standardized name, 1 the other way around
        :return: the corresponding standardized node name
        :type dictionary: np.array
        :type astring : string
        :rtype : string
        """
        source = 0
        target = 1
        if from_man_to_machine == 1:
            source = 1
            target = 0

        for index, item in enumerate(self.dictionary):
            if item[source] == astring:
                break
        return item[target]

    def clean_edge_list(self, edge_array, parent):
        '''the get functions for the edges, both in networx as pgmpy contain the parent name
            this function removes it from the list'''
        cleaned_list = []
        for a in edge_array:
            if a != parent:
                cleaned_list.append(a)
        return cleaned_list

    def clean_parent_list(self, parent_array, child):
        '''the get functions for the edges, both in networx as pgmpy contain the parent name
            this function removes it from the list'''
        cleaned_list = []
        for i, a in enumerate(parent_array):
            if a[0] != child:
                cleaned_list.append(a[0])
        return cleaned_list

    def get_edges(self):
        """
        Creates a dictionary with a node as a key and an array with its child as value
        (the methods get_child give generally a list of tuples (parent,child)

        :param  pgmpy_object: the pgmpy network
        :return: a dictionary with the edges of all the node

        :type fpgmpy_object:adress
        :rtype :dictionary
                """
        edg = self.pgmpy_object.edges()
        edges = dict()
        [
            edges[str(t[0])].append(str(t[1])) if t[0] in list(edges.keys())
            else edges.update({str(t[0]): [str(t[1])]}) for t in edg
        ]
        return edges

    def get_nodes_and_attributes(self):
        """
        Creates an  array  of tuple with a node as element 0 and a dictionary with cardinalities and cpd as key's and
         the key cardinality returns an int
         the key cpd a 2 dimensional matrix

        :param  pgmpy_object: the pgmpy network
        :return: array  of tuple with a node as element 0 and a dictionary with cardinalities and cpd as key's

        :type  :pgmpy_object:adress
        :rtype :array of tuples
        """
        nodes = self.pgmpy_object.nodes()
        nod_and_attributes = []
        [
            nod_and_attributes.append((str(node), {
                'cardinality':
                int(self.pgmpy_object.get_cardinality(node)),
                'cpd':
                self.pgmpy_object.get_cpds(node).values.astype(float)
            })) for i, node in enumerate(nodes)
        ]
        #need to reshape the cpds when more than 1 parent
        for i, node in enumerate(nod_and_attributes):
            shape = nod_and_attributes[i][1]['cpd'].shape
            dimension = nod_and_attributes[i][1]['cpd'].ndim
            if dimension > 2:
                col = int(np.prod(shape) / shape[0])
                nod_and_attributes[i][1]['cpd'] = nod_and_attributes[i][1][
                    'cpd'].reshape(shape[0], col)
            nod_and_attributes[i][1]['cpd'] = nod_and_attributes[i][1][
                'cpd'].tolist()
        return nod_and_attributes

    def translate_pgmpy_to_digraph(self):
        """
        Converts a pgmpy network into a networkx network

        :param  pgmpy_object: the pgmpy network
        :return networkx : networkx network

        :type  :pgmpy_object:adress
        :rtype :networkx:adress
        """
        self.networkx_object = nx.DiGraph()
        edges = self.pgmpy_object.edges()
        nodes_and_attributes = self.get_nodes_and_attributes()
        self.networkx_object.add_nodes_from(nodes_and_attributes)
        self.networkx_object.add_edges_from(edges)
        return

    def update_networkx(self, networkx, dic, header):
        self.header = header
        self.dictionary = dic
        self.networkx_object = networkx

    def update_pgmpy(self, pgmpy, dic, header):
        self.header = header
        self.dictionary = dic
        self.pgmpy_object = pgmpy

    def save_pgmpy_network(self):
        """
                Saves the passed pgmpy_object class object in a json file
        """
        self.translate_pgmpy_to_digraph()
        self.save_network()
        return

    def translate_digraph_to_pgmpy(self, digraf):
        """
        Converts a pgmpy network into a networkx network

        :param  pgmpy_object: the pgmpy network
        :return networkx : networkx network

        :type  :pgmpy_object:adress
        :rtype :networkx:adress
        """
        self.pgmpy_object, x, y = self.get_pgmpy_network(from_object=True,
                                                         digraph=digraf)
        return self.pgmpy_object

    def translate_pgmpy_to_digraph(self):
        """
        Converts a pgmpy network into a networkx network

        :param  pgmpy_object: the pgmpy network
        :return networkx : networkx network

        :type  :pgmpy_object:adress
        :rtype :networkx:adress
        """
        self.networkx_object = nx.DiGraph()
        edges = self.pgmpy_object.edges()
        nodes_and_attributes = self.get_nodes_and_attributes()
        self.networkx_object.add_nodes_from(nodes_and_attributes)
        self.networkx_object.add_edges_from(edges)
        return

    def save_network(self):
        """
        Saves the passed networkx class object in a json file

        """
        data = self.get_empty_canvas()
        data["header"] = self.header
        nw_nodes = self.networkx_object.nodes(data=True)
        nw_edges = self.networkx_object.edges()
        keywords = self.keywords
        nodes = copy.deepcopy(
            self.standard_nodes
        )  #{'RONS': {'BENS': [], 'MEMS': []}, 'LANS': {'LANS': []}, 'LENS': {'MOTOR': [], 'WORLD': []}}
        edges = []
        cpds = []
        '''adding edges'''
        for i, node in enumerate(nw_nodes):
            node_name = node[0]
            childs = []
            for k, edge in enumerate(nw_edges):
                if edge[0] == node_name:
                    childs.append(self.translation(edge[1], 1))
            if len(childs) != 0:
                edges.append({self.translation(node_name, 1): childs})

        for i, node in enumerate(nw_nodes):
            node_name = node[0]
            cardinality = node[1]['cardinality']
            cpd = node[1]['cpd']
            for pseudonym in keywords:
                if pseudonym in node_name:
                    node_name_ = self.translation(node_name, 1)
                    if pseudonym == 'BENS' or pseudonym == 'MEMS':
                        nodes['RONS'][pseudonym].append(
                            [node_name_, cardinality])
                    if pseudonym == 'LANS':
                        nodes['LANS'][pseudonym].append(
                            [node_name_, cardinality])
                    if pseudonym == 'MOTOR' or pseudonym == 'WORLD':
                        nodes['LENS'][pseudonym].append(
                            [node_name_, cardinality])
            cpds.append({self.translation(node_name, 1): cpd})
        data['Nodes'] = nodes
        data['Edges'] = edges
        data['CPDs'] = cpds
        data['header']['Date'] = datetime.datetime.now().strftime("%c")
        self.save_json(json.dumps(data))
        return

    def get_pgmpy_network(self, from_object=False, digraph=None):
        """
        Reads the passed json file and translates it's content to the passed pgmpy class object
        - uses the get_network(file) to read the json file in a networkx format and translate this to pgmpy
        - Creates a dictionary for the nodes in the form of an array of tuples : [(names defines by user, standard name)]

        :param file: : filename without path or extension
        :pgmp_object : the pgmpy object which will be completed
        :return: a dictionary as an array of tuples and the header of the json file

        :type file : string
        :type pgmp_object : pgmpy class object
        :rtype : array of tuples, dictionary

        CAUTION : the method does not perform a check() on the constructed DAG ! -> has to be done in the calling module
        """
        self.pgmpy_object = BayesianModel()
        if not (from_object):
            network, dictionary, header = self.get_network()
        else:
            network = digraph
        nw_nodes = network.nodes(data=True)
        nw_edges = network.edges()
        '''adding nnodes and edges'''
        for i, node in enumerate(nw_nodes):
            node_name = node[0]
            self.pgmpy_object.add_node(node_name)
            for k, edge in enumerate(nw_edges):
                if edge[0] == node_name:
                    self.pgmpy_object.add_edge(node_name, edge[1])
        '''add  cpd's'''
        for i, node in enumerate(nw_nodes):
            parent_nodes = network.in_edges(node[0])
            parent_nodes = self.clean_parent_list(parent_nodes, node[0])
            cpd = node[1]['cpd']
            ''' find the cardinality of the node '''
            cardinality_node = node[1]['cardinality']
            """  cardinality card of parents has to be determined"""
            cardinality_parents = []
            for i, nod in enumerate(parent_nodes):
                cardinality_parents.append(network.node[nod]['cardinality'])
            ''' Depending on the place in the BN and/or the number of parents  the PGMPY CPD methods have another call'''
            if len(cardinality_parents) == 0:
                self.pgmpy_object.add_cpds(
                    TabularCPD(variable=node[0],
                               variable_card=cardinality_node,
                               values=[cpd]))
                continue
            table = TabularCPD(variable=node[0], variable_card= cardinality_node, values=cpd, \
                              evidence=parent_nodes,\
                              evidence_card=np.asarray(cardinality_parents))
            self.pgmpy_object.add_cpds(table)
        '''------TO DELETE-------------'''
        # pgmpy_object.check_model()
        # draw_network(pgmpy_object)
        '''-----------------------------'''
        return self.pgmpy_object, self.dictionary, self.header

    def get_network(self):
        """
        Reads the passed json file and translate it's content in a networkx class object
        - The nodes in the object are renamed so they have a standardized signature
        - Creates a dictionary for the nodes in the form of an array of tuples : [(names defines by user, standard name)]

        :param file: : filename without path or extension
        :return: a networkx class object, dictionary as an array of tuples and the header of the json file

        :type file : string
        :rtype : networkx class object, array of tuples, dictionary
        """
        self.dictionary = []
        self.networkx_object = nx.DiGraph()
        with open(self.file) as f:
            data = f.read()
        '''Remove possible non informative characters'''
        data = re.sub('\n', '', data)
        data = re.sub('\t', '', data)
        data = json.loads(data)
        self.header = data['header']
        '''Feeding G with the nodes'''
        cardinality = {}
        for key in data['Nodes'].keys():
            for secondkey in data['Nodes'][key].keys():
                for c, n in enumerate(data['Nodes'][key][secondkey]):
                    node = secondkey + "_" + str(c)
                    self.networkx_object.add_node(node, {
                        'cardinality': n[1],
                        'cpd': []
                    })
                    self.dictionary.append((n[0], node))
                    cardinality.update(
                        {node: n[1]}
                    )  #this contains the cardinality of each node with the node name as dictionary entry
        '''Feeding G with the edges'''
        edges = []
        for j, pair in enumerate(data['Edges']):
            for parent in pair.keys():
                for child in data['Edges'][j][parent]:
                    parent_ = self.translation(parent, 0)
                    child_ = self.translation(child, 0)
                    edges.append((parent_, child_))
        np.ravel(edges)
        self.networkx_object.add_edges_from(edges)
        '''Feeding G with the  CPD's as nodes attributes'''
        for j, node in enumerate(data['CPDs']):
            for parent, cpd in node.items():
                node_ = self.translation(parent, 0)
                self.networkx_object.node[node_]['cpd'] = cpd
        '''TO REMOVE LATER'''
        # plt.figure(figsize=(10, 5))
        # pos = nx.circular_layout(G, scale=2)
        # node_labels = nx.get_node_attributes(G, 'cpd')
        # nx.draw(G, pos, node_size=1200, node_color='lightblue',
        #         linewidths=0.25,  font_size=10, font_weight='bold', with_labels=True)
        # plt.show()
        return self.networkx_object, self.dictionary, self.header

    def create_json_file(self, **kwargs):
        """
        EWAMPLE :

        A helping method if the user prefers to create the BN within the code

        :param case_name: the file name without path or extension where the json file will be saved
        :param : **kwargs takes the following variables:
                                                            description = kwargs.get('description', '')
                                                            train_from = kwargs.get('train_from', '')
                                                            cpds = kwargs.get('CPDs', [])
                                                            bens = kwargs.get('BENS',[])
                                                            mems = kwargs.get('MEMS', [])
                                                            lans = kwargs.get('LANS', [])
                                                            motors = kwargs.get('MOTORS', [])
                                                            world = kwargs.get('WORLD', [])
                                                            edges = kwargs.get('Edges', [])
                                                            frozen = kwargs.get('frozen',False)
        .
        .
        .
        :return: void

        :type case_name : string
        :type  :
        .
        .
        .
        :rtype : void
        """
        description = kwargs.get('description', '')
        train_from = kwargs.get('train_from', '')
        cpds = kwargs.get('CPDs', [])
        bens = kwargs.get('BENS', [])
        mems = kwargs.get('MEMS', [])
        lans = kwargs.get('LANS', [])
        motors = kwargs.get('MOTORS', [])
        world = kwargs.get('WORLD', [])
        edges = kwargs.get('Edges', [])
        frozen = kwargs.get('frozen', False)

        #json_tab_file_write = JSONTabIndentFileWriter( Case_name,5a)
        data = self.get_empty_canvas()
        '''       - the 3 next items are for tracking purpose only, not fundamentally necessary'''
        data["header"]['Identification'] = self.file
        data["header"]['Date'] = datetime.datetime.now().strftime("%c")
        data["header"]['Description'] = description
        '''       - the next item gives a file containing possible training data (OPTIONAL)'''
        data["header"]['Train_from'] = train_from
        '''      Frozen tells whether or not the model can be considered as final i.e. is there still "training" needed'''
        data["header"]['Frozen'] = frozen
        '''       - the 5 next lines tells how much nodes  and their names + cardinality the model will start with
                    the names can be any valid python string'''
        bens = [['pooping', 2], ['peeing', 2], ['constipated', 2]]
        mems = [['havenotoiletpaper', 2]]
        lans = [['diarhea', 2], ['happypoop', 2]]
        motors = [['asshole1', 2], ['asshole2', 2]]
        world = [['toilet1', 2], ['toilet2', 2], ['garden1', 2],
                 ['garden2', 2], ['doctor', 2]]
        '''     - the next items describe the edges as a dictionary
                 -> the dictionary entry is always one of the rootnodes, the array following can only contain LANs or LENs'''
        edges = []
        '''       !! in case we start from scratch and we rely on peepo to find the best BN -> leave this array empty'''
        edges.append({'pooping': ['toilet1', 'diarhea', 'happypoop']})
        edges.append({'peeing': ['toilet2', 'garden1', 'garden2']})
        edges.append({'constipated': ['doctor']})
        edges.append({'havenotoiletpaper': ['garden1', 'garden2']})
        edges.append(
            {'diarhea': ['toilet1', 'doctor', 'asshole1', 'asshole2']})
        edges.append(
            {'happypoop': ['garden1', 'garden2', 'asshole1', 'asshole2']})
        '''       - the next items describe the CPD's  as a dictionary
                  -> the dictionary entry is the corresponding node'''
        cpds = []
        cpds.append({'pooping': [0.5, 0.5]})
        cpds.append({'peeing': [0.2, 0.8]})
        cpds.append({'constipated': [0.9, 0.1]})
        cpds.append({'havenotoiletpaper': [0.6, 0.4]})
        cpds.append({'happypoop': [[0.3, 0.8], [0.7, 0.2]]})
        cpds.append({'diarhea': [[0.8, 0.3], [0.2, 0.7]]})
        cpds.append({'toilet1': [[0.3, 0.8, 0.8, 0.7], [0.7, 0.2, 0.2, 0.3]]})
        cpds.append({'asshole1': [[0.3, 0.8, 0.8, 0.7], [0.7, 0.2, 0.2, 0.3]]})
        cpds.append({'asshole2': [[0.3, 0.8, 0.8, 0.7], [0.7, 0.2, 0.2, 0.3]]})
        cpds.append({'toilet2': [[0.5, 0.5], [0.5, 0.5]]})
        cpds.append({'doctor': [[0.3, 0.8, 0.8, 0.7], [0.7, 0.2, 0.2, 0.3]]})
        cpds.append({
            'garden1': [[0.3, 0.8, 0.8, 0.7, 0.8, 0.2, 0.5, 0.5],
                        [0.7, 0.2, 0.2, 0.3, 0.2, 0.8, 0.5, 0.5]]
        })
        cpds.append({
            'garden2': [[0.3, 0.8, 0.8, 0.7, 0.8, 0.2, 0.5, 0.5],
                        [0.7, 0.2, 0.2, 0.3, 0.2, 0.8, 0.5, 0.5]]
        })
        '''       - feeding the data'''
        data["Nodes"]['RONS']['BENS'] = bens
        data["Nodes"]['RONS']['MEMS'] = mems
        data["Nodes"]['LANS']['LANS'] = lans
        data["Nodes"]['LENS']['MOTOR'] = motors
        data["Nodes"]['LENS']['WORLD'] = world
        data["Edges"] = edges
        data["CPDs"] = cpds
        ''' dumping to CASENAME file in jason format'''
        self.save_json(json.dumps(data))

        print("Json file for  - ", self.file, "  - created")

    def create_json_template(self):
        """
        A helping method if the  jason template in the project_repository ditectory has been deleted or corrupted

        :param : void
        :return: void

        :type : void
        :rtype : void
        """
        self.get_json_path(
            "Template"
        )  # creates the right path in which case_name will be saved
        data = self.get_empty_canvas()
        data['header']['Identification'] = self.file
        '''Filling some dummies to facilitate the user'''
        a_node = ['*', 0]
        an_edge = {'*': ['&', '&', '&']}
        a_cpd = {'*': [[0, 0, 0], [0, 0, 0]]}
        nodes = []
        edges = []
        cpds = []
        for i in range(0, 3):
            nodes.append(a_node)
            edges.append(an_edge)
            cpds.append(a_cpd)

        data['Nodes']['RONS']['BENS'] = nodes
        data['Nodes']['RONS']['MEMS'] = nodes
        data['Nodes']['LANS']['LANS'] = nodes
        data['Nodes']['LENS']['MOTOR'] = nodes
        data['Nodes']['LENS']['WORLD'] = nodes
        data['Edges'] = edges
        data['CPDs'] = cpds
        ''' dumping to CASENAME file in jason format'''
        # with open(case_name, 'w') as f:
        #     json.dump(data, f, separators = (",",":"))
        self.save_json(json.dumps(data))
        print("Empty template created")

    def get_empty_canvas(self):
        """
         This method creates a json canvas which will be used for the several json creating method

         :param : void
         :return: a dictionary with the structure of the json file
         :type : non
         :rtype : dictionary
         """

        data = {
            'header': {
                'Identification': '',
                'Date': '',
                'Description': '',
                'Frozen': '',
                'Train_from': ''
            },
            'Nodes': {},
            'Edges': [],
            'CPDs': []
        }
        '''       - the 5 next lines tells how much nodes  and their names the model will start with
                    the names can be any valid python string'''
        bens = []
        mems = []
        lans = []
        motors = []
        world = []
        '''     - the next items describe the edges as a dictionary
                 -> the dictionary entry is always one of the rootnodes, the array following can only contain LANs or LENs

                 !! in case we start from scratch and we rely on peepo to find the best BN -> leave this array empty'''
        edges = []
        '''       - the next items describe the CPD's  as a dictionary
                  -> the dictionary entry is the corresponding node'''
        cpds = []
        '''       - feeding the data'''
        data['Nodes'] = {
            'RONS': {
                'BENS': bens,
                'MEMS': mems
            },
            'LANS': {
                'LANS': lans
            },
            'LENS': {
                'MOTOR': motors,
                'WORLD': world
            }
        }
        data['Edges'] = edges
        data['CPDs'] = cpds
        return data
Exemple #14
0
# -*- coding: utf-8 -*-
"""
Created on Wed Jan 13 20:42:38 2021

@author: zhang
"""

from pgmpy.models import BayesianModel
from pgmpy.factors.discrete import TabularCPD
from pgmpy.inference import VariableElimination

bayesNet = BayesianModel()
bayesNet.add_node("S1")
bayesNet.add_node("S2")
bayesNet.add_node("S2")
bayesNet.add_node("S")

bayesNet.add_edge("S1", "S")
bayesNet.add_edge("S2", "S")
bayesNet.add_edge("S3", "S")

cpd_household = TabularCPD('S1', 3, values=[[.13], [.32], [.55]])
cpd_hdbcarp = TabularCPD('S2', 3, values=[[.25], [.28], [.46]])
cpd_publicarp = TabularCPD('S3', 3, values=[[.15], [.38], [.47]])

cpd_society = TabularCPD('S',
                         3,
                         values=[[
                             1, 0.99, 0.95, 0.8, 0.54, 0.56, 0.7, 0.6, 0.52,
                             0.7, 0.45, 0.1, 0.1, 0.1, 0.12, 0.19, 0.12, 0.18,
                             0.4, 0.22, 0.12, 0.1, 0.02, 0.02, 0.03, 0.01, 0
# Add all the CPDs to the network
# (model is the network object which has references/pointers to all the CPDs, nodes, etc)
model.add_cpds(cpd_d, cpd_i, cpd_g, cpd_l)
# Check model is done to verify that the network is consistent (i.e. CPD values sum to 1 etc.)
model.check_model()

# Perform some inference queries using Variable Elimination (this is an exact inference algorithm, we will need
# to investigate whether an approximate inference algorithm is possible. I haven't found one yet in the library)
infer = VariableElimination(model)
print(infer.query(['G'])['G'])
"""
FROM HERE START CHANGING THE NETWORK 
WE'RE ADDING ONE NODE S WITH AN EDGE COMING FROM I
"""

model.add_node('S')
model.add_edge('I', 'S')

cpd_s = TabularCPD(variable='S',
                   variable_card=2,
                   values=[[0.95, 0.2], [0.05, 0.8]],
                   evidence=['I'],
                   evidence_card=[2])

model.add_cpds(cpd_s)
model.check_model()

infer = VariableElimination(model)
print("========== NEW INFERENCE ============")
print(infer.query(['G'])['G'])
print(infer.query(['S'])['S'])
Exemple #16
0
plt.title('ROC curve')
plt.legend(loc="lower right")

###############################################
# Incorporate uncertainty to random variables #
###############################################

# convert to Markov network (undirected graph) #
model = model.to_markov_model()

# can not be a factor graph since not all random variables are connected to factors #
# model = model.to_factor_graph()
# print(model.check_model())

# add the new received variable and connect #
model.add_node('doors_received')
model.add_node('persons_received')
model.add_node('lug_boot_received')
model.add_node('maint_received')
model.add_node('safety_received')
model.add_node('buying_received')
model.add_edges_from([('persons', 'persons_received'),
                      ('doors', 'doors_received'),
                      ('buying', 'buying_received'),
                      ('safety', 'safety_received'),
                      ('maint', 'maint_received'),
                      ('lug_boot', 'lug_boot_received')])

# binary symmetric channel noise #
n = 4
cpd1 = []
class BNPlayer2(Player):
    def __init__(self, character, start_location, players_n):
        super().__init__(character, start_location)
        self.model = None
        self.my_index = CHARACTERS.index(character)  # I'm player number -
        #  dictionaries name: cpd
        self.weapons_cpds = dict()
        self.room_cpds = dict()
        self.character_cpds = dict()
        # accusation material
        self.murder_char = None
        self.murder_weapon = None
        self.murder_room = None

        self.murder_card_ind = players_n  # is the number of players
        self.card_vals_range = self.murder_card_ind + 1  # The last is Murder-card

    def update_on_other_player_suggestion(self, suggestion, was_showed,
                                          responders):
        if not self.model:
            self.create_model()
        parents = [suggestion[0].name, suggestion[1].name, suggestion[2].name]
        # For players that didn't answer update that they answered False (0) on the triplet
        players_didnt_answer = responders[:-1]
        for p in players_didnt_answer:
            name, cpd = self.three_cards_q(parents[0], parents[1], parents[2],
                                           CHARACTERS.index(p))
            self.update_p_of_parents_given_child(parents, name, 0)
            self.model.remove_node(name)
        if was_showed:
            # For player that showed card update that one of them may be his
            player_answered = responders[-1]
            name, cpd = self.three_cards_q(parents[0], parents[1], parents[2],
                                           CHARACTERS.index(player_answered))
            self.update_p_of_parents_given_child(parents, name, 1)
            self.model.remove_node(name)

    def see_card(self, responders, card=None):
        # If card wasn't shown - it's the result
        if not card:
            self.murder_char, self.murder_weapon, self.murder_room = self._last_suggestion
            return

        parents = [
            self._last_suggestion[0].name, self._last_suggestion[1].name,
            self._last_suggestion[2].name
        ]
        # For players that didn't answer update that they answered False (0) on the triplet
        players_didnt_answer = responders[:-1]
        for p in players_didnt_answer:
            name, cpd = self.three_cards_q(parents[0], parents[1], parents[2],
                                           CHARACTERS.index(p))
            self.update_p_of_parents_given_child(parents, name, 0)
            self.model.remove_node(name)
        # For player that showed card update player-exactly-this-card
        player_answered = responders[-1]
        name = card.name + "P" + str(CHARACTERS.index(player_answered))
        self.update_p_of_parents_given_child([card], name, 1)

    def make_move_suggestion(self, possible_locations):
        if not self.model:
            self.create_model()
        # weapon is assumed murder weapon, otherwise - high % one
        weapon = self.murder_weapon if self.murder_weapon else Weapon[
            self.most_probable_murder_card(self.weapons_cpds)[0]]
        # character is assumed culprit, otherwise - high % one
        character = self.murder_char if self.murder_char else Character[
            self.most_probable_murder_card(self.character_cpds)[0]]
        # weapon is assumed murder weapon, otherwise - None if all are unreachable and room.name if reachable
        if self.murder_room:
            room = self.murder_room
            if LOCATIONS_OF_ROOMS[room] in possible_locations:
                self._last_suggestion = (character, weapon, room)
                return LOCATIONS_OF_ROOMS[room], self._last_suggestion
        probable_rooms = self.most_probable_murder_card(self.room_cpds)
        room = None
        for p_room in probable_rooms:
            if LOCATIONS_OF_ROOMS[Room[p_room]] in possible_locations:
                room = Room[p_room]
                break
        if room is None:
            # all probable rooms are unreachable, move towards highest P room
            self._last_suggestion = None
            return find_location_closest_to_m_room(possible_locations,
                                                   probable_rooms[0]), None
        self._last_suggestion = (character, weapon, room)
        return LOCATIONS_OF_ROOMS[room], self._last_suggestion

    def most_probable_murder_card(self, cpds):
        """
        Goes through all cards, checks the probability of it being the secret murder card. Sorts from higher to lower
        probability.
        :param cpds: Conditional Probability Distribution tables (and their names) to get probability from.
        :return: sorted list of probable murder cards (excludes impossibles (P = 0)).
        """
        card_prob_dict = dict()
        for name in cpds:
            card_prob_dict[name] = cpds[name].values[self.murder_card_ind]
        card_prob_dict = {
            k: v
            for k, v in sorted(
                card_prob_dict.items(), key=lambda item: item[1], reverse=True)
        }
        # use this to print current probabilities distribution
        # print(card_prob_dict)
        ordered_l = [v for v in card_prob_dict
                     if card_prob_dict[v] != 0]  # what was returned before

        if card_prob_dict[ordered_l[0]] >= 0.97 or len(
                ordered_l) == 1:  # probability for accusation
            if ordered_l[0] in Room.__members__:
                self.murder_room = Room[ordered_l[0]]
            elif ordered_l[0] in Character.__members__:
                self.murder_char = Character[ordered_l[0]]
            else:
                self.murder_weapon = Weapon[ordered_l[0]]
        return ordered_l

    def make_accusation(self):
        if self.murder_char and self.murder_weapon and self.murder_room:
            return self.murder_char, self.murder_weapon, self.murder_room
        return None

    def create_model(self):
        """
        Create Dynamic Bayesian Model of the game (updated and changed during the gamerun)
        """
        self.model = BayesianModel()
        # Create weapons
        self.model_group(util.WEAPONS, self.weapons_cpds)
        # Create rooms
        self.model_group(util.ROOMS, self.room_cpds)
        # Create chars
        self.model_group(util.CHARACTERS, self.character_cpds)
        # Answer one card one player
        self.exact_card_ans_by_player()

    def exact_card_ans_by_player(self):
        """
        Tables for answers to our question. This update is for a situation where it's known exactly which card was
        revealed by which player.
        """
        for j in range(
                self.murder_card_ind):  # murder-card can't answer questions
            for group in [
                    self.character_cpds, self.weapons_cpds, self.room_cpds
            ]:
                for card in group:
                    name = card + "P" + str(j)
                    self.model.add_edge(card, name)
                    has_card_true = []
                    for value in range(self.card_vals_range):
                        has_card_true.append(1 if value == j else 0)
                    has_card_false = [1 - v for v in has_card_true]
                    tbl = [has_card_false, has_card_true]
                    cpd = TabularCPD(name,
                                     2,
                                     tbl,
                                     evidence=[card],
                                     evidence_card=[self.card_vals_range])
                    self.model.add_cpds(cpd)

    def three_cards_q(self, character, weapon, room, player_ind):
        """
        Adds CPDs to our model for a triplet of Char-Weapon-Room that is either answered or not by given player.
        Probability is True if at least one belongs to the player and False otherwise.
        :param character: Character card name
        :param weapon: Weapon card name
        :param room: Room card name
        :param player_ind: index of current player
        :return: name of the created node and added CPD
        """
        name = character + "_" + weapon + "_" + room + "P" + str(player_ind)
        self.model.add_edge(character, name)
        self.model.add_edge(weapon, name)
        self.model.add_edge(room, name)
        balanced_true = []
        for comb in itertools.product(range(self.card_vals_range), repeat=3):
            if any(comb[i] == player_ind for i in range(len(comb))):
                balanced_true.append(1)
            else:
                balanced_true.append(0)
        balanced_false = [1 - v for v in balanced_true]
        tbl = [balanced_false, balanced_true]
        cpd = TabularCPD(name,
                         2,
                         tbl,
                         evidence=[character, weapon, room],
                         evidence_card=[self.card_vals_range] * 3)
        self.model.add_cpds(cpd)
        return name, cpd

    def model_group(self, cards, cpd_dic):
        """
        Creates models for a given group of cards. Variable is the name of the card, values are player indexes and one
        more out of range, that is murder-card.
        :param cards: Cards of the given group (e.x. weapons cards)
        :param cpd_dic: dictionary to save the resulting tables
        """
        for card in cards:
            if card in self._cards:
                tbl = [[1] if i == self.my_index else [0]
                       for i in range(self.card_vals_range)]
            else:
                tbl = [[1 / (self.card_vals_range - 1)]
                       if i != self.my_index else [0]
                       for i in range(self.card_vals_range)]
            w = TabularCPD(card.name, self.card_vals_range, tbl)
            cpd_dic[card.name] = w
            self.model.add_node(card.name)
            self.model.add_cpds(w)

    def update_p_of_parents_given_child(self, parents, card_type, value):
        """
        Update probabilities of parents considering that card_type has given value
        :param parents:
        :param card_type:
        :param value:
        :return:
        """
        #  balance variables
        var_elim = VariableElimination(self.model)
        for v in parents:
            if type(v) != str:
                v = v.name
            new_vals = var_elim.query(variables=[v],
                                      evidence={card_type: value},
                                      show_progress=False)
            original_vals = self.model.get_cpds(v)
            original_vals.values = new_vals.values
class TestBayesianModelCPD(unittest.TestCase):
    def setUp(self):
        self.G = BayesianModel([('d', 'g'), ('i', 'g'), ('g', 'l'),
                                ('i', 's')])

    def test_active_trail_nodes(self):
        self.assertEqual(sorted(self.G.active_trail_nodes('d')['d']),
                         ['d', 'g', 'l'])
        self.assertEqual(sorted(self.G.active_trail_nodes('i')['i']),
                         ['g', 'i', 'l', 's'])
        self.assertEqual(sorted(self.G.active_trail_nodes(['d', 'i'])['d']),
                         ['d', 'g', 'l'])

    def test_active_trail_nodes_args(self):
        self.assertEqual(
            sorted(self.G.active_trail_nodes(['d', 'l'], observed='g')['d']),
            ['d', 'i', 's'])
        self.assertEqual(
            sorted(self.G.active_trail_nodes(['d', 'l'], observed='g')['l']),
            ['l'])
        self.assertEqual(
            sorted(self.G.active_trail_nodes('s', observed=['i', 'l'])['s']),
            ['s'])
        self.assertEqual(
            sorted(self.G.active_trail_nodes('s', observed=['d', 'l'])['s']),
            ['g', 'i', 's'])

    def test_is_active_trail_triplets(self):
        self.assertTrue(self.G.is_active_trail('d', 'l'))
        self.assertTrue(self.G.is_active_trail('g', 's'))
        self.assertFalse(self.G.is_active_trail('d', 'i'))
        self.assertTrue(self.G.is_active_trail('d', 'i', observed='g'))
        self.assertFalse(self.G.is_active_trail('d', 'l', observed='g'))
        self.assertFalse(self.G.is_active_trail('i', 'l', observed='g'))
        self.assertTrue(self.G.is_active_trail('d', 'i', observed='l'))
        self.assertFalse(self.G.is_active_trail('g', 's', observed='i'))

    def test_is_active_trail(self):
        self.assertFalse(self.G.is_active_trail('d', 's'))
        self.assertTrue(self.G.is_active_trail('s', 'l'))
        self.assertTrue(self.G.is_active_trail('d', 's', observed='g'))
        self.assertFalse(self.G.is_active_trail('s', 'l', observed='g'))

    def test_is_active_trail_args(self):
        self.assertFalse(self.G.is_active_trail('s', 'l', 'i'))
        self.assertFalse(self.G.is_active_trail('s', 'l', 'g'))
        self.assertTrue(self.G.is_active_trail('d', 's', 'l'))
        self.assertFalse(self.G.is_active_trail('d', 's', ['i', 'l']))

    def test_get_cpds(self):
        cpd_d = TabularCPD('d', 2, values=np.random.rand(2, 1))
        cpd_i = TabularCPD('i', 2, values=np.random.rand(2, 1))
        cpd_g = TabularCPD('g',
                           2,
                           values=np.random.rand(2, 4),
                           evidence=['d', 'i'],
                           evidence_card=[2, 2])
        cpd_l = TabularCPD('l',
                           2,
                           values=np.random.rand(2, 2),
                           evidence=['g'],
                           evidence_card=[2])
        cpd_s = TabularCPD('s',
                           2,
                           values=np.random.rand(2, 2),
                           evidence=['i'],
                           evidence_card=[2])
        self.G.add_cpds(cpd_d, cpd_i, cpd_g, cpd_l, cpd_s)

        self.assertEqual(self.G.get_cpds('d').variable, 'd')

    def test_get_cpds1(self):
        self.model = BayesianModel([('A', 'AB')])
        cpd_a = TabularCPD('A', 2, values=np.random.rand(2, 1))
        cpd_ab = TabularCPD('AB',
                            2,
                            values=np.random.rand(2, 2),
                            evidence=['A'],
                            evidence_card=[2])

        self.model.add_cpds(cpd_a, cpd_ab)
        self.assertEqual(self.model.get_cpds('A').variable, 'A')
        self.assertEqual(self.model.get_cpds('AB').variable, 'AB')
        self.assertRaises(ValueError, self.model.get_cpds, 'B')

        self.model.add_node('B')
        self.assertIsNone(self.model.get_cpds('B'))

    def test_add_single_cpd(self):
        cpd_s = TabularCPD('s', 2, np.random.rand(2, 2), ['i'], [2])
        self.G.add_cpds(cpd_s)
        self.assertListEqual(self.G.get_cpds(), [cpd_s])

    def test_add_multiple_cpds(self):
        cpd_d = TabularCPD('d', 2, values=np.random.rand(2, 1))
        cpd_i = TabularCPD('i', 2, values=np.random.rand(2, 1))
        cpd_g = TabularCPD('g',
                           2,
                           values=np.random.rand(2, 4),
                           evidence=['d', 'i'],
                           evidence_card=[2, 2])
        cpd_l = TabularCPD('l',
                           2,
                           values=np.random.rand(2, 2),
                           evidence=['g'],
                           evidence_card=[2])
        cpd_s = TabularCPD('s',
                           2,
                           values=np.random.rand(2, 2),
                           evidence=['i'],
                           evidence_card=[2])

        self.G.add_cpds(cpd_d, cpd_i, cpd_g, cpd_l, cpd_s)
        self.assertEqual(self.G.get_cpds('d'), cpd_d)
        self.assertEqual(self.G.get_cpds('i'), cpd_i)
        self.assertEqual(self.G.get_cpds('g'), cpd_g)
        self.assertEqual(self.G.get_cpds('l'), cpd_l)
        self.assertEqual(self.G.get_cpds('s'), cpd_s)

    def test_check_model(self):
        cpd_g = TabularCPD('g',
                           2,
                           values=np.array([[0.2, 0.3, 0.4, 0.6],
                                            [0.8, 0.7, 0.6, 0.4]]),
                           evidence=['d', 'i'],
                           evidence_card=[2, 2])

        cpd_s = TabularCPD('s',
                           2,
                           values=np.array([[0.2, 0.3], [0.8, 0.7]]),
                           evidence=['i'],
                           evidence_card=[2])

        cpd_l = TabularCPD('l',
                           2,
                           values=np.array([[0.2, 0.3], [0.8, 0.7]]),
                           evidence=['g'],
                           evidence_card=[2])

        self.G.add_cpds(cpd_g, cpd_s, cpd_l)
        self.assertRaises(ValueError, self.G.check_model)

        cpd_d = TabularCPD('d', 2, values=[[0.8, 0.2]])
        cpd_i = TabularCPD('i', 2, values=[[0.7, 0.3]])
        self.G.add_cpds(cpd_d, cpd_i)

        self.assertTrue(self.G.check_model())

    def test_check_model1(self):
        cpd_g = TabularCPD('g',
                           2,
                           values=np.array([[0.2, 0.3], [0.8, 0.7]]),
                           evidence=['i'],
                           evidence_card=[2])
        self.G.add_cpds(cpd_g)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_g)

        cpd_g = TabularCPD('g',
                           2,
                           values=np.array([[0.2, 0.3, 0.4, 0.6],
                                            [0.8, 0.7, 0.6, 0.4]]),
                           evidence=['d', 's'],
                           evidence_card=[2, 2])
        self.G.add_cpds(cpd_g)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_g)

        cpd_g = TabularCPD('g',
                           2,
                           values=np.array([[0.2, 0.3], [0.8, 0.7]]),
                           evidence=['l'],
                           evidence_card=[2])
        self.G.add_cpds(cpd_g)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_g)

        cpd_l = TabularCPD('l',
                           2,
                           values=np.array([[0.2, 0.3], [0.8, 0.7]]),
                           evidence=['d'],
                           evidence_card=[2])
        self.G.add_cpds(cpd_l)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_l)

        cpd_l = TabularCPD('l',
                           2,
                           values=np.array([[0.2, 0.3, 0.4, 0.6],
                                            [0.8, 0.7, 0.6, 0.4]]),
                           evidence=['d', 'i'],
                           evidence_card=[2, 2])
        self.G.add_cpds(cpd_l)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_l)

        cpd_l = TabularCPD('l',
                           2,
                           values=np.array(
                               [[0.2, 0.3, 0.4, 0.6, 0.2, 0.3, 0.4, 0.6],
                                [0.8, 0.7, 0.6, 0.4, 0.8, 0.7, 0.6, 0.4]]),
                           evidence=['g', 'd', 'i'],
                           evidence_card=[2, 2, 2])
        self.G.add_cpds(cpd_l)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_l)

    def test_check_model2(self):
        cpd_s = TabularCPD('s',
                           2,
                           values=np.array([[0.5, 0.3], [0.8, 0.7]]),
                           evidence=['i'],
                           evidence_card=[2])
        self.G.add_cpds(cpd_s)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_s)

        cpd_g = TabularCPD('g',
                           2,
                           values=np.array([[0.2, 0.3, 0.4, 0.6],
                                            [0.3, 0.7, 0.6, 0.4]]),
                           evidence=['d', 'i'],
                           evidence_card=[2, 2])
        self.G.add_cpds(cpd_g)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_g)

        cpd_l = TabularCPD('l',
                           2,
                           values=np.array([[0.2, 0.3], [0.1, 0.7]]),
                           evidence=['g'],
                           evidence_card=[2])
        self.G.add_cpds(cpd_l)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_l)

    def tearDown(self):
        del self.G
def main():

    andPGM = PGM_t()
    print('loading features..')
    train_set, test_set = andPGM.load_features()
    print('loading features.. Done')
    # Bayesian network of 19 nodes, 9*2 variables of network given
    # Initial incomplete Bayesian model connected manually based on intuition
    print('Generating model.. ')
    initialModel = BayesianModel({})
    initialModel.add_nodes_from(andPGM.img_features.columns[1:10].tolist())
    initialModel.add_edges_from([('f6_a' , 'f2_a'),\
                             ('f3_a' , 'f4_a') ,\
                             ('f5_a' , 'f9_a') ,\
                             ('f4_a' , 'f7_a') ])

    # Use hill climb search algorithm to find network structure of initial 9 nodes
    hc = HillClimbSearch(data=andPGM.img_features.iloc[0:,1:10], \
                         scoring_method=BdeuScore(andPGM.img_features.iloc[0:,1:10], \
                                                  equivalent_sample_size=0.1*len(andPGM.img_features)), \
                         state_names = andPGM.states_9)
    # Get best estimated structure
    best_model = hc.estimate(start=initialModel)
    # Edges in the acquired graph
    print('model of 9 var: ', best_model.edges())

    # Create a Clone of generated Bayesian network structure
    clone_model = BayesianModel({})
    for edge in best_model.edges():
        new_edge = [edge[0][:-1] + 'b', edge[1][:-1] + 'b']
        clone_model.add_edges_from([new_edge])

    # Join together the Original and clone network through node 'same'
    multinetModel = BayesianModel({})
    multinetModel.add_edges_from(best_model.edges() + clone_model.edges())
    multinetModel.add_node('same')
    multinetModel.add_edge('f5_a', 'same')
    multinetModel.add_edge('f9_a', 'same')
    multinetModel.add_edge('f5_b', 'same')
    multinetModel.add_edge('f9_b', 'same')
    print('Generating model.. Done')
    # Edges in the final structure
    print('Final model: ', multinetModel.edges())

    print('Fit data into model..')
    # fit the data to model to generate CPDs using maximum likelyhood estimation
    multinetModel.fit(data=train_set, state_names=andPGM.states_all)
    print('Fit data into model.. Done')
    print('CPDs generated: ')
    cpds = multinetModel.get_cpds()
    for cpd in cpds:
        print(cpd)
    # Inference using Variable Elimination
    print('Start inference..')
    inference = VariableElimination(multinetModel)
    train_set_same = train_set[train_set['same'] == 0]
    train_set_not_same = train_set[train_set['same'] == 1]

    # Accuracy of positive inferences
    acc_same = andPGM.chk_accuracy(
        train_set_same,
        inference,
        variables=train_set_same.columns[0:9].tolist(),
        evidence=train_set_same.columns[9:19].tolist())
    print('accuracy of positives ', acc_same)

    # Accuracy of negative inferences
    acc_nt_same = andPGM.chk_accuracy(
        train_set_not_same,
        inference,
        variables=train_set_not_same.columns[0:9].tolist(),
        evidence=train_set_not_same.columns[9:19].tolist())
    print('accuracy of negatives', acc_nt_same)
Exemple #20
0
def get_game_network():
    BayesNet = BayesianModel()
    BayesNet.add_node('A')
    BayesNet.add_node('B')
    BayesNet.add_node('C')
    BayesNet.add_node('AvB')
    BayesNet.add_node('BvC')
    BayesNet.add_node('CvA')
    BayesNet.add_edge('A', 'AvB')
    BayesNet.add_edge('B', 'AvB')
    BayesNet.add_edge('B', 'BvC')
    BayesNet.add_edge('C', 'BvC')
    BayesNet.add_edge('C', 'CvA')
    BayesNet.add_edge('A', 'CvA')
    cpd_a = TabularCPD('A', 4, values=[[0.15], [0.45], [0.3], [0.1]])
    cpd_b = TabularCPD('B', 4, values=[[0.15], [0.45], [0.3], [0.1]])
    cpd_c = TabularCPD('C', 4, values=[[0.15], [0.45], [0.3], [0.1]])
    cpd_avb = TabularCPD('AvB',
                         3,
                         values=[[
                             0.10, 0.20, 0.15, 0.05, 0.60, 0.10, 0.20, 0.15,
                             0.75, 0.60, 0.10, 0.20, 0.90, 0.75, 0.60, 0.10
                         ],
                                 [
                                     0.10, 0.60, 0.75, 0.90, 0.20, 0.10, 0.60,
                                     0.75, 0.15, 0.20, 0.10, 0.60, 0.05, 0.15,
                                     0.20, 0.10
                                 ],
                                 [
                                     0.80, 0.20, 0.10, 0.05, 0.20, 0.80, 0.20,
                                     0.10, 0.10, 0.20, 0.80, 0.20, 0.05, 0.10,
                                     0.20, 0.80
                                 ]],
                         evidence=['A', 'B'],
                         evidence_card=[4, 4])
    cpd_bvc = TabularCPD('BvC',
                         3,
                         values=[[
                             0.10, 0.20, 0.15, 0.05, 0.60, 0.10, 0.20, 0.15,
                             0.75, 0.60, 0.10, 0.20, 0.90, 0.75, 0.60, 0.10
                         ],
                                 [
                                     0.10, 0.60, 0.75, 0.90, 0.20, 0.10, 0.60,
                                     0.75, 0.15, 0.20, 0.10, 0.60, 0.05, 0.15,
                                     0.20, 0.10
                                 ],
                                 [
                                     0.80, 0.20, 0.10, 0.05, 0.20, 0.80, 0.20,
                                     0.10, 0.10, 0.20, 0.80, 0.20, 0.05, 0.10,
                                     0.20, 0.80
                                 ]],
                         evidence=['B', 'C'],
                         evidence_card=[4, 4])
    cpd_cva = TabularCPD('CvA',
                         3,
                         values=[[
                             0.10, 0.20, 0.15, 0.05, 0.60, 0.10, 0.20, 0.15,
                             0.75, 0.60, 0.10, 0.20, 0.90, 0.75, 0.60, 0.10
                         ],
                                 [
                                     0.10, 0.60, 0.75, 0.90, 0.20, 0.10, 0.60,
                                     0.75, 0.15, 0.20, 0.10, 0.60, 0.05, 0.15,
                                     0.20, 0.10
                                 ],
                                 [
                                     0.80, 0.20, 0.10, 0.05, 0.20, 0.80, 0.20,
                                     0.10, 0.10, 0.20, 0.80, 0.20, 0.05, 0.10,
                                     0.20, 0.80
                                 ]],
                         evidence=['C', 'A'],
                         evidence_card=[4, 4])
    BayesNet.add_cpds(cpd_a, cpd_b, cpd_c, cpd_avb, cpd_bvc, cpd_cva)
    return BayesNet
class BayesianNetworkTester:
    def __init__(self, filename):
        # property
        self.networks = BayesianModel()
        self.mapper = dict()

        f = open(filename, 'r')
        N = int(f.readline())
        lines = f.readlines()
        for line in lines:
            node, parents, domain, shape, probabilities = self.__extract_model(
                line)

            # Create Mapper
            mapper_node = dict()
            for index, value in enumerate(domain):
                mapper_node[value] = index

            self.mapper[node] = mapper_node

            # Add node
            self.networks.add_node(node)

            # Add edge to modal
            for parent in parents:
                self.networks.add_edge(parent, node)

            # Shape to list
            if isinstance(shape, tuple):
                shape = list(shape)[:-1]
            else:
                shape = []

            reshape = (reduce(lambda r, v: r * v, shape, 1), len(domain))
            probabilities = probabilities.reshape(reshape)
            probabilities = np.transpose(probabilities)

            cpd = TabularCPD(variable=node,
                             variable_card=len(domain),
                             values=probabilities,
                             evidence=parents,
                             evidence_card=shape)

            self.networks.add_cpds(cpd)

        f.close()

    def exact_inference(self, filename):
        result = 0
        f = open(filename, 'r')
        query_variables, evidence_variables = self.__extract_query(
            f.readline())

        eliminate = VariableElimination(self.networks)

        evidence_variables_mapped = dict()
        for variable in evidence_variables:
            evidence_variables_mapped[variable] = self.mapper[variable][
                evidence_variables[variable]]

        query_variables_feature = list(query_variables.keys())

        result = eliminate.query(variables=query_variables_feature,
                                 evidence=evidence_variables_mapped)

        value = result.values
        for feature in result.variables:
            value = value[result.get_state_no(
                feature, self.mapper[feature][query_variables[feature]])]

        f.close()
        return value

    def approx_inference(self, filename):
        result = 0
        f = open(filename, 'r')
        # YOUR CODE HERE

        f.close()
        return result

    def __extract_model(self, line):
        parts = line.split(';')
        node = parts[0]
        if parts[1] == '':
            parents = []
        else:
            parents = parts[1].split(',')
        domain = parts[2].split(',')
        shape = eval(parts[3])
        probabilities = np.array(eval(parts[4]))
        return node, parents, domain, shape, probabilities

    def __extract_query(self, line):
        parts = line.split(';')

        # extract query variables
        query_variables = {}
        for item in parts[0].split(','):
            if item is None or item == '':
                continue
            lst = item.split('=')
            query_variables[lst[0]] = lst[1]

        # extract evidence variables
        evidence_variables = {}
        for item in parts[1].split(','):
            if item is None or item == '':
                continue
            lst = item.split('=')
            evidence_variables[lst[0]] = lst[1]
        return query_variables, evidence_variables
Exemple #22
0
    def __init__(
            self,
            #  dataset,
            table,
            num_samples,
            algorithm="greedy",
            max_parents=-1,
            topological_sampling_order=True,
            use_pgm=True,
            discretize=None,
            discretize_method="equal_size",
            root=None):

        from pomegranate import BayesianNetwork
        self.discretize = discretize
        self.discretize_method = discretize_method
        self.table = copy.deepcopy(table)
        self.dataset = np.stack([
            col.discretize(self.table.data[cname])
            for cname, col in self.table.columns.items()
        ],
                                axis=1)
        self.algorithm = algorithm
        self.topological_sampling_order = topological_sampling_order
        self.num_samples = num_samples
        self.discrete_mapping = self.build_discrete_mapping(
            self.dataset, discretize, discretize_method)
        self.discrete_table = self.apply_discrete_mapping(
            self.dataset, self.discrete_mapping)
        L.info('calling BayesianNetwork.from_samples...')
        t = time.time()
        self.model = BayesianNetwork.from_samples(self.discrete_table,
                                                  algorithm=self.algorithm,
                                                  max_parents=max_parents,
                                                  n_jobs=NUM_THREADS,
                                                  root=root)
        L.info(f'done! took {(time.time() - t)/60:.2f} mins')

        def size(states):
            n = 0
            for state in states:
                if "distribution" in state:
                    dist = state["distribution"]
                else:
                    dist = state
                if dist["name"] == "DiscreteDistribution":
                    for p in dist["parameters"]:
                        n += len(p)
                elif dist["name"] == "ConditionalProbabilityTable":
                    for t in dist["table"]:
                        n += len(t)
                    if "parents" in dist:
                        for parent in dist["parents"]:
                            n += size(dist["parents"])
                else:
                    assert False, dist["name"]
            return n

        self.size = 4 * size(json.loads(self.model.to_json())["states"])
        L.info(f'model size is {self.size/1024/1024:.2f}MB')

        # print('json:\n', self.model.to_json())
        self.json_size = len(self.model.to_json())
        self.use_pgm = use_pgm
        #        print(self.model.to_json())

        if topological_sampling_order:
            self.sampling_order = []
            while len(self.sampling_order) < len(self.model.structure):
                for i, deps in enumerate(self.model.structure):
                    if i in self.sampling_order:
                        continue  # already ordered
                    if all(d in self.sampling_order for d in deps):
                        self.sampling_order.append(i)
                L.debug(f"Building sampling order {self.sampling_order}")
        else:
            self.sampling_order = list(range(len(self.model.structure)))
        L.info(f"Using sampling order {self.sampling_order} {str(self)}")

        if use_pgm:
            from pgmpy.models import BayesianModel
            data = pd.DataFrame(self.discrete_table.astype(np.int64))
            spec = []
            orphans = []
            for i, parents in enumerate(self.model.structure):
                for p in parents:
                    spec.append((p, i))
                if not parents:
                    orphans.append(i)
            L.info(f"Model spec {spec}")
            model = BayesianModel(spec)
            for o in orphans:
                model.add_node(o)
            L.info('calling pgm.BayesianModel.fit...')
            t = time.time()
            model.fit(data)
            L.info(f'done! took {(time.time() - t)/60:.2f} mins')
            self.pgm_model = model
class TestBayesianModelCPD(unittest.TestCase):
    def setUp(self):
        self.G = BayesianModel([("d", "g"), ("i", "g"), ("g", "l"),
                                ("i", "s")])
        self.G2 = DAG([("d", "g"), ("i", "g"), ("g", "l"), ("i", "s")])

    def test_active_trail_nodes(self):
        self.assertEqual(sorted(self.G2.active_trail_nodes("d")["d"]),
                         ["d", "g", "l"])
        self.assertEqual(sorted(self.G2.active_trail_nodes("i")["i"]),
                         ["g", "i", "l", "s"])
        self.assertEqual(sorted(self.G2.active_trail_nodes(["d", "i"])["d"]),
                         ["d", "g", "l"])

    def test_active_trail_nodes_args(self):
        self.assertEqual(
            sorted(self.G2.active_trail_nodes(["d", "l"], observed="g")["d"]),
            ["d", "i", "s"],
        )
        self.assertEqual(
            sorted(self.G2.active_trail_nodes(["d", "l"], observed="g")["l"]),
            ["l"])
        self.assertEqual(
            sorted(self.G2.active_trail_nodes("s", observed=["i", "l"])["s"]),
            ["s"])
        self.assertEqual(
            sorted(self.G2.active_trail_nodes("s", observed=["d", "l"])["s"]),
            ["g", "i", "s"],
        )

    def test_is_active_trail_triplets(self):
        self.assertTrue(self.G.is_active_trail("d", "l"))
        self.assertTrue(self.G.is_active_trail("g", "s"))
        self.assertFalse(self.G.is_active_trail("d", "i"))
        self.assertTrue(self.G.is_active_trail("d", "i", observed="g"))
        self.assertFalse(self.G.is_active_trail("d", "l", observed="g"))
        self.assertFalse(self.G.is_active_trail("i", "l", observed="g"))
        self.assertTrue(self.G.is_active_trail("d", "i", observed="l"))
        self.assertFalse(self.G.is_active_trail("g", "s", observed="i"))

    def test_is_active_trail(self):
        self.assertFalse(self.G.is_active_trail("d", "s"))
        self.assertTrue(self.G.is_active_trail("s", "l"))
        self.assertTrue(self.G.is_active_trail("d", "s", observed="g"))
        self.assertFalse(self.G.is_active_trail("s", "l", observed="g"))

    def test_is_active_trail_args(self):
        self.assertFalse(self.G.is_active_trail("s", "l", "i"))
        self.assertFalse(self.G.is_active_trail("s", "l", "g"))
        self.assertTrue(self.G.is_active_trail("d", "s", "l"))
        self.assertFalse(self.G.is_active_trail("d", "s", ["i", "l"]))

    def test_get_cpds(self):
        cpd_d = TabularCPD("d", 2, values=np.random.rand(2, 1))
        cpd_i = TabularCPD("i", 2, values=np.random.rand(2, 1))
        cpd_g = TabularCPD(
            "g",
            2,
            values=np.random.rand(2, 4),
            evidence=["d", "i"],
            evidence_card=[2, 2],
        )
        cpd_l = TabularCPD("l",
                           2,
                           values=np.random.rand(2, 2),
                           evidence=["g"],
                           evidence_card=[2])
        cpd_s = TabularCPD("s",
                           2,
                           values=np.random.rand(2, 2),
                           evidence=["i"],
                           evidence_card=[2])
        self.G.add_cpds(cpd_d, cpd_i, cpd_g, cpd_l, cpd_s)

        self.assertEqual(self.G.get_cpds("d").variable, "d")

    def test_get_cpds1(self):
        self.model = BayesianModel([("A", "AB")])
        cpd_a = TabularCPD("A", 2, values=np.random.rand(2, 1))
        cpd_ab = TabularCPD("AB",
                            2,
                            values=np.random.rand(2, 2),
                            evidence=["A"],
                            evidence_card=[2])

        self.model.add_cpds(cpd_a, cpd_ab)
        self.assertEqual(self.model.get_cpds("A").variable, "A")
        self.assertEqual(self.model.get_cpds("AB").variable, "AB")
        self.assertRaises(ValueError, self.model.get_cpds, "B")

        self.model.add_node("B")
        self.assertIsNone(self.model.get_cpds("B"))

    def test_add_single_cpd(self):
        cpd_s = TabularCPD("s", 2, np.random.rand(2, 2), ["i"], [2])
        self.G.add_cpds(cpd_s)
        self.assertListEqual(self.G.get_cpds(), [cpd_s])

    def test_add_multiple_cpds(self):
        cpd_d = TabularCPD("d", 2, values=np.random.rand(2, 1))
        cpd_i = TabularCPD("i", 2, values=np.random.rand(2, 1))
        cpd_g = TabularCPD(
            "g",
            2,
            values=np.random.rand(2, 4),
            evidence=["d", "i"],
            evidence_card=[2, 2],
        )
        cpd_l = TabularCPD("l",
                           2,
                           values=np.random.rand(2, 2),
                           evidence=["g"],
                           evidence_card=[2])
        cpd_s = TabularCPD("s",
                           2,
                           values=np.random.rand(2, 2),
                           evidence=["i"],
                           evidence_card=[2])

        self.G.add_cpds(cpd_d, cpd_i, cpd_g, cpd_l, cpd_s)
        self.assertEqual(self.G.get_cpds("d"), cpd_d)
        self.assertEqual(self.G.get_cpds("i"), cpd_i)
        self.assertEqual(self.G.get_cpds("g"), cpd_g)
        self.assertEqual(self.G.get_cpds("l"), cpd_l)
        self.assertEqual(self.G.get_cpds("s"), cpd_s)

    def test_check_model(self):
        cpd_g = TabularCPD(
            "g",
            2,
            values=np.array([[0.2, 0.3, 0.4, 0.6], [0.8, 0.7, 0.6, 0.4]]),
            evidence=["d", "i"],
            evidence_card=[2, 2],
        )

        cpd_s = TabularCPD(
            "s",
            2,
            values=np.array([[0.2, 0.3], [0.8, 0.7]]),
            evidence=["i"],
            evidence_card=[2],
        )

        cpd_l = TabularCPD(
            "l",
            2,
            values=np.array([[0.2, 0.3], [0.8, 0.7]]),
            evidence=["g"],
            evidence_card=[2],
        )

        self.G.add_cpds(cpd_g, cpd_s, cpd_l)
        self.assertRaises(ValueError, self.G.check_model)

        cpd_d = TabularCPD("d", 2, values=[[0.8, 0.2]])
        cpd_i = TabularCPD("i", 2, values=[[0.7, 0.3]])
        self.G.add_cpds(cpd_d, cpd_i)

        self.assertTrue(self.G.check_model())

    def test_check_model1(self):
        cpd_g = TabularCPD(
            "g",
            2,
            values=np.array([[0.2, 0.3], [0.8, 0.7]]),
            evidence=["i"],
            evidence_card=[2],
        )
        self.G.add_cpds(cpd_g)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_g)

        cpd_g = TabularCPD(
            "g",
            2,
            values=np.array([[0.2, 0.3, 0.4, 0.6], [0.8, 0.7, 0.6, 0.4]]),
            evidence=["d", "s"],
            evidence_card=[2, 2],
        )
        self.G.add_cpds(cpd_g)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_g)

        cpd_g = TabularCPD(
            "g",
            2,
            values=np.array([[0.2, 0.3], [0.8, 0.7]]),
            evidence=["l"],
            evidence_card=[2],
        )
        self.G.add_cpds(cpd_g)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_g)

        cpd_l = TabularCPD(
            "l",
            2,
            values=np.array([[0.2, 0.3], [0.8, 0.7]]),
            evidence=["d"],
            evidence_card=[2],
        )
        self.G.add_cpds(cpd_l)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_l)

        cpd_l = TabularCPD(
            "l",
            2,
            values=np.array([[0.2, 0.3, 0.4, 0.6], [0.8, 0.7, 0.6, 0.4]]),
            evidence=["d", "i"],
            evidence_card=[2, 2],
        )
        self.G.add_cpds(cpd_l)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_l)

        cpd_l = TabularCPD(
            "l",
            2,
            values=np.array([
                [0.2, 0.3, 0.4, 0.6, 0.2, 0.3, 0.4, 0.6],
                [0.8, 0.7, 0.6, 0.4, 0.8, 0.7, 0.6, 0.4],
            ]),
            evidence=["g", "d", "i"],
            evidence_card=[2, 2, 2],
        )
        self.G.add_cpds(cpd_l)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_l)

    def test_check_model2(self):
        cpd_s = TabularCPD(
            "s",
            2,
            values=np.array([[0.5, 0.3], [0.8, 0.7]]),
            evidence=["i"],
            evidence_card=[2],
        )
        self.G.add_cpds(cpd_s)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_s)

        cpd_g = TabularCPD(
            "g",
            2,
            values=np.array([[0.2, 0.3, 0.4, 0.6], [0.3, 0.7, 0.6, 0.4]]),
            evidence=["d", "i"],
            evidence_card=[2, 2],
        )
        self.G.add_cpds(cpd_g)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_g)

        cpd_l = TabularCPD(
            "l",
            2,
            values=np.array([[0.2, 0.3], [0.1, 0.7]]),
            evidence=["g"],
            evidence_card=[2],
        )
        self.G.add_cpds(cpd_l)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_l)

    def tearDown(self):
        del self.G
class TestBaseModelCreation(unittest.TestCase):
    def setUp(self):
        self.G = BayesianModel()

    def test_class_init_without_data(self):
        self.assertIsInstance(self.G, nx.DiGraph)

    def test_class_init_with_data_string(self):
        self.g = BayesianModel([("a", "b"), ("b", "c")])
        self.assertListEqual(sorted(self.g.nodes()), ["a", "b", "c"])
        self.assertListEqual(hf.recursive_sorted(self.g.edges()),
                             [["a", "b"], ["b", "c"]])

    def test_class_init_with_data_nonstring(self):
        BayesianModel([(1, 2), (2, 3)])

    def test_add_node_string(self):
        self.G.add_node("a")
        self.assertListEqual(list(self.G.nodes()), ["a"])

    def test_add_node_nonstring(self):
        self.G.add_node(1)

    def test_add_nodes_from_string(self):
        self.G.add_nodes_from(["a", "b", "c", "d"])
        self.assertListEqual(sorted(self.G.nodes()), ["a", "b", "c", "d"])

    def test_add_nodes_from_non_string(self):
        self.G.add_nodes_from([1, 2, 3, 4])

    def test_add_edge_string(self):
        self.G.add_edge("d", "e")
        self.assertListEqual(sorted(self.G.nodes()), ["d", "e"])
        self.assertListEqual(list(self.G.edges()), [("d", "e")])
        self.G.add_nodes_from(["a", "b", "c"])
        self.G.add_edge("a", "b")
        self.assertListEqual(hf.recursive_sorted(self.G.edges()),
                             [["a", "b"], ["d", "e"]])

    def test_add_edge_nonstring(self):
        self.G.add_edge(1, 2)

    def test_add_edge_selfloop(self):
        self.assertRaises(ValueError, self.G.add_edge, "a", "a")

    def test_add_edge_result_cycle(self):
        self.G.add_edges_from([("a", "b"), ("a", "c")])
        self.assertRaises(ValueError, self.G.add_edge, "c", "a")

    def test_add_edges_from_string(self):
        self.G.add_edges_from([("a", "b"), ("b", "c")])
        self.assertListEqual(sorted(self.G.nodes()), ["a", "b", "c"])
        self.assertListEqual(hf.recursive_sorted(self.G.edges()),
                             [["a", "b"], ["b", "c"]])
        self.G.add_nodes_from(["d", "e", "f"])
        self.G.add_edges_from([("d", "e"), ("e", "f")])
        self.assertListEqual(sorted(self.G.nodes()),
                             ["a", "b", "c", "d", "e", "f"])
        self.assertListEqual(
            hf.recursive_sorted(self.G.edges()),
            hf.recursive_sorted([("a", "b"), ("b", "c"), ("d", "e"),
                                 ("e", "f")]),
        )

    def test_add_edges_from_nonstring(self):
        self.G.add_edges_from([(1, 2), (2, 3)])

    def test_add_edges_from_self_loop(self):
        self.assertRaises(ValueError, self.G.add_edges_from, [("a", "a")])

    def test_add_edges_from_result_cycle(self):
        self.assertRaises(ValueError, self.G.add_edges_from, [("a", "b"),
                                                              ("b", "c"),
                                                              ("c", "a")])

    def test_update_node_parents_bm_constructor(self):
        self.g = BayesianModel([("a", "b"), ("b", "c")])
        self.assertListEqual(list(self.g.predecessors("a")), [])
        self.assertListEqual(list(self.g.predecessors("b")), ["a"])
        self.assertListEqual(list(self.g.predecessors("c")), ["b"])

    def test_update_node_parents(self):
        self.G.add_nodes_from(["a", "b", "c"])
        self.G.add_edges_from([("a", "b"), ("b", "c")])
        self.assertListEqual(list(self.G.predecessors("a")), [])
        self.assertListEqual(list(self.G.predecessors("b")), ["a"])
        self.assertListEqual(list(self.G.predecessors("c")), ["b"])

    def tearDown(self):
        del self.G
Exemple #25
0
from pgmpy.models import BayesianModel
from pgmpy.factors import TabularCPD
# Creating the above bayesian network
model = BayesianModel()
model.add_nodes_from(['Rain', 'TrafficJam'])
model.add_edge('Rain', 'TrafficJam')
model.add_edge('Accident', 'TrafficJam')
cpd_rain = TabularCPD('Rain', 2, [[0.4], [0.6]])
cpd_accident = TabularCPD('Accident', 2, [[0.2], [0.8]])
cpd_traffic_jam = TabularCPD('TrafficJam', 2,
                             [[0.9, 0.6, 0.7, 0.1],
                              [0.1, 0.4, 0.3, 0.9]],
                             evidence=['Rain', 'Accident'],
                             evidence_card=[2, 2])
model.add_cpds(cpd_rain, cpd_accident, cpd_traffic_jam)
model.add_node('LongQueues')
model.add_edge('TrafficJam', 'LongQueues')
cpd_long_queues = TabularCPD('LongQueues', 2,
                             [[0.9, 0.2],
                              [0.1, 0.8]],
                             evidence=['TrafficJam'],
                             evidence_card=[2])
model.add_cpds(cpd_long_queues)
model.add_nodes_from(['GettingUpLate', 'LateForSchool'])
model.add_edges_from([('GettingUpLate', 'LateForSchool'),
                      ('TrafficJam', 'LateForSchool')])
cpd_getting_up_late = TabularCPD('GettingUpLate', 2,
                                 [[0.6], [0.4]])
cpd_late_for_school = TabularCPD('LateForSchool', 2,
                                 [[0.9, 0.45, 0.8, 0.1],
                                  [0.1, 0.55, 0.2, 0.9]],
class TestBayesianModelCPD(unittest.TestCase):

    def setUp(self):
        self.G = BayesianModel([('d', 'g'), ('i', 'g'), ('g', 'l'),
                                ('i', 's')])

    def test_active_trail_nodes(self):
        self.assertEqual(sorted(self.G.active_trail_nodes('d')['d']), ['d', 'g', 'l'])
        self.assertEqual(sorted(self.G.active_trail_nodes('i')['i']), ['g', 'i', 'l', 's'])
        self.assertEqual(sorted(self.G.active_trail_nodes(['d', 'i'])['d']), ['d', 'g', 'l'])

    def test_active_trail_nodes_args(self):
        self.assertEqual(sorted(self.G.active_trail_nodes(['d', 'l'], observed='g')['d']), ['d', 'i', 's'])
        self.assertEqual(sorted(self.G.active_trail_nodes(['d', 'l'], observed='g')['l']), ['l'])
        self.assertEqual(sorted(self.G.active_trail_nodes('s', observed=['i', 'l'])['s']), ['s'])
        self.assertEqual(sorted(self.G.active_trail_nodes('s', observed=['d', 'l'])['s']), ['g', 'i', 's'])

    def test_is_active_trail_triplets(self):
        self.assertTrue(self.G.is_active_trail('d', 'l'))
        self.assertTrue(self.G.is_active_trail('g', 's'))
        self.assertFalse(self.G.is_active_trail('d', 'i'))
        self.assertTrue(self.G.is_active_trail('d', 'i', observed='g'))
        self.assertFalse(self.G.is_active_trail('d', 'l', observed='g'))
        self.assertFalse(self.G.is_active_trail('i', 'l', observed='g'))
        self.assertTrue(self.G.is_active_trail('d', 'i', observed='l'))
        self.assertFalse(self.G.is_active_trail('g', 's', observed='i'))

    def test_is_active_trail(self):
        self.assertFalse(self.G.is_active_trail('d', 's'))
        self.assertTrue(self.G.is_active_trail('s', 'l'))
        self.assertTrue(self.G.is_active_trail('d', 's', observed='g'))
        self.assertFalse(self.G.is_active_trail('s', 'l', observed='g'))

    def test_is_active_trail_args(self):
        self.assertFalse(self.G.is_active_trail('s', 'l', 'i'))
        self.assertFalse(self.G.is_active_trail('s', 'l', 'g'))
        self.assertTrue(self.G.is_active_trail('d', 's', 'l'))
        self.assertFalse(self.G.is_active_trail('d', 's', ['i', 'l']))

    def test_get_cpds(self):
        cpd_d = TabularCPD('d', 2, values=np.random.rand(2, 1))
        cpd_i = TabularCPD('i', 2, values=np.random.rand(2, 1))
        cpd_g = TabularCPD('g', 2, values=np.random.rand(2, 4),
                           evidence=['d', 'i'], evidence_card=[2, 2])
        cpd_l = TabularCPD('l', 2, values=np.random.rand(2, 2),
                           evidence=['g'], evidence_card=[2])
        cpd_s = TabularCPD('s', 2, values=np.random.rand(2, 2),
                           evidence=['i'], evidence_card=[2])
        self.G.add_cpds(cpd_d, cpd_i, cpd_g, cpd_l, cpd_s)

        self.assertEqual(self.G.get_cpds('d').variable, 'd')

    def test_get_cpds1(self):
        self.model = BayesianModel([('A', 'AB')])
        cpd_a = TabularCPD('A', 2, values=np.random.rand(2, 1))
        cpd_ab = TabularCPD('AB', 2, values=np.random.rand(2, 2),
                            evidence=['A'], evidence_card=[2])

        self.model.add_cpds(cpd_a, cpd_ab)
        self.assertEqual(self.model.get_cpds('A').variable, 'A')
        self.assertEqual(self.model.get_cpds('AB').variable, 'AB')
        self.assertRaises(ValueError, self.model.get_cpds, 'B')

        self.model.add_node('B')
        self.assertIsNone(self.model.get_cpds('B'))

    def test_add_single_cpd(self):
        cpd_s = TabularCPD('s', 2, np.random.rand(2, 2), ['i'], [2])
        self.G.add_cpds(cpd_s)
        self.assertListEqual(self.G.get_cpds(), [cpd_s])

    def test_add_multiple_cpds(self):
        cpd_d = TabularCPD('d', 2, values=np.random.rand(2, 1))
        cpd_i = TabularCPD('i', 2, values=np.random.rand(2, 1))
        cpd_g = TabularCPD('g', 2, values=np.random.rand(2, 4),
                           evidence=['d', 'i'], evidence_card=[2, 2])
        cpd_l = TabularCPD('l', 2, values=np.random.rand(2, 2),
                           evidence=['g'], evidence_card=[2])
        cpd_s = TabularCPD('s', 2, values=np.random.rand(2, 2),
                           evidence=['i'], evidence_card=[2])

        self.G.add_cpds(cpd_d, cpd_i, cpd_g, cpd_l, cpd_s)
        self.assertEqual(self.G.get_cpds('d'), cpd_d)
        self.assertEqual(self.G.get_cpds('i'), cpd_i)
        self.assertEqual(self.G.get_cpds('g'), cpd_g)
        self.assertEqual(self.G.get_cpds('l'), cpd_l)
        self.assertEqual(self.G.get_cpds('s'), cpd_s)

    def test_check_model(self):
        cpd_g = TabularCPD('g', 2, values=np.array([[0.2, 0.3, 0.4, 0.6],
                                                    [0.8, 0.7, 0.6, 0.4]]),
                           evidence=['d', 'i'], evidence_card=[2, 2])

        cpd_s = TabularCPD('s', 2, values=np.array([[0.2, 0.3],
                                                    [0.8, 0.7]]),
                           evidence=['i'], evidence_card=[2])

        cpd_l = TabularCPD('l', 2, values=np.array([[0.2, 0.3],
                                                    [0.8, 0.7]]),
                           evidence=['g'], evidence_card=[2])

        self.G.add_cpds(cpd_g, cpd_s, cpd_l)
        self.assertRaises(ValueError, self.G.check_model)

        cpd_d = TabularCPD('d', 2, values=[[0.8, 0.2]])
        cpd_i = TabularCPD('i', 2, values=[[0.7, 0.3]])
        self.G.add_cpds(cpd_d, cpd_i)

        self.assertTrue(self.G.check_model())

    def test_check_model1(self):
        cpd_g = TabularCPD('g', 2, values=np.array([[0.2, 0.3],
                                                    [0.8, 0.7]]),
                           evidence=['i'], evidence_card=[2])
        self.G.add_cpds(cpd_g)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_g)

        cpd_g = TabularCPD('g', 2, values=np.array([[0.2, 0.3, 0.4, 0.6],
                                                    [0.8, 0.7, 0.6, 0.4]]),
                           evidence=['d', 's'], evidence_card=[2, 2])
        self.G.add_cpds(cpd_g)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_g)

        cpd_g = TabularCPD('g', 2, values=np.array([[0.2, 0.3],
                                                    [0.8, 0.7]]),
                           evidence=['l'], evidence_card=[2])
        self.G.add_cpds(cpd_g)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_g)

        cpd_l = TabularCPD('l', 2, values=np.array([[0.2, 0.3],
                                                    [0.8, 0.7]]),
                           evidence=['d'], evidence_card=[2])
        self.G.add_cpds(cpd_l)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_l)

        cpd_l = TabularCPD('l', 2, values=np.array([[0.2, 0.3, 0.4, 0.6],
                                                    [0.8, 0.7, 0.6, 0.4]]),
                           evidence=['d', 'i'], evidence_card=[2, 2])
        self.G.add_cpds(cpd_l)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_l)

        cpd_l = TabularCPD('l', 2, values=np.array([[0.2, 0.3, 0.4, 0.6, 0.2, 0.3, 0.4, 0.6],
                                                    [0.8, 0.7, 0.6, 0.4, 0.8, 0.7, 0.6, 0.4]]),
                           evidence=['g', 'd', 'i'], evidence_card=[2, 2, 2])
        self.G.add_cpds(cpd_l)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_l)

    def test_check_model2(self):
        cpd_s = TabularCPD('s', 2, values=np.array([[0.5, 0.3],
                                                    [0.8, 0.7]]),
                           evidence=['i'], evidence_card=[2])
        self.G.add_cpds(cpd_s)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_s)

        cpd_g = TabularCPD('g', 2, values=np.array([[0.2, 0.3, 0.4, 0.6],
                                                    [0.3, 0.7, 0.6, 0.4]]),
                           evidence=['d', 'i'], evidence_card=[2, 2])
        self.G.add_cpds(cpd_g)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_g)

        cpd_l = TabularCPD('l', 2, values=np.array([[0.2, 0.3],
                                                    [0.1, 0.7]]),
                           evidence=['g'], evidence_card=[2])
        self.G.add_cpds(cpd_l)
        self.assertRaises(ValueError, self.G.check_model)
        self.G.remove_cpds(cpd_l)

    def tearDown(self):
        del self.G
Exemple #27
0
class RaptorModel:
    RADIUS = 100

    def __init__(self, raptor_actor, Pigeons, wall):
        self.raptor_actor = raptor_actor
        self.Pigeons = Pigeons
        self.wall = wall
        self.n_sectors = raptor_actor.n_sectors
        self.cardinality_vision = self.n_sectors
        self.cardinality_delta_azimuth = 2
        self.cardinality_correction = 3
        self.cardinality_direction = 3
        self.resolution = abs(
            np.angle(self.raptor_actor.sector_L[1]) -
            np.angle(self.raptor_actor.sector_L[0]))
        self.target = self.Pigeons.tensor_of_pigeons[0]
        self.R_previous = 0  #raptor_actor.R_previous
        self.R_now = 0  #raptor_actor.R_now
        self.observations = []
        self.network = BayesianModel()
        self.models = self.create_networks()  #see generative_model.py
        self.correction = 0
        self.direction = 0
        self.compass = 0
        self.cpd_left = CPD.create_fixed_parent((self.n_sectors),
                                                int(self.n_sectors / 2))
        self.cpd_right = CPD.create_fixed_parent((self.n_sectors),
                                                 int(self.n_sectors / 3))
        self.cpd_left_previous = self.cpd_right.copy()
        self.cpd_right_previous = self.cpd_left.copy()
        self.cpd_left_observed = self.cpd_right_previous.copy()
        self.cpd_right_observed = self.cpd_left_previous.copy()
        self.cpd_action = CPD.create_fixed_parent(
            self.cardinality_correction, int(self.cardinality_correction / 2))
        self.cpd_direction = CPD.create_fixed_parent(
            self.cardinality_direction, int(self.cardinality_direction / 2))

    def create_networks(self):
        gamma = 1  # this controls how steep the discrimination will be between the classes (gamma << 1 low discrimination, gamma >> 1 : high discrimination
        sigma = 1  # this controls how steep the squeezing of the action will be
        index_jump = int(
            self.raptor_actor.alfa_increment / self.resolution
        )  #calculates the number of "sector  jumps"  dpeending on the tuple alfa_ainvrement and sector_resolution
        index_jump = 2
        #         print("Index gamma ", index_gamma)
        ParentNodes = []
        ParentNodes.append("MEM_vision_left")
        ParentNodes.append("MEM_vision_right")
        ParentNodes.append("BEN_Correction")
        ParentNodes.append("BEN_Direction")

        #ParentNodes.append("Reward_Predicted")
        count = 0
        while count < len(ParentNodes):
            self.network.add_node(ParentNodes[count])
            count = count + 1

        LeafNodes = []
        LeafNodes.append("LEN_vision_left")
        LeafNodes.append("LEN_vision_right")
        LeafNodes.append("LEN_motor_Correction")
        LeafNodes.append("LEN_motor_Direction")

        count = 0
        while count < len(LeafNodes):
            self.network.add_node(LeafNodes[count])
            count = count + 1
        self.network.add_edge(ParentNodes[0], LeafNodes[0])
        self.network.add_edge(ParentNodes[2], LeafNodes[0])
        self.network.add_edge(ParentNodes[3], LeafNodes[0])
        self.network.add_edge(ParentNodes[1], LeafNodes[1])
        self.network.add_edge(ParentNodes[2], LeafNodes[1])
        self.network.add_edge(ParentNodes[3], LeafNodes[1])
        self.network.add_edge(ParentNodes[2], LeafNodes[2])
        self.network.add_edge(ParentNodes[3], LeafNodes[3])

        CPD_Parents = []
        CPD_Parents.append(
            CPD.parent_cpd(
                ParentNodes[0], self.cardinality_vision,
                int(random.uniform(0, self.cardinality_vision - 0.4)),
                sigma / 2, "fixed"))
        CPD_Parents.append(
            CPD.parent_cpd(
                ParentNodes[1], self.cardinality_vision,
                int(random.uniform(0, self.cardinality_vision - 0.4)),
                sigma / 2, "fixed"))
        CPD_Parents.append(
            CPD.parent_cpd(
                ParentNodes[2], self.cardinality_correction,
                int(random.uniform(0, self.cardinality_correction - 0.4)),
                sigma / 2, "fixed"))
        CPD_Parents.append(
            CPD.parent_cpd(
                ParentNodes[3], self.cardinality_direction,
                int(random.uniform(0, self.cardinality_direction - 0.4)),
                sigma / 2, "fixed"))

        for n in range(0, len(CPD_Parents)):
            self.network.add_cpds(CPD_Parents[n])

        CPD_Leafs = []
        CPD_Leafs.append(
            CPD.leaf_cpd(LeafNodes[0], self.cardinality_vision, [
                self.cardinality_vision, self.cardinality_correction,
                self.cardinality_direction
            ], [ParentNodes[0], ParentNodes[2], ParentNodes[3]], 'left_vision',
                         index_jump))
        CPD_Leafs.append(
            CPD.leaf_cpd(LeafNodes[1], self.cardinality_vision, [
                self.cardinality_vision, self.cardinality_correction,
                self.cardinality_direction
            ], [ParentNodes[1], ParentNodes[2], ParentNodes[3]],
                         'right_vision', index_jump))
        CPD_Leafs.append(
            CPD.leaf_cpd(LeafNodes[2], self.cardinality_correction,
                         [self.cardinality_correction], [ParentNodes[2]],
                         'one_2_one', index_jump))
        CPD_Leafs.append(
            CPD.leaf_cpd(LeafNodes[3], self.cardinality_direction,
                         [self.cardinality_direction], [ParentNodes[3]],
                         'one_2_one', index_jump))
        for n in range(0, len(CPD_Leafs)):
            self.network.add_cpds(CPD_Leafs[n])
        self.network.check_model()
        #draw_network(self.network)
        '''for n in range(0,len(CPD_Latents)):
            print("Latents :")
            print(CPD_Latents[n])'''
        for n in range(0, len(CPD_Leafs)):
            print("Leafs :")
            print(CPD_Leafs[n])
        #wait = input("PRESS ENTER TO CONTINUE.")
        relevant_parent_nodes = [2, 3]

        return {
            'main': GenerativeModel(SensoryInputVirtualPeepo(self),
                                    self.network)
        }

    def process(self):
        self.calculate_environment()
        self.network.get_cpds('BEN_Correction').values = self.cpd_action
        self.network.get_cpds('BEN_Direction').values = self.cpd_direction
        self.network.get_cpds(
            'MEM_vision_left').values = self.cpd_left_previous
        self.network.get_cpds(
            'MEM_vision_right').values = self.cpd_right_previous
        '''print("PARENT CPD's")
        print("******************************************************************************************************************")
        print("Previous left :", self.cpd_left_previous, " Previous right : ", self.cpd_right_previous)
        print("New  correction :", self.action, " New   direction : ", self.direction)'''

        for key in self.models:
            err = self.models[key].process()
            self.correction = self.network.get_cpds('BEN_Correction').values
            self.direction = self.network.get_cpds('BEN_Direction').values
            self.cpd_action = self.correction
            self.cpd_direction = self.direction
            index_direction_angle = np.argmax(self.direction)
            index_correction_angle = np.argmax(self.correction)
            angle_increment = 1j
            if index_direction_angle >= 0:
                if index_correction_angle == 0:
                    angle_increment = np.exp(-1j *
                                             self.raptor_actor.alfa_increment)
                    print("Turning right")
                if index_correction_angle == 1:
                    angle_increment = np.exp(0 * 1j *
                                             self.raptor_actor.alfa_increment)
                    print("No Turning")
                if index_correction_angle == 2:
                    angle_increment = np.exp(1j *
                                             self.raptor_actor.alfa_increment)
                    print("Turning left")
            if index_direction_angle > 3:
                if index_correction_angle == 2:
                    angle_increment = np.exp(-1j *
                                             self.raptor_actor.alfa_increment)
                    print("Turning right")
                if index_correction_angle == 1:
                    angle_increment = np.exp(0 * 1j *
                                             self.raptor_actor.alfa_increment)
                    print("No Turning")
                if index_correction_angle == 0:
                    angle_increment = np.exp(1j *
                                             self.raptor_actor.alfa_increment)
                    print("Turning left")

            #print("Incrementing angle with ",angle_increment)
            #print("Angle from  " ,self.raptor_actor.angle)
            self.raptor_actor.angle *= angle_increment
            #print ( "to : ", self.raptor_actor.angle)
            #print("Peepo's new moving direction :  ", np.angle(self.raptor_actor.angle)*180/math.pi," degrees")
            self.cpd_left_previous = self.cpd_left_observed
            self.cpd_right_previous = self.cpd_right_observed
            #self.action = CPD.create_fixed_parent(self.cardinality_correction, self.correction)
            #self.direction = CPD.create_fixed_parent(self.cardinality_correction, self.compass)
            '''print("Parent nodes ")
            print(self.network.get_cpds('Delta_alfa_left').values)
            print(self.network.get_cpds('Delta_alfa_right').values)
            print("Leaf nodes ")
            #print(self.network.get_cpds('Correction'))'''
            #print("Inference ----> ",self.correction)

    def calculate_environment(obj):
        pos_target = [obj.target[0], obj.target[1]]
        pos_raptor_left_eye = [
            obj.raptor_actor.left_eye[0], obj.raptor_actor.left_eye[1]
        ]
        pos_raptor_right_eye = [
            obj.raptor_actor.right_eye[0], obj.raptor_actor.right_eye[1]
        ]
        observed_left_angle = (pos_target[0] - pos_raptor_left_eye[0]) + 1j * (
            pos_target[1] - pos_raptor_left_eye[1])
        observed_right_angle = (pos_target[0] -
                                pos_raptor_right_eye[0]) + 1j * (
                                    pos_target[1] - pos_raptor_right_eye[1])
        index_sector_left = RaptorModel.get_sector_index(
            observed_left_angle, obj.raptor_actor.sector_L, 'Left')
        obj.raptor_actor.choosen_sector_L = index_sector_left
        if obj.raptor_actor.choosen_sector_L == len(
                obj.raptor_actor.sector_L) - 2:
            obj.raptor_actor.choosen_sector_L = len(
                obj.raptor_actor.sector_L) - 1
        index_sector_right = RaptorModel.get_sector_index(
            observed_right_angle, obj.raptor_actor.sector_R, 'Right')
        obj.raptor_actor.choosen_sector_R = index_sector_right
        if obj.raptor_actor.choosen_sector_R == 0 * (
                len(obj.raptor_actor.sector_R) - 2):
            obj.raptor_actor.choosen_sector_R = (
                len(obj.raptor_actor.sector_R) - 1)
        obj.cpd_left_observed = CPD.create_fixed_parent(
            obj.cardinality_vision, index_sector_left)
        obj.cpd_right_observed = CPD.create_fixed_parent(
            obj.cardinality_vision, index_sector_right)
        obj.observations.clear()
        obj.observations.append(obj.cpd_left_observed)
        obj.observations.append(obj.cpd_right_observed)
        #print("Observations -------------------", obj.observations)

    def get_sector_index(angle, sector, side):
        index = 0
        aim = angle.real / abs(angle.real)
        if side == 'Left':
            for sec in range(0, len(sector) - 1):
                #print("Angle :" , 180/math.pi*angle, " for sectors ", sec , " to ", sec+1 ," (",180/math.pi*np.angle(sector[sec]),",", 180/math.pi*np.angle(sector[sec+1]),")")
                if (np.angle(angle) >= np.angle(sector[sec])
                        and np.angle(angle) < np.angle(sector[sec + 1])):
                    index = sec
            if (np.angle(angle) >= np.angle(sector[len(sector) - 2])
                    and np.angle(angle) < np.angle(sector[len(sector) - 1])):
                index = len(sector) - 2
        if side == 'Right':
            for sec in range(1, len(sector) - 1):
                #print("Angle :" , 180/math.pi*angle, " for sectors ", sec , " to ", sec+1 ," (",180/math.pi*np.angle(sector[sec]),",", 180/math.pi*np.angle(sector[sec+1]),")")
                if (np.angle(angle) > np.angle(sector[sec])
                        and np.angle(angle) <= np.angle(sector[sec + 1])):
                    index = sec
            if (np.angle(angle) >= np.angle(sector[0])
                    and np.angle(angle) <= np.angle(sector[1])):
                index = len(sector) - 2

        if side == 'Left':
            if aim * angle.real <= aim * sector[
                    0].real and aim * angle.real >= aim * sector[len(sector) -
                                                                 1].real:
                index = int((len(sector) - 2) / 2)
        if side == 'Right':
            if aim * angle.real >= aim * sector[
                    0].real and aim * angle.real <= aim * sector[len(sector) -
                                                                 1].real:
                index = int((len(sector) - 2) / 2)

        #print("Angle :", 180 / math.pi * angle, " for sectors ", len(sector)-2, " to ", len(sector)-2 + 1, " (",  180 / math.pi * sector[len(sector)-2], ",", 180 / math.pi * sector[len(sector)-2+ 1], ")")
        #print("Index for angle ",angle , " and sector : ", sector, " : ", index)
        #print(side , " sector Index for angle ", 180/math.pi*np.angle(angle), " ------> ",  index, "   for sectors angles(", 180/math.pi*np.angle(sector[index]),", ", 180/math.pi*np.angle(sector[index+1]),")")
        return index

    def normalize(s):
        som = 0
        for sec in range(0, len(s)):
            som += s[sec]
        for sec in range(0, len(s)):
            s[sec] /= som
        return s
Exemple #28
0
class Inference(object):
    """
    Base class for all inference algorithms.

    Converts BayesianModel and MarkovModel to a uniform representation so that inference
    algorithms can be applied. Also it checks if all the associated CPDs / Factors are
    consistent with the model.

    Initialize inference for a model.

    Parameters
    ----------
    model: pgmpy.models.BayesianModel or pgmpy.models.MarkovModel or pgmpy.models.NoisyOrModel or
    pgmpy.models.IntervalTemporalBayesianNetwork.py
        model for which to initialize the inference object.

    Examples
    --------
    >>> from pgmpy.inference import Inference
    >>> from pgmpy.models import BayesianModel
    >>> from pgmpy.factors.discrete import TabularCPD
    >>> student = BayesianModel([('diff', 'grade'), ('intel', 'grade')])
    >>> diff_cpd = TabularCPD('diff', 2, [[0.2, 0.8]])
    >>> intel_cpd = TabularCPD('intel', 2, [[0.3, 0.7]])
    >>> grade_cpd = TabularCPD('grade', 3, [[0.1, 0.1, 0.1, 0.1],
    ...                                     [0.1, 0.1, 0.1, 0.1],
    ...                                     [0.8, 0.8, 0.8, 0.8]],
    ...                        evidence=['diff', 'intel'], evidence_card=[2, 2])
    >>> student.add_cpds(diff_cpd, intel_cpd, grade_cpd)
    >>> model = Inference(student)

    >>> from pgmpy.models import MarkovModel
    >>> from pgmpy.factors import DiscreteFactor
    >>> import numpy as np
    >>> student = MarkovModel([('Alice', 'Bob'), ('Bob', 'Charles'),
    ...                        ('Charles', 'Debbie'), ('Debbie', 'Alice')])
    >>> factor_a_b = DiscreteFactor(['Alice', 'Bob'], cardinality=[2, 2], value=np.random.rand(4))
    >>> factor_b_c = DiscreteFactor(['Bob', 'Charles'], cardinality=[2, 2], value=np.random.rand(4))
    >>> factor_c_d = DiscreteFactor(['Charles', 'Debbie'], cardinality=[2, 2], value=np.random.rand(4))
    >>> factor_d_a = DiscreteFactor(['Debbie', 'Alice'], cardinality=[2, 2], value=np.random.rand(4))
    >>> student.add_factors(factor_a_b, factor_b_c, factor_c_d, factor_d_a)
    >>> model = Inference(student)
    """
    @StateNameInit()
    def __init__(self, model):
        self.model = model
        model.check_model()

        if isinstance(model, JunctionTree):
            self.variables = set(chain(*model.nodes()))
        else:
            self.variables = model.nodes()

        self.cardinality = {}
        self.factors = defaultdict(list)

        if isinstance(model, BayesianModel):
            for node in model.nodes():
                cpd = model.get_cpds(node)
                cpd_as_factor = cpd.to_factor()
                self.cardinality[node] = cpd.variable_card

                for var in cpd.variables:
                    self.factors[var].append(cpd_as_factor)

        elif isinstance(model, (MarkovModel, FactorGraph, JunctionTree)):
            self.cardinality = model.get_cardinality()

            for factor in model.get_factors():
                for var in factor.variables:
                    self.factors[var].append(factor)

        elif isinstance(model, DynamicBayesianNetwork):
            self.start_bayesian_model = BayesianModel(model.get_intra_edges(0))
            start_cpds = model.get_cpds(time_slice=0)
            for cpd in start_cpds:
                for variable in cpd.variables:
                    if variable[1] == 0:
                        self.start_bayesian_model.add_node(variable)
            self.start_bayesian_model.add_cpds(*start_cpds)
            cpd_inter = [
                model.get_cpds(node)
                for node in set(model.get_interface_nodes(1))
            ]
            self.interface_nodes = set(model.get_interface_nodes(0))
            self.one_and_half_model = BayesianModel(model.get_inter_edges() +
                                                    model.get_intra_edges(1))
            one_and_half_cpds = model.get_cpds(time_slice=1)
            for cpd in one_and_half_cpds:
                for variable in cpd.variables:
                    if variable[1] == 1:
                        self.one_and_half_model.add_node(variable)
            self.one_and_half_model.add_cpds(*(one_and_half_cpds + cpd_inter))
class TestBaseModelCreation(unittest.TestCase):
    def setUp(self):
        self.G = BayesianModel()

    def test_class_init_without_data(self):
        self.assertIsInstance(self.G, nx.DiGraph)

    def test_class_init_with_data_string(self):
        self.g = BayesianModel([('a', 'b'), ('b', 'c')])
        self.assertListEqual(sorted(self.g.nodes()), ['a', 'b', 'c'])
        self.assertListEqual(hf.recursive_sorted(self.g.edges()),
                             [['a', 'b'], ['b', 'c']])

    def test_class_init_with_data_nonstring(self):
        BayesianModel([(1, 2), (2, 3)])

    def test_add_node_string(self):
        self.G.add_node('a')
        self.assertListEqual(self.G.nodes(), ['a'])

    def test_add_node_nonstring(self):
        self.G.add_node(1)

    def test_add_nodes_from_string(self):
        self.G.add_nodes_from(['a', 'b', 'c', 'd'])
        self.assertListEqual(sorted(self.G.nodes()), ['a', 'b', 'c', 'd'])

    def test_add_nodes_from_non_string(self):
        self.G.add_nodes_from([1, 2, 3, 4])

    def test_add_edge_string(self):
        self.G.add_edge('d', 'e')
        self.assertListEqual(sorted(self.G.nodes()), ['d', 'e'])
        self.assertListEqual(self.G.edges(), [('d', 'e')])
        self.G.add_nodes_from(['a', 'b', 'c'])
        self.G.add_edge('a', 'b')
        self.assertListEqual(hf.recursive_sorted(self.G.edges()),
                             [['a', 'b'], ['d', 'e']])

    def test_add_edge_nonstring(self):
        self.G.add_edge(1, 2)

    def test_add_edge_selfloop(self):
        self.assertRaises(ValueError, self.G.add_edge, 'a', 'a')

    def test_add_edge_result_cycle(self):
        self.G.add_edges_from([('a', 'b'), ('a', 'c')])
        self.assertRaises(ValueError, self.G.add_edge, 'c', 'a')

    def test_add_edges_from_string(self):
        self.G.add_edges_from([('a', 'b'), ('b', 'c')])
        self.assertListEqual(sorted(self.G.nodes()), ['a', 'b', 'c'])
        self.assertListEqual(hf.recursive_sorted(self.G.edges()),
                             [['a', 'b'], ['b', 'c']])
        self.G.add_nodes_from(['d', 'e', 'f'])
        self.G.add_edges_from([('d', 'e'), ('e', 'f')])
        self.assertListEqual(sorted(self.G.nodes()),
                             ['a', 'b', 'c', 'd', 'e', 'f'])
        self.assertListEqual(hf.recursive_sorted(self.G.edges()),
                             hf.recursive_sorted([('a', 'b'), ('b', 'c'),
                                                  ('d', 'e'), ('e', 'f')]))

    def test_add_edges_from_nonstring(self):
        self.G.add_edges_from([(1, 2), (2, 3)])

    def test_add_edges_from_self_loop(self):
        self.assertRaises(ValueError, self.G.add_edges_from,
                          [('a', 'a')])

    def test_add_edges_from_result_cycle(self):
        self.assertRaises(ValueError, self.G.add_edges_from,
                          [('a', 'b'), ('b', 'c'), ('c', 'a')])

    def test_update_node_parents_bm_constructor(self):
        self.g = BayesianModel([('a', 'b'), ('b', 'c')])
        self.assertListEqual(self.g.predecessors('a'), [])
        self.assertListEqual(self.g.predecessors('b'), ['a'])
        self.assertListEqual(self.g.predecessors('c'), ['b'])

    def test_update_node_parents(self):
        self.G.add_nodes_from(['a', 'b', 'c'])
        self.G.add_edges_from([('a', 'b'), ('b', 'c')])
        self.assertListEqual(self.G.predecessors('a'), [])
        self.assertListEqual(self.G.predecessors('b'), ['a'])
        self.assertListEqual(self.G.predecessors('c'), ['b'])

    def tearDown(self):
        del self.G
Exemple #30
0
    """

    np_all = np.loadtxt(open("dishwasher.out", "rb"),
                        delimiter=",",
                        skiprows=0)
    print(np_all.shape)
    print(np_all)
    plt.plot(np_all[:, 266])
    plt.show()

    #np_all = np_all[33:-34,:]
    #print(np_all.shape)
    #"""

    G = BayesianModel()
    G.add_node('time_slot')

    G.add_edge('time_slot', 'device_on')
    G.add_edge('time_slot', 'energy')
    G.add_edge('time_slot', 'duration')
    G.add_edge('device_on', 'energy')
    G.add_edge('device_on', 'duration')

    for i in range(np_all.shape[1]):
        gtz_idxb = np_all[:, i] > 10
        total_energy = np_all[gtz_idxb, i].sum()

        gtz_idx = np.argwhere(np_all[:, i] > 10)
        train_list = []
        if gtz_idx.shape[0] > 0 and total_energy < 60000:
Exemple #31
0
class TestBaseModelCreation(unittest.TestCase):
    def setUp(self):
        self.G = BayesianModel()

    def test_class_init_without_data(self):
        self.assertIsInstance(self.G, nx.DiGraph)

    def test_class_init_with_data_string(self):
        self.g = BayesianModel([('a', 'b'), ('b', 'c')])
        self.assertListEqual(sorted(self.g.nodes()), ['a', 'b', 'c'])
        self.assertListEqual(hf.recursive_sorted(self.g.edges()),
                             [['a', 'b'], ['b', 'c']])

    def test_class_init_with_data_nonstring(self):
        BayesianModel([(1, 2), (2, 3)])

    def test_add_node_string(self):
        self.G.add_node('a')
        self.assertListEqual(self.G.nodes(), ['a'])

    def test_add_node_nonstring(self):
        self.G.add_node(1)

    def test_add_nodes_from_string(self):
        self.G.add_nodes_from(['a', 'b', 'c', 'd'])
        self.assertListEqual(sorted(self.G.nodes()), ['a', 'b', 'c', 'd'])

    def test_add_nodes_from_non_string(self):
        self.G.add_nodes_from([1, 2, 3, 4])

    def test_add_edge_string(self):
        self.G.add_edge('d', 'e')
        self.assertListEqual(sorted(self.G.nodes()), ['d', 'e'])
        self.assertListEqual(self.G.edges(), [('d', 'e')])
        self.G.add_nodes_from(['a', 'b', 'c'])
        self.G.add_edge('a', 'b')
        self.assertListEqual(hf.recursive_sorted(self.G.edges()),
                             [['a', 'b'], ['d', 'e']])

    def test_add_edge_nonstring(self):
        self.G.add_edge(1, 2)

    def test_add_edge_selfloop(self):
        self.assertRaises(ValueError, self.G.add_edge, 'a', 'a')

    def test_add_edge_result_cycle(self):
        self.G.add_edges_from([('a', 'b'), ('a', 'c')])
        self.assertRaises(ValueError, self.G.add_edge, 'c', 'a')

    def test_add_edges_from_string(self):
        self.G.add_edges_from([('a', 'b'), ('b', 'c')])
        self.assertListEqual(sorted(self.G.nodes()), ['a', 'b', 'c'])
        self.assertListEqual(hf.recursive_sorted(self.G.edges()),
                             [['a', 'b'], ['b', 'c']])
        self.G.add_nodes_from(['d', 'e', 'f'])
        self.G.add_edges_from([('d', 'e'), ('e', 'f')])
        self.assertListEqual(sorted(self.G.nodes()),
                             ['a', 'b', 'c', 'd', 'e', 'f'])
        self.assertListEqual(
            hf.recursive_sorted(self.G.edges()),
            hf.recursive_sorted([('a', 'b'), ('b', 'c'), ('d', 'e'),
                                 ('e', 'f')]))

    def test_add_edges_from_nonstring(self):
        self.G.add_edges_from([(1, 2), (2, 3)])

    def test_add_edges_from_self_loop(self):
        self.assertRaises(ValueError, self.G.add_edges_from, [('a', 'a')])

    def test_add_edges_from_result_cycle(self):
        self.assertRaises(ValueError, self.G.add_edges_from, [('a', 'b'),
                                                              ('b', 'c'),
                                                              ('c', 'a')])

    def test_update_node_parents_bm_constructor(self):
        self.g = BayesianModel([('a', 'b'), ('b', 'c')])
        self.assertListEqual(self.g.predecessors('a'), [])
        self.assertListEqual(self.g.predecessors('b'), ['a'])
        self.assertListEqual(self.g.predecessors('c'), ['b'])

    def test_update_node_parents(self):
        self.G.add_nodes_from(['a', 'b', 'c'])
        self.G.add_edges_from([('a', 'b'), ('b', 'c')])
        self.assertListEqual(self.G.predecessors('a'), [])
        self.assertListEqual(self.G.predecessors('b'), ['a'])
        self.assertListEqual(self.G.predecessors('c'), ['b'])

    def tearDown(self):
        del self.G
Exemple #32
0
	                         [[0.9, 0.6, 0.7, 0.1],
	                          [0.1, 0.4, 0.3, 0.9]],
	                          evdience=['rain', 'accident'],
	                          evidence_card=[2, 2])
# associate each CPD to model
model.add_cpds(cpd_rain, cpd_accident, cpd_traffic_jam)
model.get_cpds()
" [<TabularCPD representing P(rain: 2) at fsjidfsjdfaskdf>, "
" [<TabularCPD representing P(accident: 2) at fsxfgsdfgfsjdfaskdf>, "
" [<TabularCPD representing P(traffic_jam: 2 | rain:2, accident:2) at fsjidf234sjdfaskdf>, "



# Adding the remaining variables and their CPDs
# ------------------------------------------------------ ( traffic_jam -> long_queues )
model.add_node('long_queues')
model.add_edge('traffic_jam', 'long_queues')
cpd_long_queues = TabularCPD('long_queues', 2,
	                         [[0.9, 0.2],
	                          [0.1, 0.8]],
	                          evidence=['traffic_jam'],
	                          evidence_card=[2])
model.add_cpds(cpd_long_queues)


# ------------------------------------------------------ ( getting_up_late -> late_for_school )
# ------------------------------------------------------ ( traffic_jam -> late_for_school )
model.add_nodes_from(['getting_up_late',
	                  'late_for_school'])
model.add_edges_from([('getting_up_late', 'late_for_school'),
	                  ('traffic_jam', 'late_for_school')])