Пример #1
0
  def testBugInferenceWithEvidenceWithSemiFastSyntax(self):
    tst_id = gum.InfluenceDiagram()
    tst_id.addVariables(["c1","c","$u","*d"])
    tst_id.addArcs([("c","c1"),
                    ("c","u"),
                    ("d","u")])

    tst_id.cpt("c").fillWith([0.5, 0.5])

    tst_id.cpt("c1")[{'c': 0}] = [1, 0]
    tst_id.cpt("c1")[{'c': 1}] = [0, 1]

    tst_id.utility("u")[{'c': 0, 'd': 0}] = [10]
    tst_id.utility("u")[{'c': 0, 'd': 1}] = [21]
    tst_id.utility("u")[{'c': 1, 'd': 0}] = [100]
    tst_id.utility("u")[{'c': 1, 'd': 1}] = [200]

    ie = gum.ShaferShenoyLIMIDInference(tst_id)
    ie.setEvidence({'c': 0})
    ie.makeInference()
    self.assertEqual(ie.optimalDecision("d"), gum.Potential().add(tst_id.variableFromName("d")).fillWith([0, 1]))
    self.assertEqual(ie.MEU()['mean'], 21)

    ie = gum.ShaferShenoyLIMIDInference(tst_id)
    ie.setEvidence({'c': 1})
    ie.makeInference()
    self.assertEqual(ie.optimalDecision("d"), gum.Potential().add(tst_id.variableFromName("d")).fillWith([0, 1]))
    self.assertEqual(ie.MEU()['mean'], 200)
Пример #2
0
  def testBugInferenceWithEvidence(self):
    tst_id = gum.fastID("c1<-c->$u<-*d")

    tst_id.cpt("c").fillWith([0.5, 0.5])

    tst_id.cpt("c1")[{'c': 0}] = [1, 0]
    tst_id.cpt("c1")[{'c': 1}] = [0, 1]

    tst_id.utility("u")[{'c': 0, 'd': 0}] = [10]
    tst_id.utility("u")[{'c': 0, 'd': 1}] = [21]
    tst_id.utility("u")[{'c': 1, 'd': 0}] = [100]
    tst_id.utility("u")[{'c': 1, 'd': 1}] = [200]

    ie = gum.ShaferShenoyLIMIDInference(tst_id)
    ie.setEvidence({'c': 0})
    ie.makeInference()
    self.assertEqual(ie.optimalDecision("d"), gum.Potential().add(tst_id.variableFromName("d")).fillWith([0, 1]))
    self.assertEqual(ie.MEU()['mean'], 21)

    ie = gum.ShaferShenoyLIMIDInference(tst_id)
    ie.setEvidence({'c': 1})
    ie.makeInference()
    self.assertEqual(ie.optimalDecision("d"), gum.Potential().add(tst_id.variableFromName("d")).fillWith([0, 1]))
    self.assertEqual(ie.MEU()['mean'], 200)
Пример #3
0
def LIMIDinference2dot(diag, size, engine, evs, targets):
    """
  create a pydot representation of an inference in a influence diagram

  Parameters
  ----------
  diag: pyAgrum.InfluenceDiagram
    the model
  size: float|str
    the size of the rendered graph
  engine: pyAgrum.InfluenceDiagramInference
    the inference algorithm used. If None, ShaferShenoyLIMIDInference will be used
  evs: Dict[str,str|int|List[float]]
    the evidence
  targets: Set[str]
    set of targetted variable. If targets={} then each node is a target

  Returns
  -------
  pydot.Dot
    the representation of the inference
  """
    startTime = time.time()
    if engine is None:
        ie = gum.ShaferShenoyLIMIDInference(diag)
    else:
        ie = engine
    ie.setEvidence(evs)
    ie.makeInference()
    stopTime = time.time()
    meu = ie.MEU()

    temp_dir = mkdtemp("", "tmp",
                       None)  # with TemporaryDirectory() as temp_dir:

    dotstr = "digraph structs {\n  fontcolor=\"" + \
             gumcols.getBlackInTheme() + "\";bgcolor=\"transparent\";"

    fmt = '.' + gum.config["influenceDiagram", "utility_visible_digits"] + 'f'
    if gum.config["influenceDiagram", "utility_show_loss"] == "True":
        titut = f'mEL {-meu["mean"]:{fmt}}'
    else:
        titut = f'MEU {meu["mean"]:{fmt}}'
    if gum.config["influenceDiagram", "utility_show_stdev"] == "True":
        titut += f' (stdev={math.sqrt(meu["variance"]):{fmt}})'

    slabel = f'label="{titut}'

    if gum.config["notebook", "show_inference_time"] == "True":
        slabel += f"\nInference in {1000 * (stopTime - startTime):6.2f}ms"
    dotstr += slabel + "\";\n"

    for nid in diag.nodes():
        name = diag.variable(nid).name()

        # defaults
        if diag.isChanceNode(nid):
            bgcolor = gum.config["influenceDiagram", "default_chance_bgcolor"]
            fgcolor = gum.config["influenceDiagram", "default_chance_fgcolor"]
            shape = gum.config["influenceDiagram", "chance_shape"]
        elif diag.isDecisionNode(nid):
            bgcolor = gum.config["influenceDiagram",
                                 "default_decision_bgcolor"]
            fgcolor = gum.config["influenceDiagram",
                                 "default_decision_fgcolor"]
            shape = gum.config["influenceDiagram", "decision_shape"]
        else:  # diag.isUtilityNode(nid):
            bgcolor = gum.config["influenceDiagram", "default_utility_bgcolor"]
            fgcolor = gum.config["influenceDiagram", "default_utility_fgcolor"]
            shape = gum.config["influenceDiagram", "utility_shape"]

        # 'hard' colour for evidence (?)
        if name in evs or nid in evs:
            bgcolor = gum.config["notebook", "evidence_bgcolor"]
            fgcolor = gum.config["notebook", "evidence_fgcolor"]

        styleattribute = 'style=filled, height=0,margin=0.1'
        colorattribute = f'fillcolor="{bgcolor}", fontcolor="{fgcolor}", color="#000000"'

        if not diag.isUtilityNode(nid):
            if len(targets) == 0 or name in targets or nid in targets:
                # shape="rectangle"
                filename = temp_dir + \
                           hashlib.md5(name.encode()).hexdigest() + "." + \
                           gum.config["notebook", "graph_format"]
                saveFigProba(ie.posterior(name),
                             filename,
                             bgcolor=bgcolor,
                             util=ie.posteriorUtility(nid),
                             txtcolor=fgcolor)
                dotstr += f' "{name}" [shape=rectangle,image="{filename}",label="", {colorattribute}];\n'
            else:
                dotstr += f' "{name}" [{colorattribute},shape={shape},{styleattribute}]'
        else:  # utility node
            mv = ie.meanVar(name)

            if gum.config["influenceDiagram", "utility_show_loss"] == "True":
                coef = -1
            else:
                coef = 1

            fmt = "." + gum.config["influenceDiagram",
                                   "utility_visible_digits"] + "f"
            labut = f'{name} : {coef * mv["mean"]:{fmt}}'
            if gum.config["influenceDiagram", "utility_show_stdev"] == "True":
                labut += f' ({math.sqrt(mv["variance"]):{fmt}})'

            dotstr += f' "{name}" [label="{labut}",{colorattribute},{styleattribute},shape={shape}]'

    # arcs
    dotstr += "\n"
    for node in diag.nodes():
        for chi in diag.children(node):
            dotstr += '  "' + diag.variable(node).name() + '"->"' + \
                      diag.variable(chi).name() + '"'
            if diag.isDecisionNode(chi):
                dotstr += f' [style="{gum.config["influenceDiagram", "decision_arc_style"]}"]'
            elif diag.isUtilityNode(chi):
                dotstr += f' [style="{gum.config["influenceDiagram", "utility_arc_style"]}"]'
            dotstr += ";\n"
    dotstr += "}"

    g = dot.graph_from_dot_data(dotstr)[0]

    # workaround for some badly parsed graph (pyparsing>=3.03)
    g.del_node('"\\n"')

    if size is None:
        size = gum.config["influenceDiagram", "default_id_inference_size"]
    g.set_size(size)
    g.temp_dir = temp_dir

    return g
Пример #4
0
def prepareShowInference(model,
                         engine=None,
                         evs=None,
                         targets=None,
                         size=None,
                         nodeColor=None,
                         factorColor=None,
                         arcWidth=None,
                         arcColor=None,
                         cmap=None,
                         cmapArc=None,
                         graph=None,
                         view=None):
    """
  Transform an inference for a model in a dot representation

  Parameters
  ----------
  model: pyAgrum:GraphicalModel
      the model in which to infer (pyAgrum.BayesNet, pyAgrum.MarkovNet or pyAgrum.InfluenceDiagram)
  filename: str
      the name of the resulting file (suffix in ['pdf', 'png', 'ps']). If filename is None, the result is a np.array ready to be used with imshow().
  engine: pyAgrum.Inference
      inference algorithm used. If None, gum.LazyPropagation will be used for BayesNet,gum.ShaferShenoy for gum.MarkovNet and gum.ShaferShenoyLIMIDInference for gum.InfluenceDiagram.
  evs: Dict[str,str|int]
      map of evidence
  targets: Set[str|int]
      set of targets
  size: str
      size of the rendered graph
  nodeColor: Dict[int,float]
      a nodeMap of values (between 0 and 1) to be shown as color of nodes (with special colors for 0 and 1)
  factorColor: Dict[int,float]
      a nodeMap of values (between 0 and 1) to be shown as color of factors (in MarkovNet representation)
  arcWidth: Dict[(int,int),float]
      a arcMap of values to be shown as width of arcs
  arcColor: Dict[(int,int),float]
      a arcMap of values (between 0 and 1) to be shown as color of arcs
  cmap: matplotlib.colors.ColorMap
      color map to show the color of nodes and arcs
  cmapArc: matplotlib.colors.ColorMap
      color map to show the vals of Arcs.
  graph: pyAgrum.Graph
      only shows nodes that have their id in the graph (and not in the whole BN)
  view: str
      graph | factorgraph | None (default) for Markov network

  Raises
  ------
  pyAgrum.InvalidArgument:
      if the arg is invalid

  Returns
  -------
  str
      the obtained graph as a string
  """
    if size is None:
        size = gum.config["notebook", "default_graph_inference_size"]

    if evs is None:
        evs = {}

    if targets is None:
        targets = {}

    if isinstance(model, gum.BayesNet):
        if engine is None:
            engine = gum.LazyPropagation(model)
        return BNinference2dot(model,
                               size=size,
                               engine=engine,
                               evs=evs,
                               targets=targets,
                               nodeColor=nodeColor,
                               arcWidth=arcWidth,
                               arcColor=arcColor,
                               cmapNode=cmap,
                               cmapArc=cmapArc)
    if isinstance(model, gum.MarkovNet):
        if view is None:
            view = gum.config["notebook", "default_markovnetwork_view"]
        if engine is None:
            engine = gum.ShaferShenoyMNInference(model)

        if view == "graph":
            return MNinference2UGdot(model,
                                     size=size,
                                     engine=engine,
                                     evs=evs,
                                     targets=targets,
                                     nodeColor=nodeColor,
                                     factorColor=factorColor,
                                     arcWidth=arcWidth,
                                     arcColor=arcColor,
                                     cmapNode=cmap,
                                     cmapArc=cmapArc)
        # view=factor graph
        return MNinference2FactorGraphdot(model,
                                          size=size,
                                          engine=engine,
                                          evs=evs,
                                          targets=targets,
                                          nodeColor=nodeColor,
                                          factorColor=factorColor,
                                          cmapNode=cmap)
    if isinstance(model, gum.InfluenceDiagram):
        if engine is None:
            engine = gum.ShaferShenoyLIMIDInference(model)
        return LIMIDinference2dot(model,
                                  size=size,
                                  engine=engine,
                                  evs=evs,
                                  targets=targets)
    if isinstance(model, gum.CredalNet):
        if engine is None:
            engine = gum.CNMonteCarloSampling(model)
        return CNinference2dot(model,
                               size=size,
                               engine=engine,
                               evs=evs,
                               targets=targets,
                               nodeColor=nodeColor,
                               arcWidth=arcWidth,
                               arcColor=arcColor,
                               cmapNode=cmap)

    raise gum.InvalidArgument(
        "Argument model should be a PGM (BayesNet, MarkovNet or Influence Diagram)"
    )