class_docstr: Initializes a Bayesian Network.
  A models stores nodes and edges with conditional probability
  distribution (cpd) and other attributes.
  
  models hold directed edges.  Self loops are not allowed neither
  multiple (parallel) edges.
  
  Nodes can be any hashable python object.
  
  Edges are represented as links between nodes.
  
  Parameters
  ----------
  ebunch: input graph
      Data to initialize graph.  If ebunch=None (default) an empty
      graph is created.  The ebunch can be an edge list, or any
      NetworkX graph object.
  
  latents: list, array-like
      List of variables which are latent (i.e. unobserved) in the model.
  
  Examples
  --------
  Create an empty Bayesian Network with no nodes and no edges.
  
  >>> from pgmpy.models import BayesianNetwork
  >>> G = BayesianNetwork()
  
  G can be grown in several ways.
  
  **Nodes:**
  
  Add one node at a time:
  
  >>> G.add_node('a')
  
  Add the nodes from any container (a list, set or tuple or the nodes
  from another graph).
  
  >>> G.add_nodes_from(['a', 'b'])
  
  **Edges:**
  
  G can also be grown by adding edges.
  
  Add one edge,
  
  >>> G.add_edge('a', 'b')
  
  a list of edges,
  
  >>> G.add_edges_from([('a', 'b'), ('b', 'c')])
  
  If some edges connect nodes not yet in the model, the nodes
  are added automatically.  There are no errors when adding
  nodes or edges that already exist.
  
  **Shortcuts:**
  
  Many common graph features allow python syntax for speed reporting.
  
  >>> 'a' in G     # check if node in graph
  True
  >>> len(G)  # number of nodes in graph
  3
class_docstr_tok: ["Initializes","a","Bayesian","Network",".","A","models","stores","nodes","and","edges","with","conditional","probability","distribution","(","cpd",")","and","other","attributes",".","models","hold","directed","edges",".","Self","loops","are","not","allowed","neither","multiple","(","parallel",")","edges",".","Nodes","can","be","any","hashable","python","object",".","Edges","are","represented","as","links","between","nodes",".","Parameters","--","--","--","--","--","ebunch",":","input","graph","Data","to","initialize","graph",".","If","ebunch=None","(","default",")","an","empty","graph","is","created",".","The","ebunch","can","be","an","edge","list",",","or","any","NetworkX","graph","object",".","latents",":","list",",","array-like","List","of","variables","which","are","latent","(","i.e",".","unobserved",")","in","the","model",".","Examples","--","--","--","--","Create","an","empty","Bayesian","Network","with","no","nodes","and","no","edges",".",">",">",">","from","pgmpy.models","import","BayesianNetwork",">",">",">","G","=","BayesianNetwork","(",")","G","can","be","grown","in","several","ways",".","*","*","Nodes",":","*","*","Add","one","node","at","a","time",":",">",">",">","G.add_node","(","'","a","'",")","Add","the","nodes","from","any","container","(","a","list",",","set","or","tuple","or","the","nodes","from","another","graph",")",".",">",">",">","G.add_nodes_from","(","[","'","a","'",",","'","b","'","]",")","*","*","Edges",":","*","*","G","can","also","be","grown","by","adding","edges",".","Add","one","edge",",",">",">",">","G.add_edge","(","'","a","'",",","'","b","'",")","a","list","of","edges",",",">",">",">","G.add_edges_from","(","[","(","'","a","'",",","'","b","'",")",",","(","'","b","'",",","'","c","'",")","]",")","If","some","edges","connect","nodes","not","yet","in","the","model",",","the","nodes","are","added","automatically",".","There","are","no","errors","when","adding","nodes","or","edges","that","already","exist",".","*","*","Shortcuts",":","*","*","Many","common","graph","features","allow","python","syntax","for","speed","reporting",".",">",">",">","'","a","'","in","G","#","check","if","node","in","graph","True",">",">",">","len","(","G",")","#","number","of","nodes","in","graph","3"]
docstr: Predicts probabilities of all states of the missing variables.
  
  Parameters
  ----------
  data : pandas DataFrame object
      A DataFrame object with column names same as the variables in the model.
  
  Examples
  --------
  >>> import numpy as np
  >>> import pandas as pd
  >>> from pgmpy.models import BayesianNetwork
  >>> values = pd.DataFrame(np.random.randint(low=0, high=2, size=(100, 5)),
  ...                       columns=['A', 'B', 'C', 'D', 'E'])
  >>> train_data = values[:80]
  >>> predict_data = values[80:]
  >>> model = BayesianNetwork([('A', 'B'), ('C', 'B'), ('C', 'D'), ('B', 'E')])
  >>> model.fit(values)
  >>> predict_data = predict_data.copy()
  >>> predict_data.drop('B', axis=1, inplace=True)
  >>> y_prob = model.predict_probability(predict_data)
  >>> y_prob
      B_0         B_1
  80  0.439178    0.560822
  81  0.581970    0.418030
  82  0.488275    0.511725
  83  0.581970    0.418030
  84  0.510794    0.489206
  85  0.439178    0.560822
  86  0.439178    0.560822
  87  0.417124    0.582876
  88  0.407978    0.592022
  89  0.429905    0.570095
  90  0.581970    0.418030
  91  0.407978    0.592022
  92  0.429905    0.570095
  93  0.429905    0.570095
  94  0.439178    0.560822
  95  0.407978    0.592022
  96  0.559904    0.440096
  97  0.417124    0.582876
  98  0.488275    0.511725
  99  0.407978    0.592022
code: def predict_probability(self, data):
      """
      Predicts probabilities of all states of the missing variables.
  
      Parameters
      ----------
      data : pandas DataFrame object
          A DataFrame object with column names same as the variables in the model.
  
      Examples
      --------
      >>> import numpy as np
      >>> import pandas as pd
      >>> from pgmpy.models import BayesianNetwork
      >>> values = pd.DataFrame(np.random.randint(low=0, high=2, size=(100, 5)),
      ...                       columns=['A', 'B', 'C', 'D', 'E'])
      >>> train_data = values[:80]
      >>> predict_data = values[80:]
      >>> model = BayesianNetwork([('A', 'B'), ('C', 'B'), ('C', 'D'), ('B', 'E')])
      >>> model.fit(values)
      >>> predict_data = predict_data.copy()
      >>> predict_data.drop('B', axis=1, inplace=True)
      >>> y_prob = model.predict_probability(predict_data)
      >>> y_prob
          B_0         B_1
      80  0.439178    0.560822
      81  0.581970    0.418030
      82  0.488275    0.511725
      83  0.581970    0.418030
      84  0.510794    0.489206
      85  0.439178    0.560822
      86  0.439178    0.560822
      87  0.417124    0.582876
      88  0.407978    0.592022
      89  0.429905    0.570095
      90  0.581970    0.418030
      91  0.407978    0.592022
      92  0.429905    0.570095
      93  0.429905    0.570095
      94  0.439178    0.560822
      95  0.407978    0.592022
      96  0.559904    0.440096
      97  0.417124    0.582876
      98  0.488275    0.511725
      99  0.407978    0.592022
      """
      from pgmpy.inference import VariableElimination
  
      if set(data.columns) == set(self.nodes()):
          raise ValueError(
              "No variable missing in data. Nothing to predict"
          )
  
      elif set(data.columns) - set(self.nodes()):
          raise ValueError(
              "Data has variables which are not in the model"
          )
  
      missing_variables = set(self.nodes()) - set(data.columns)
      pred_values = defaultdict(list)
  
      model_inference = VariableElimination(self)
      for _, data_point in data.iterrows():
          full_distribution = model_inference.query(
              variables=missing_variables,
              evidence=data_point.to_dict(),
              show_progress=False,
          )
          states_dict = {}
          for var in missing_variables:
              states_dict[var] = full_distribution.marginalize(
                  missing_variables - {var}, inplace=False
              )
          for k, v in states_dict.items():
              for l in range(len(v.values)):
                  state = self.get_cpds(k).state_names[k][l]
                  pred_values[k + "_" + str(state)].append(v.values[l])
      return pd.DataFrame(pred_values, index=data.index)
  
imports: import itertools
  from collections import defaultdict
  from functools import reduce
  from operator import mul
  import networkx
  import numpy
  import pandas
  from joblib import Parallel, delayed
  from tqdm.auto import tqdm
  from pgmpy.base import DAG
  from pgmpy.factors.continuous import ContinuousFactor
  from pgmpy.factors.discrete import DiscreteFactor, JointProbabilityDistribution, TabularCPD
  from pgmpy.global_vars import logger
  from pgmpy.models.MarkovNetwork import MarkovNetwork
  from pgmpy.utils import compat_fns
label_desc: Use image node_id 16 for calling the BayesianNetwork obj's underlying member method code with example usage: obj.predict_probability(data) and returns: pd