def __init__( self, gid: str, nodes: Set[NumCatRVariable], edges: Set[Edge], factors: Optional[Set[Factor]] = None, data={}, ): """! \brief constructor for a generic Probabilistic Graphical Model The generic model that extends the #Graph definition by adding a new set, called set of factors. Most of the parameters are documented in #Graph. """ super().__init__(gid=gid, data=data, nodes=nodes, edges=edges) if factors is None: fs: Set[Factor] = set() for e in BaseGraphOps.edges(self): estart = e.start() eend = e.end() sdata = estart.data() edata = eend.data() evidences = set() if "evidence" in sdata: evidences.add((estart.id(), sdata["evidence"])) if "evidence" in edata: evidences.add((eend.id(), edata["evidence"])) f = Factor(gid=str(uuid4()), scope_vars=set([estart, eend])) if len(evidences) != 0: f = f.reduced_by_value(evidences) fs.add(f) self.Fs = fs else: self.Fs = factors
def from_undigraph(cls, udi: UndiGraph): """! \brief Make a markov network from undirected graph \throws ValueError If nodes are not an instance of a random variable, we raise a value error. Unless it is specified we assume that edges indicate a joint distribution \code{.py} >>> idata = {"A": {"outcome-values": [True, False]}} >>> a = NumCatRVariable( >>> node_id="a", >>> input_data=idata["A"], >>> distribution=lambda x: 0.01 if x else 0.99, >>> ) >>> b = NumCatRVariable( >>> node_id="b", input_data=idata["B"], distribution=lambda x: 0.5 >>> ) >>> d = NumCatRVariable( >>> node_id="d", >>> input_data=idata["A"], >>> distribution=lambda x: 0.7468 if x else 0.2532, >>> ) >>> c = NumCatRVariable( >>> node_id="c", >>> input_data=idata["A"], >>> distribution=lambda x: 0.7312 if x else 0.2688, >>> ) >>> ab = Edge( >>> "ab", start_node=a, end_node=b, edge_type=EdgeType.UNDIRECTED >>> ) >>> ad = Edge( >>> "ad", start_node=a, end_node=d, edge_type=EdgeType.UNDIRECTED >>> ) >>> bc = Edge( >>> "bc", start_node=b, end_node=c, edge_type=EdgeType.UNDIRECTED >>> ) >>> dc = Edge( >>> "dc", start_node=d, end_node=c, edge_type=EdgeType.UNDIRECTED >>> ) >>> ugraph = UndiGraph( >>> "ug1", >>> data={"m": "f"}, >>> nodes=set([a, b, c, d]), >>> edges=set([ab, ad, bc, dc]), >>> ) >>> markov = MarkovNetwork.from_undigraph(udi=ugraph) \endcode """ for n in BaseGraphOps.nodes(udi): if not isinstance(n, RandomVariable): raise ValueError( "Nodes are not an instance of random variable") fs: Set[Factor] = set() maximal_cliques = udi.find_maximal_cliques() for clique in maximal_cliques: evidences = set() for n in clique: edata = n.data() if "evidence" in edata: evidences.add((n.id(), edata["evidence"])) f = Factor(gid=str(uuid4()), scope_vars=clique) if len(evidences) != 0: f = f.reduced_by_value(evidences) fs.add(f) return MarkovNetwork( gid=str(uuid4()), nodes=BaseGraphOps.nodes(udi), edges=BaseGraphOps.edges(udi), factors=fs, )