def test_get_assertions(self): self.Independencies1 = Independencies(["X", "Y", "Z"]) self.assertEqual(self.Independencies1.independencies, self.Independencies1.get_assertions()) self.Independencies2 = Independencies(["A", "B", "C"], ["D", "E", "F"]) self.assertEqual(self.Independencies2.independencies, self.Independencies2.get_assertions())
def local_independencies(self, variables): """ Returns an instance of Independencies containing the local independencies of each of the variables. Parameters ---------- variables: str or array like variables whose local independencies are to found. Examples -------- >>> from pgmpy.models import NaiveBayes >>> model = NaiveBayes() >>> model.add_edges_from([('a', 'b'), ('a', 'c'), ('a', 'd')]) >>> ind = model.local_independencies('b') >>> ind (b _|_ d, c | a) """ independencies = Independencies() for variable in [variables] if isinstance(variables, str) else variables: if variable != self.parent_node: independencies.add_assertions([ variable, list(set(self.children_nodes) - set(variable)), self.parent_node ]) return independencies
def get_independencies(self, condition=None): """ Returns the independent variables in the joint probability distribution. Returns marginally independent variables if condition=None. Returns conditionally independent variables if condition!=None Parameter --------- condition: array_like Random Variable on which to condition the Joint Probability Distribution. Examples -------- >>> import numpy as np >>> from pgmpy.factors import JointProbabilityDistribution >>> prob = JointProbabilityDistribution(['x1', 'x2', 'x3'], [2, 3, 2], np.ones(12)/12) >>> prob.get_independencies() (x1 _|_ x2) (x1 _|_ x3) (x2 _|_ x3) """ JPD = self.copy() if condition: JPD.conditional_distribution(condition) independencies = Independencies() for variable_pair in itertools.combinations(list(JPD.variables), 2): if (JPD.marginal_distribution( variable_pair, inplace=False) == JPD.marginal_distribution( variable_pair[0], inplace=False) * JPD.marginal_distribution(variable_pair[1], inplace=False)): independencies.add_assertions(variable_pair) return independencies
def test_get_independencies(self): chain = BayesianModel([('X', 'Y'), ('Y', 'Z')]) self.assertEqual(chain.get_independencies(), Independencies(('X', 'Z', 'Y'), ('Z', 'X', 'Y'))) fork = BayesianModel([('Y', 'X'), ('Y', 'Z')]) self.assertEqual(fork.get_independencies(), Independencies(('X', 'Z', 'Y'), ('Z', 'X', 'Y'))) collider = BayesianModel([('X', 'Y'), ('Z', 'Y')]) self.assertEqual(collider.get_independencies(), Independencies(('X', 'Z'), ('Z', 'X')))
def get_independencies(self, condition=None): """ Returns the independent variables in the joint probability distribution. Returns marginally independent variables if condition=None. Returns conditionally independent variables if condition!=None Parameter --------- condition: array_like Random Variable on which to condition the Joint Probability Distribution. Examples -------- >>> from pgmpy.factors import JointProbabilityDistribution >>> prob = JointProbabilityDistribution(['x1', 'x2', 'x3'], [2, 3, 2], np.ones(8)/8) >>> prob.get_independencies() """ if condition: self.conditional_distribution(condition) independencies = Independencies() from itertools import combinations for variable_pair in combinations(list(self.variables), 2): from copy import deepcopy if JointProbabilityDistribution.marginal_distribution(deepcopy(self), variable_pair) == \ JointProbabilityDistribution.marginal_distribution(deepcopy(self), variable_pair[0]) * \ JointProbabilityDistribution.marginal_distribution(deepcopy(self), variable_pair[1]): independencies.add_assertions(variable_pair) return independencies
def get_independencies(self, condition=None): """ Returns the independent variables in the joint probability distribution. Returns marginally independent variables if condition=None. Returns conditionally independent variables if condition!=None Parameter --------- condition: array_like Random Variable on which to condition the Joint Probability Distribution. Examples -------- >>> import numpy as np >>> from pgmpy.factors import JointProbabilityDistribution >>> prob = JointProbabilityDistribution(['x1', 'x2', 'x3'], [2, 3, 2], np.ones(12)/12) >>> prob.get_independencies() (x1 _|_ x2) (x1 _|_ x3) (x2 _|_ x3) """ JPD = self.copy() if condition: JPD.conditional_distribution(condition) independencies = Independencies() for variable_pair in itertools.combinations(list(JPD.variables), 2): if (JPD.marginal_distribution(variable_pair, inplace=False) == JPD.marginal_distribution(variable_pair[0], inplace=False) * JPD.marginal_distribution(variable_pair[1], inplace=False)): independencies.add_assertions(variable_pair) return independencies
def test_get_assertions(self): self.Independencies1 = Independencies(['X', 'Y', 'Z']) self.assertEqual(self.Independencies1.independencies, self.Independencies1.get_assertions()) self.Independencies2 = Independencies(['A', 'B', 'C'], ['D', 'E', 'F']) self.assertEqual(self.Independencies2.independencies, self.Independencies2.get_assertions())
def test_build_skeleton(self): ind = Independencies(['B', 'C'], ['A', ['B', 'C'], 'D']) ind = ind.closure() skel1, sep_sets1 = ConstraintBasedEstimator.build_skeleton("ABCD", ind) self.assertTrue( self._edge_list_equal(skel1.edges(), [('A', 'D'), ('B', 'D'), ('C', 'D')])) sep_sets_ref1 = { frozenset({'A', 'C'}): (), frozenset({'A', 'B'}): (), frozenset({'C', 'B'}): () } self.assertEqual(sep_sets1, sep_sets_ref1) model = BayesianModel([('A', 'C'), ('B', 'C'), ('B', 'D'), ('C', 'E')]) skel2, sep_sets2 = ConstraintBasedEstimator.build_skeleton( model.nodes(), model.get_independencies()) self.assertTrue( self._edge_list_equal(skel2, [('D', 'B'), ('A', 'C'), ('B', 'C'), ('C', 'E')])) sep_sets_ref2 = { frozenset({'D', 'C'}): ('B', ), frozenset({'E', 'B'}): ('C', ), frozenset({'A', 'D'}): (), frozenset({'E', 'D'}): ('C', ), frozenset({'E', 'A'}): ('C', ), frozenset({'A', 'B'}): () } # witnesses/seperators might change on each run, so we cannot compare directly self.assertEqual(sep_sets2.keys(), sep_sets_ref2.keys()) self.assertEqual([len(v) for v in sorted(sep_sets2.values())], [len(v) for v in sorted(sep_sets_ref2.values())])
def test_get_independencies(self): independencies = Independencies(['x1', 'x2'], ['x2', 'x3'], ['x3', 'x1']) independencies1 = Independencies(['x1', 'x2']) self.assertEqual(self.jpd1.get_independencies(), independencies) self.assertEqual(self.jpd2.get_independencies(), independencies1) self.assertEqual(self.jpd1.get_independencies([('x3', 0)]), independencies1) self.assertEqual(self.jpd2.get_independencies([('x3', 0)]), Independencies())
def local_independencies(self, variables): """ Returns an instance of Independencies containing the local independencies of each of the variables. Parameters ---------- variables: str or array like variables whose local independencies are to found. Examples -------- >>> from pgmpy.models import NaiveBayes >>> model = NaiveBayes() >>> model.add_edges_from([('a', 'b'), ('a', 'c'), ('a', 'd')]) >>> ind = model.local_independencies('b') >>> ind (b _|_ d, c | a) """ independencies = Independencies() for variable in [variables] if isinstance(variables, str) else variables: if variable != self.parent_node: independencies.add_assertions([variable, list(set(self.children_nodes) - set(variable)), self.parent_node]) return independencies
def test_local_independencies(self): self.assertEqual(self.G1.local_independencies('a'), Independencies()) self.assertEqual(self.G1.local_independencies('b'), Independencies(['b', ['e', 'c', 'd'], 'a'])) self.assertEqual(self.G1.local_independencies('c'), Independencies(['c', ['e', 'b', 'd'], 'a'])) self.assertEqual(self.G1.local_independencies('d'), Independencies(['d', ['b', 'c', 'e'], 'a']))
def test_local_independencies(self): self.assertListEqual(self.G1.local_independencies('a'), [None]) self.assertListEqual(self.G1.local_independencies('b'), [Independencies(['b', ['e', 'c', 'd'], 'a'])]) self.assertListEqual(self.G1.local_independencies('c'), [Independencies(['c', ['e', 'b', 'd'], 'a'])]) self.assertListEqual(self.G1.local_independencies('d'), [Independencies(['d', ['b', 'c', 'e'], 'a'])])
def test_get_independencies(self): chain = BayesianModel([("X", "Y"), ("Y", "Z")]) self.assertEqual(chain.get_independencies(), Independencies(("X", "Z", "Y"), ("Z", "X", "Y"))) fork = BayesianModel([("Y", "X"), ("Y", "Z")]) self.assertEqual(fork.get_independencies(), Independencies(("X", "Z", "Y"), ("Z", "X", "Y"))) collider = BayesianModel([("X", "Y"), ("Z", "Y")]) self.assertEqual(collider.get_independencies(), Independencies(("X", "Z"), ("Z", "X")))
def setUp(self): self.Independencies = Independencies() self.Independencies3 = Independencies( ["a", ["b", "c", "d"], ["e", "f", "g"]], ["c", ["d", "e", "f"], ["g", "h"]]) self.Independencies4 = Independencies( [["f", "d", "e"], "c", ["h", "g"]], [["b", "c", "d"], "a", ["f", "g", "e"]]) self.Independencies5 = Independencies( ["a", ["b", "c", "d"], ["e", "f", "g"]], ["c", ["d", "e", "f"], "g"])
def setUp(self): self.Independencies = Independencies() self.Independencies3 = Independencies( ['a', ['b', 'c', 'd'], ['e', 'f', 'g']], ['c', ['d', 'e', 'f'], ['g', 'h']]) self.Independencies4 = Independencies( [['f', 'd', 'e'], 'c', ['h', 'g']], [['b', 'c', 'd'], 'a', ['f', 'g', 'e']]) self.Independencies5 = Independencies( ['a', ['b', 'c', 'd'], ['e', 'f', 'g']], ['c', ['d', 'e', 'f'], 'g'])
def local_independencies(self, variables): """ Returns a independencies object containing the local independencies of each of the variables. Parameters ---------- variables: str or array like variables whose local independencies are to found. Examples -------- >>> from pgmpy.models import BayesianModel >>> student = BayesianModel() >>> student.add_edges_from([('diff', 'grade'), ('intel', 'grade'), >>> ('grade', 'letter'), ('intel', 'SAT')]) >>> ind = student.local_independencies('grade') >>> ind.event1 {'grade'} >>> ind.event2 {'SAT'} >>> ind.event3 {'diff', 'intel'} """ def dfs(node): """ Returns the descendents of node. Since there can't be any cycles in the Bayesian Network. This is a very simple dfs which doen't remember which nodes it has visited. """ descendents = [] visit = [node] while visit: n = visit.pop() neighbors = self.neighbors(n) visit.extend(neighbors) descendents.extend(neighbors) return descendents from pgmpy.independencies import Independencies independencies = Independencies() for variable in [variables] if isinstance(variables, str) else variables: independencies.add_assertions([ variable, set(self.nodes()) - set(dfs(variable)) - set(self.get_parents(variable)) - {variable}, set(self.get_parents(variable)) ]) return independencies
def test_local_independencies(self): self.assertEqual(self.G1.local_independencies("a"), Independencies()) self.assertEqual( self.G1.local_independencies("b"), Independencies(["b", ["e", "c", "d"], "a"]), ) self.assertEqual( self.G1.local_independencies("c"), Independencies(["c", ["e", "b", "d"], "a"]), ) self.assertEqual( self.G1.local_independencies("d"), Independencies(["d", ["b", "c", "e"], "a"]), )
def test_estimate_from_independencies(self): ind = Independencies(['B', 'C'], ['A', ['B', 'C'], 'D']) ind = ind.closure() model = ConstraintBasedEstimator.estimate_from_independencies("ABCD", ind) self.assertSetEqual(set(model.edges()), set([('B', 'D'), ('A', 'D'), ('C', 'D')])) model1 = BayesianModel([('A', 'C'), ('B', 'C'), ('B', 'D'), ('C', 'E')]) model2 = ConstraintBasedEstimator.estimate_from_independencies( model1.nodes(), model1.get_independencies()) self.assertTrue(set(model2.edges()) == set(model1.edges()) or set(model2.edges()) == set([('B', 'C'), ('A', 'C'), ('C', 'E'), ('D', 'B')]))
def test_entails(self): ind1 = Independencies([['A', 'B'], ['C', 'D'], 'E']) ind2 = Independencies(['A', 'C', 'E']) self.assertTrue(ind1.entails(ind2)) self.assertFalse(ind2.entails(ind1)) ind3 = Independencies(('W', ['X', 'Y', 'Z'])) self.assertTrue(ind3.entails(ind3.closure())) self.assertTrue(ind3.closure().entails(ind3))
def local_independencies(self, variables): """ Returns a list of independencies objects containing the local independencies of each of the variables. If local independencies does not exist for a variable it gives a None for that variable. Parameters ---------- variables: str or array like variables whose local independencies are to found. Examples -------- >>> from pgmpy.models import NaiveBayes >>> model = NaiveBayes() >>> model.add_edges_from([('a', 'b'), ('a', 'c'), ('a', 'd')]) >>> ind = model.local_independencies('b') >>> ind [(b _|_ d, c | a)] """ independencies = [] for variable in [variables] if isinstance(variables, str) else variables: if variable != self.parent_node: independencies.append( Independencies([ variable, list(set(self.children_nodes) - set(variable)), self.parent_node ])) else: independencies.append(None) return independencies
def local_independencies(self, variables): """ Returns an instance of Independencies containing the local independencies of each of the variables. Parameters ---------- variables: str or array like variables whose local independencies are to be found. Examples -------- >>> from pgmpy.models import BayesianModel >>> student = BayesianModel() >>> student.add_edges_from([('diff', 'grade'), ('intel', 'grade'), >>> ('grade', 'letter'), ('intel', 'SAT')]) >>> ind = student.local_independencies('grade') >>> ind (grade _|_ SAT | diff, intel) """ def dfs(node): """ Returns the descendents of node. Since Bayesian Networks are acyclic, this is a very simple dfs which does not remember which nodes it has visited. """ descendents = [] visit = [node] while visit: n = visit.pop() neighbors = self.neighbors(n) visit.extend(neighbors) descendents.extend(neighbors) return descendents independencies = Independencies() for variable in variables if isinstance(variables, (list, tuple)) else [variables]: non_descendents = set(self.nodes()) - {variable} - set( dfs(variable)) parents = set(self.get_parents(variable)) if non_descendents - parents: independencies.add_assertions( [variable, non_descendents - parents, parents]) return independencies
def local_independencies(self, variables): """ Returns a independencies object containing the local independencies of each of the variables. Parameters ---------- variables: str or array like variables whose local independencies are to found. Examples -------- >>> from pgmpy.models import BayesianModel >>> student = BayesianModel() >>> student.add_edges_from([('diff', 'grade'), ('intel', 'grade'), >>> ('grade', 'letter'), ('intel', 'SAT')]) >>> ind = student.local_independencies('grade') >>> ind.event1 {'grade'} >>> ind.event2 {'SAT'} >>> ind.event3 {'diff', 'intel'} """ def dfs(node): """ Returns the descendents of node. Since there can't be any cycles in the Bayesian Network. This is a very simple dfs which doen't remember which nodes it has visited. """ descendents = [] visit = [node] while visit: n = visit.pop() neighbors = self.neighbors(n) visit.extend(neighbors) descendents.extend(neighbors) return descendents from pgmpy.independencies import Independencies independencies = Independencies() for variable in [variables] if isinstance(variables, str) else variables: independencies.add_assertions([variable, set(self.nodes()) - set(dfs(variable)) - set(self.get_parents(variable)) - {variable}, set(self.get_parents(variable))]) return independencies
def get_independencies(self, latex=False): """ Computes independencies in the Bayesian Network, by checking d-seperation. Parameters ---------- latex: boolean If latex=True then latex string of the independence assertion would be created. Examples -------- >>> from pgmpy.models import BayesianModel >>> chain = BayesianModel([('X', 'Y'), ('Y', 'Z')]) >>> chain.get_independencies() (X _|_ Z | Y) (Z _|_ X | Y) """ independencies = Independencies() for start in (self.nodes()): rest = set(self.nodes()) - {start} for r in range(len(rest)): for observed in itertools.combinations(rest, r): d_seperated_variables = rest - set(observed) - set( self.active_trail_nodes(start, observed=observed)) if d_seperated_variables: independencies.add_assertions( [start, d_seperated_variables, observed]) independencies.reduce() if not latex: return independencies else: return independencies.latex_string()
def test_estimate_from_independencies(self): ind = Independencies(['B', 'C'], ['A', ['B', 'C'], 'D']) ind = ind.closure() model = ConstraintBasedEstimator.estimate_from_independencies( "ABCD", ind) self.assertSetEqual(set(model.edges()), set([('B', 'D'), ('A', 'D'), ('C', 'D')])) model1 = BayesianModel([('A', 'C'), ('B', 'C'), ('B', 'D'), ('C', 'E')]) model2 = ConstraintBasedEstimator.estimate_from_independencies( model1.nodes(), model1.get_independencies()) self.assertTrue( set(model2.edges()) == set(model1.edges()) or set(model2.edges()) == set([('B', 'C'), ('A', 'C'), ('C', 'E'), ('D', 'B')]))
def test_estimate_from_independencies(self): ind = Independencies(["B", "C"], ["A", ["B", "C"], "D"]) ind = ind.closure() model = ConstraintBasedEstimator.estimate_from_independencies( "ABCD", ind) self.assertSetEqual(set(model.edges()), set([("B", "D"), ("A", "D"), ("C", "D")])) model1 = BayesianModel([("A", "C"), ("B", "C"), ("B", "D"), ("C", "E")]) model2 = ConstraintBasedEstimator.estimate_from_independencies( model1.nodes(), model1.get_independencies()) self.assertTrue( set(model2.edges()) == set(model1.edges()) or set(model2.edges()) == set([("B", "C"), ("A", "C"), ("C", "E"), ("D", "B")]))
def local_independencies(self, variables): """ Returns an instance of Independencies containing the local independencies of each of the variables. Parameters ---------- variables: str or array like variables whose local independencies are to be found. Examples -------- >>> from pgmpy.models import BayesianModel >>> student = BayesianModel() >>> student.add_edges_from([('diff', 'grade'), ('intel', 'grade'), >>> ('grade', 'letter'), ('intel', 'SAT')]) >>> ind = student.local_independencies('grade') >>> ind (grade _|_ SAT | diff, intel) """ def dfs(node): """ Returns the descendents of node. Since Bayesian Networks are acyclic, this is a very simple dfs which does not remember which nodes it has visited. """ descendents = [] visit = [node] while visit: n = visit.pop() neighbors = self.neighbors(n) visit.extend(neighbors) descendents.extend(neighbors) return descendents independencies = Independencies() for variable in variables if isinstance(variables, (list, tuple)) else [variables]: non_descendents = set(self.nodes()) - {variable} - set(dfs(variable)) parents = set(self.get_parents(variable)) if non_descendents - parents: independencies.add_assertions([variable, non_descendents - parents, parents]) return independencies
def get_independencies(self, latex=False): """ Compute independencies in Bayesian Network. Parameters ---------- latex: boolean If latex=True then latex string of the independence assertion would be created. Examples -------- >>> from pgmpy.models import BayesianModel >>> student = BayesianModel() >>> student.add_nodes_from(['diff', 'intel', 'grades', 'letter', 'sat']) >>> student.add_edges_from([('diff', 'grades'), ('intel', 'grades'), ('grade', 'letter'), ... ('intel', 'sat')]) >>> student.get_independencies() """ independencies = Independencies() for start in (self.nodes()): for r in (1, len(self.nodes())): for observed in itertools.combinations(self.nodes(), r): independent_variables = self.active_trail_nodes(start, observed=observed) independent_variables = set(independent_variables) - {start} if independent_variables: independencies.add_assertions([start, independent_variables, observed]) independencies.reduce() if not latex: return independencies else: return independencies.latex_string()
def get_independencies(self, latex=False): """ Computes independencies in the Bayesian Network, by checking d-seperation. Parameters ---------- latex: boolean If latex=True then latex string of the independence assertion would be created. Examples -------- >>> from pgmpy.models import BayesianModel >>> chain = BayesianModel([('X', 'Y'), ('Y', 'Z')]) >>> chain.get_independencies() (X _|_ Z | Y) (Z _|_ X | Y) """ independencies = Independencies() for start in (self.nodes()): rest = set(self.nodes()) - {start} for r in range(len(rest)): for observed in itertools.combinations(rest, r): d_seperated_variables = rest - set(observed) - set( self.active_trail_nodes(start, observed=observed)[start]) if d_seperated_variables: independencies.add_assertions([start, d_seperated_variables, observed]) independencies.reduce() if not latex: return independencies else: return independencies.latex_string()
def test_is_equivalent(self): ind1 = Independencies(["X", ["Y", "W"], "Z"]) ind2 = Independencies(["X", "Y", "Z"], ["X", "W", "Z"]) ind3 = Independencies(["X", "Y", "Z"], ["X", "W", "Z"], ["X", "Y", ["W", "Z"]]) self.assertFalse(ind1.is_equivalent(ind2)) self.assertTrue(ind1.is_equivalent(ind3))
def test_is_equivalent(self): ind1 = Independencies(['X', ['Y', 'W'], 'Z']) ind2 = Independencies(['X', 'Y', 'Z'], ['X', 'W', 'Z']) ind3 = Independencies(['X', 'Y', 'Z'], ['X', 'W', 'Z'], ['X', 'Y', ['W', 'Z']]) self.assertFalse(ind1.is_equivalent(ind2)) self.assertTrue(ind1.is_equivalent(ind3))
def test_eq(self): self.assertTrue(self.Independencies3 == self.Independencies4) self.assertFalse(self.Independencies3 != self.Independencies4) self.assertTrue(self.Independencies3 != self.Independencies5) self.assertFalse(self.Independencies4 == self.Independencies5) self.assertFalse(Independencies() == Independencies(["A", "B", "C"])) self.assertFalse(Independencies(["A", "B", "C"]) == Independencies()) self.assertTrue(Independencies() == Independencies())
def test_eq(self): self.assertTrue(self.Independencies3 == self.Independencies4) self.assertFalse(self.Independencies3 != self.Independencies4) self.assertTrue(self.Independencies3 != self.Independencies5) self.assertFalse(self.Independencies4 == self.Independencies5) self.assertFalse(Independencies() == Independencies(['A', 'B', 'C'])) self.assertFalse(Independencies(['A', 'B', 'C']) == Independencies()) self.assertTrue(Independencies() == Independencies())
def test_build_skeleton(self): ind = Independencies(['B', 'C'], ['A', ['B', 'C'], 'D']) ind = ind.closure() skel1, sep_sets1 = ConstraintBasedEstimator.build_skeleton("ABCD", ind) self.assertTrue(self._edge_list_equal(skel1.edges(), [('A', 'D'), ('B', 'D'), ('C', 'D')])) sep_sets_ref1 = {frozenset({'A', 'C'}): (), frozenset({'A', 'B'}): (), frozenset({'C', 'B'}): ()} self.assertEqual(sep_sets1, sep_sets_ref1) model = BayesianModel([('A', 'C'), ('B', 'C'), ('B', 'D'), ('C', 'E')]) skel2, sep_sets2 = ConstraintBasedEstimator.build_skeleton(model.nodes(), model.get_independencies()) self.assertTrue(self._edge_list_equal(skel2, [('D', 'B'), ('A', 'C'), ('B', 'C'), ('C', 'E')])) sep_sets_ref2 = {frozenset({'D', 'C'}): ('B',), frozenset({'E', 'B'}): ('C',), frozenset({'A', 'D'}): (), frozenset({'E', 'D'}): ('C',), frozenset({'E', 'A'}): ('C',), frozenset({'A', 'B'}): ()} # witnesses/seperators might change on each run, so we cannot compare directly self.assertEqual(sep_sets2.keys(), sep_sets_ref2.keys()) self.assertEqual([len(v) for v in sorted(sep_sets2.values())], [len(v) for v in sorted(sep_sets_ref2.values())])
def test_build_skeleton(self): ind = Independencies(["B", "C"], ["A", ["B", "C"], "D"]) ind = ind.closure() skel1, sep_sets1 = ConstraintBasedEstimator.build_skeleton("ABCD", ind) self.assertTrue( self._edge_list_equal(skel1.edges(), [("A", "D"), ("B", "D"), ("C", "D")])) sep_sets_ref1 = { frozenset({"A", "C"}): (), frozenset({"A", "B"}): (), frozenset({"C", "B"}): (), } self.assertEqual(sep_sets1, sep_sets_ref1) model = BayesianModel([("A", "C"), ("B", "C"), ("B", "D"), ("C", "E")]) skel2, sep_sets2 = ConstraintBasedEstimator.build_skeleton( model.nodes(), model.get_independencies()) self.assertTrue( self._edge_list_equal(skel2, [("D", "B"), ("A", "C"), ("B", "C"), ("C", "E")])) sep_sets_ref2 = { frozenset({"D", "C"}): ("B", ), frozenset({"E", "B"}): ("C", ), frozenset({"A", "D"}): (), frozenset({"E", "D"}): ("C", ), frozenset({"E", "A"}): ("C", ), frozenset({"A", "B"}): (), } # witnesses/seperators might change on each run, so we cannot compare directly self.assertEqual(sep_sets2.keys(), sep_sets_ref2.keys()) self.assertEqual( [len(v) for v in sorted(sep_sets2.values())], [len(v) for v in sorted(sep_sets_ref2.values())], )
def local_independencies(self, variables): """ Returns an instance of Independencies containing the local independencies of each of the variables. Parameters ---------- variables: str or array like variables whose local independencies are to be found. Examples -------- >>> from pgmpy.models import DAG >>> student = DAG() >>> student.add_edges_from([('diff', 'grade'), ('intel', 'grade'), >>> ('grade', 'letter'), ('intel', 'SAT')]) >>> ind = student.local_independencies('grade') >>> ind (grade _|_ SAT | diff, intel) """ independencies = Independencies() for variable in ( variables if isinstance(variables, (list, tuple)) else [variables] ): non_descendents = ( set(self.nodes()) - {variable} - set(nx.dfs_preorder_nodes(self, variable)) ) parents = set(self.get_parents(variable)) if non_descendents - parents: independencies.add_assertions( [variable, non_descendents - parents, parents] ) return independencies
def get_local_independencies(self, latex=False): """ Returns all the local independencies present in the markov model. Local independencies are the independence assertion in the form of .. math:: {X \perp W - {X} - MB(X) | MB(X)} where MB is the markov blanket of all the random variables in X Parameters ---------- latex: boolean If latex=True then latex string of the indepedence assertion would be created Examples -------- >>> from pgmpy.models import MarkovModel >>> mm = MarkovModel() >>> mm.add_nodes_from(['x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7']) >>> mm.add_edges_from([('x1', 'x3'), ('x1', 'x4'), ('x2', 'x4'), ... ('x2', 'x5'), ('x3', 'x6'), ('x4', 'x6'), ... ('x4', 'x7'), ('x5', 'x7')]) >>> mm.get_local_independecies() """ from pgmpy.exceptions import RequiredError local_independencies = Independencies() all_vars = set(self.nodes()) for node in self.nodes(): markov_blanket = set(self.markov_blanket(node)) rest = all_vars - set([node]) - markov_blanket try: local_independencies.add_assertions( [node, list(rest), list(markov_blanket)]) except RequiredError: pass local_independencies.reduce() if latex: return local_independencies.latex_string() else: return local_independencies
def test_closure(self): ind1 = Independencies(('A', ['B', 'C'], 'D')) self.assertEqual(ind1.closure(), Independencies(('A', ['B', 'C'], 'D'), ('A', 'B', ['C', 'D']), ('A', 'C', ['B', 'D']), ('A', 'B', 'D'), ('A', 'C', 'D'))) ind2 = Independencies(('W', ['X', 'Y', 'Z'])) self.assertEqual(ind2.closure(), Independencies( ('W', 'Y'), ('W', 'Y', 'X'), ('W', 'Y', 'Z'), ('W', 'Y', ['X', 'Z']), ('W', ['Y', 'X']), ('W', 'X', ['Y', 'Z']), ('W', ['X', 'Z'], 'Y'), ('W', 'X'), ('W', ['X', 'Z']), ('W', ['Y', 'Z'], 'X'), ('W', ['Y', 'X', 'Z']), ('W', 'X', 'Z'), ('W', ['Y', 'Z']), ('W', 'Z', 'X'), ('W', 'Z'), ('W', ['Y', 'X'], 'Z'), ('W', 'X', 'Y'), ('W', 'Z', ['Y', 'X']), ('W', 'Z', 'Y'))) ind3 = Independencies(('c', 'a', ['b', 'e', 'd']), (['e', 'c'], 'b', ['a', 'd']), (['b', 'd'], 'e', 'a'), ('e', ['b', 'd'], 'c'), ('e', ['b', 'c'], 'd'), (['e', 'c'], 'a', 'b')) self.assertEqual(len(ind3.closure().get_assertions()), 78)
def get_independencies(self, latex=False): """ Compute independencies in Bayesian Network. Parameters ---------- latex: boolean If latex=True then latex string of the independence assertion would be created. Examples -------- >>> from pgmpy.models import BayesianModel >>> student = BayesianModel() >>> student.add_nodes_from(['diff', 'intel', 'grades', 'letter', 'sat']) >>> student.add_edges_from([('diff', 'grades'), ('intel', 'grades'), ('grade', 'letter'), ... ('intel', 'sat')]) >>> student.get_independencies() """ independencies = Independencies() for start in (self.nodes()): for r in (1, len(self.nodes())): for observed in itertools.combinations(self.nodes(), r): independent_variables = self.active_trail_nodes( start, observed=observed) independent_variables = set(independent_variables) - { start } if independent_variables: independencies.add_assertions( [start, independent_variables, observed]) independencies.reduce() if not latex: return independencies else: return independencies.latex_string()
def get_local_independencies(self, latex=False): """ Returns all the local independencies present in the markov model. Local independencies are the independence assertion in the form of .. math:: {X \perp W - {X} - MB(X) | MB(X)} where MB is the markov blanket of all the random variables in X Parameters ---------- latex: boolean If latex=True then latex string of the indepedence assertion would be created Examples -------- >>> from pgmpy.models import MarkovModel >>> mm = MarkovModel() >>> mm.add_nodes_from(['x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7']) >>> mm.add_edges_from([('x1', 'x3'), ('x1', 'x4'), ('x2', 'x4'), ... ('x2', 'x5'), ('x3', 'x6'), ('x4', 'x6'), ... ('x4', 'x7'), ('x5', 'x7')]) >>> mm.get_local_independecies() """ from pgmpy.exceptions import RequiredError local_independencies = Independencies() all_vars = set(self.nodes()) for node in self.nodes(): markov_blanket = set(self.markov_blanket(node)) rest = all_vars - set([node]) - markov_blanket try: local_independencies.add_assertions([node, list(rest), list(markov_blanket)]) except RequiredError: pass local_independencies.reduce() if latex: return local_independencies.latex_string() else: return local_independencies
def test_local_independencies(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c')]) independencies = self.graph.get_local_independencies() self.assertIsInstance(independencies, Independencies) self.assertEqual(independencies, Independencies(['a', 'c', 'b']))
def test_init(self): self.Independencies1 = Independencies(['X', 'Y', 'Z']) self.assertEqual(self.Independencies1, Independencies(['X', 'Y', 'Z'])) self.Independencies2 = Independencies() self.assertEqual(self.Independencies2, Independencies())
def test_add_assertions(self): self.Independencies1 = Independencies(['X', 'Y', 'Z']) self.assertEqual(self.Independencies1, Independencies(['X', 'Y', 'Z'])) self.Independencies2 = Independencies(['A', 'B', 'C'], ['D', 'E', 'F']) self.assertEqual(self.Independencies2, Independencies(['A', 'B', 'C'], ['D', 'E', 'F']))
class TestIndependencies(unittest.TestCase): def setUp(self): self.Independencies = Independencies() self.Independencies3 = Independencies(['a', ['b', 'c', 'd'], ['e', 'f', 'g']], ['c', ['d', 'e', 'f'], ['g', 'h']]) self.Independencies4 = Independencies([['f', 'd', 'e'], 'c', ['h', 'g']], [['b', 'c', 'd'], 'a', ['f', 'g', 'e']]) self.Independencies5 = Independencies(['a', ['b', 'c', 'd'], ['e', 'f', 'g']], ['c', ['d', 'e', 'f'], 'g']) def test_init(self): self.Independencies1 = Independencies(['X', 'Y', 'Z']) self.assertEqual(self.Independencies1, Independencies(['X', 'Y', 'Z'])) self.Independencies2 = Independencies() self.assertEqual(self.Independencies2, Independencies()) def test_add_assertions(self): self.Independencies1 = Independencies(['X', 'Y', 'Z']) self.assertEqual(self.Independencies1, Independencies(['X', 'Y', 'Z'])) self.Independencies2 = Independencies(['A', 'B', 'C'], ['D', 'E', 'F']) self.assertEqual(self.Independencies2, Independencies(['A', 'B', 'C'], ['D', 'E', 'F'])) def test_get_assertions(self): self.Independencies1 = Independencies(['X', 'Y', 'Z']) self.assertEqual(self.Independencies1.independencies, self.Independencies1.get_assertions()) self.Independencies2 = Independencies(['A', 'B', 'C'], ['D', 'E', 'F']) self.assertEqual(self.Independencies2.independencies, self.Independencies2.get_assertions()) def test_closure(self): ind1 = Independencies(('A', ['B', 'C'], 'D')) self.assertEqual(ind1.closure(), Independencies(('A', ['B', 'C'], 'D'), ('A', 'B', ['C', 'D']), ('A', 'C', ['B', 'D']), ('A', 'B', 'D'), ('A', 'C', 'D'))) ind2 = Independencies(('W', ['X', 'Y', 'Z'])) self.assertEqual(ind2.closure(), Independencies( ('W', 'Y'), ('W', 'Y', 'X'), ('W', 'Y', 'Z'), ('W', 'Y', ['X', 'Z']), ('W', ['Y', 'X']), ('W', 'X', ['Y', 'Z']), ('W', ['X', 'Z'], 'Y'), ('W', 'X'), ('W', ['X', 'Z']), ('W', ['Y', 'Z'], 'X'), ('W', ['Y', 'X', 'Z']), ('W', 'X', 'Z'), ('W', ['Y', 'Z']), ('W', 'Z', 'X'), ('W', 'Z'), ('W', ['Y', 'X'], 'Z'), ('W', 'X', 'Y'), ('W', 'Z', ['Y', 'X']), ('W', 'Z', 'Y'))) ind3 = Independencies(('c', 'a', ['b', 'e', 'd']), (['e', 'c'], 'b', ['a', 'd']), (['b', 'd'], 'e', 'a'), ('e', ['b', 'd'], 'c'), ('e', ['b', 'c'], 'd'), (['e', 'c'], 'a', 'b')) self.assertEqual(len(ind3.closure().get_assertions()), 78) def test_entails(self): ind1 = Independencies([['A', 'B'], ['C', 'D'], 'E']) ind2 = Independencies(['A', 'C', 'E']) self.assertTrue(ind1.entails(ind2)) self.assertFalse(ind2.entails(ind1)) ind3 = Independencies(('W', ['X', 'Y', 'Z'])) self.assertTrue(ind3.entails(ind3.closure())) self.assertTrue(ind3.closure().entails(ind3)) def test_is_equivalent(self): ind1 = Independencies(['X', ['Y', 'W'], 'Z']) ind2 = Independencies(['X', 'Y', 'Z'], ['X', 'W', 'Z']) ind3 = Independencies(['X', 'Y', 'Z'], ['X', 'W', 'Z'], ['X', 'Y', ['W', 'Z']]) self.assertFalse(ind1.is_equivalent(ind2)) self.assertTrue(ind1.is_equivalent(ind3)) def test_eq(self): self.assertTrue(self.Independencies3 == self.Independencies4) self.assertFalse(self.Independencies3 != self.Independencies4) self.assertTrue(self.Independencies3 != self.Independencies5) self.assertFalse(self.Independencies4 == self.Independencies5) self.assertFalse(Independencies() == Independencies(['A', 'B', 'C'])) self.assertFalse(Independencies(['A', 'B', 'C']) == Independencies()) self.assertTrue(Independencies() == Independencies()) def tearDown(self): del self.Independencies del self.Independencies3 del self.Independencies4 del self.Independencies5
def test_local_independencies(self): self.graph.add_edges_from([("a", "b"), ("b", "c")]) independencies = self.graph.get_local_independencies() self.assertIsInstance(independencies, Independencies) self.assertEqual(independencies, Independencies(["a", "c", "b"]))
from pgmpy.independencies import Independencies # There are multiple ways to create an Independencies object, we # could either initialize an empty object or initialize with some # assertions. independencies = Independencies() # Empty object independencies.get_assertions() independencies.add_assertions(assertion1, assertion2) independencies.get_assertions()