class_docstr: Class used to compute parameters for a model using Expectation
  Maximization (EM).
  
  EM is an iterative algorithm commonly used for
  estimation in the case when there are latent variables in the model.
  The algorithm iteratively improves the parameter estimates maximizing
  the likelihood of the given data.
  
  Parameters
  ----------
  model: A pgmpy.models.BayesianNetwork instance
  
  data: pandas DataFrame object
      DataFrame object with column names identical to the variable names
      of the network.  (If some values in the data are missing the data
      cells should be set to `numpy.NaN`.  Note that pandas converts each
      column containing `numpy.NaN`s to dtype `float`.)
  
  state_names: dict (optional)
      A dict indicating, for each variable, the discrete set of states
      that the variable can take. If unspecified, the observed values in
      the data set are taken to be the only possible states.
  
  Examples
  --------
  >>> import numpy as np
  >>> import pandas as pd
  >>> from pgmpy.models import BayesianNetwork
  >>> from pgmpy.estimators import ExpectationMaximization
  >>> data = pd.DataFrame(np.random.randint(low=0, high=2, size=(1000, 5)),
  ...                       columns=['A', 'B', 'C', 'D', 'E'])
  >>> model = BayesianNetwork([('A', 'B'), ('C', 'B'), ('C', 'D'), ('B', 'E')])
  >>> estimator = ExpectationMaximization(model, data)
class_docstr_tok: ["Class","used","to","compute","parameters","for","a","model","using","Expectation","Maximization","(","EM",")",".","EM","is","an","iterative","algorithm","commonly","used","for","estimation","in","the","case","when","there","are","latent","variables","in","the","model",".","The","algorithm","iteratively","improves","the","parameter","estimates","maximizing","the","likelihood","of","the","given","data",".","Parameters","--","--","--","--","--","model",":","A","pgmpy.models.BayesianNetwork","instance","data",":","pandas","DataFrame","object","DataFrame","object","with","column","names","identical","to","the","variable","names","of","the","network",".","(","If","some","values","in","the","data","are","missing","the","data","cells","should","be","set","to","`","numpy.NaN","`",".","Note","that","pandas","converts","each","column","containing","`","numpy.NaN","`","s","to","dtype","`","float","`",".",")","state_names",":","dict","(","optional",")","A","dict","indicating",",","for","each","variable",",","the","discrete","set","of","states","that","the","variable","can","take",".","If","unspecified",",","the","observed","values","in","the","data","set","are","taken","to","be","the","only","possible","states",".","Examples","--","--","--","--",">",">",">","import","numpy","as","np",">",">",">","import","pandas","as","pd",">",">",">","from","pgmpy.models","import","BayesianNetwork",">",">",">","from","pgmpy.estimators","import","ExpectationMaximization",">",">",">","data","=","pd.DataFrame","(","np.random.randint","(","low=0",",","high=2",",","size=","(","1000",",","5",")",")",",","...","columns=","[","'","A","'",",","'","B","'",",","'","C","'",",","'D","'",",","'","E","'","]",")",">",">",">","model","=","BayesianNetwork","(","[","(","'","A","'",",","'","B","'",")",",","(","'","C","'",",","'","B","'",")",",","(","'","C","'",",","'D","'",")",",","(","'","B","'",",","'","E","'",")","]",")",">",">",">","estimator","=","ExpectationMaximization","(","model",",","data",")"]
docstr: Method to estimate all model parameters (CPDs) using Expecation Maximization.
  
  Parameters
  ----------
  latent_card: dict (default: None)
      A dictionary of the form {latent_var: cardinality} specifying the
      cardinality (number of states) of each latent variable. If None,
      assumes `2` states for each latent variable.
  
  max_iter: int (default: 100)
      The maximum number of iterations the algorithm is allowed to run for.
      If max_iter is reached, return the last value of parameters.
  
  atol: int (default: 1e-08)
      The absolute accepted tolerance for checking convergence. If the parameters
      change is less than atol in an iteration, the algorithm will exit.
  
  n_jobs: int (default: 1)
      Number of jobs to run in parallel.
      Using n_jobs > 1 for small models or datasets might be slower.
  
  batch_size: int (default: 1000)
      Number of data used to compute weights in a batch.
  
  seed: int
      The random seed to use for generating the intial values.
  
  show_progress: boolean (default: True)
      Whether to show a progress bar for iterations.
  
  Returns
  -------
  Estimated paramters (CPDs): list
      A list of estimated CPDs for the model.
  
  Examples
  --------
  >>> import numpy as np
  >>> import pandas as pd
  >>> from pgmpy.models import BayesianNetwork
  >>> from pgmpy.estimators import ExpectationMaximization as EM
  >>> data = pd.DataFrame(np.random.randint(low=0, high=2, size=(1000, 3)),
  ...                       columns=['A', 'C', 'D'])
  >>> model = BayesianNetwork([('A', 'B'), ('C', 'B'), ('C', 'D')], latents={'B'})
  >>> estimator = EM(model, data)
  >>> estimator.get_parameters(latent_card={'B': 3})
  [<TabularCPD representing P(C:2) at 0x7f7b534251d0>,
  <TabularCPD representing P(B:3 | C:2, A:2) at 0x7f7b4dfd4da0>,
  <TabularCPD representing P(A:2) at 0x7f7b4dfd4fd0>,
  <TabularCPD representing P(D:2 | C:2) at 0x7f7b4df822b0>]
docstr_tok: ["Method","to","estimate","all","model","parameters","(","CPDs",")","using","Expecation","Maximization",".","Parameters","--","--","--","--","--","latent_card",":","dict","(","default",":","None",")","A","dictionary","of","the","form","{","latent_var",":","cardinality","}","specifying","the","cardinality","(","number","of","states",")","of","each","latent","variable",".","If","None",",","assumes","`","2","`","states","for","each","latent","variable",".","max_iter",":","int","(","default",":","100",")","The","maximum","number","of","iterations","the","algorithm","is","allowed","to","run","for",".","If","max_iter","is","reached",",","return","the","last","value","of","parameters",".","atol",":","int","(","default",":","1e-08",")","The","absolute","accepted","tolerance","for","checking","convergence",".","If","the","parameters","change","is","less","than","atol","in","an","iteration",",","the","algorithm","will","exit",".","n_jobs",":","int","(","default",":","1",")","Number","of","jobs","to","run","in","parallel",".","Using","n_jobs",">","1","for","small","models","or","datasets","might","be","slower",".","batch_size",":","int","(","default",":","1000",")","Number","of","data","used","to","compute","weights","in","a","batch",".","seed",":","int","The","random","seed","to","use","for","generating","the","intial","values",".","show_progress",":","boolean","(","default",":","True",")","Whether","to","show","a","progress","bar","for","iterations",".","Returns","--","--","--","-","Estimated","paramters","(","CPDs",")",":","list","A","list","of","estimated","CPDs","for","the","model",".","Examples","--","--","--","--",">",">",">","import","numpy","as","np",">",">",">","import","pandas","as","pd",">",">",">","from","pgmpy.models","import","BayesianNetwork",">",">",">","from","pgmpy.estimators","import","ExpectationMaximization","as","EM",">",">",">","data","=","pd.DataFrame","(","np.random.randint","(","low=0",",","high=2",",","size=","(","1000",",","3",")",")",",","...","columns=","[","'","A","'",",","'","C","'",",","'D","'","]",")",">",">",">","model","=","BayesianNetwork","(","[","(","'","A","'",",","'","B","'",")",",","(","'","C","'",",","'","B","'",")",",","(","'","C","'",",","'D","'",")","]",",","latents=","{","'","B","'","}",")",">",">",">","estimator","=","EM","(","model",",","data",")",">",">",">","estimator.get_parameters","(","latent_card=","{","'","B","'",":","3","}",")","[","<","TabularCPD","representing","P","(","C:2",")","at","0x7f7b534251d0",">",",","<","TabularCPD","representing","P","(","B:3","|","C:2",",","A:2",")","at","0x7f7b4dfd4da0",">",",","<","TabularCPD","representing","P","(","A:2",")","at","0x7f7b4dfd4fd0",">",",","<","TabularCPD","representing","P","(","D:2","|","C:2",")","at","0x7f7b4df822b0",">","]"]
code: def get_parameters(
      self,
      latent_card=None,
      max_iter=100,
      atol=1e-08,
      n_jobs=1,
      batch_size=1000,
      seed=None,
      show_progress=True,
  ):
      """
      Method to estimate all model parameters (CPDs) using Expecation Maximization.
  
      Parameters
      ----------
      latent_card: dict (default: None)
          A dictionary of the form {latent_var: cardinality} specifying the
          cardinality (number of states) of each latent variable. If None,
          assumes `2` states for each latent variable.
  
      max_iter: int (default: 100)
          The maximum number of iterations the algorithm is allowed to run for.
          If max_iter is reached, return the last value of parameters.
  
      atol: int (default: 1e-08)
          The absolute accepted tolerance for checking convergence. If the parameters
          change is less than atol in an iteration, the algorithm will exit.
  
      n_jobs: int (default: 1)
          Number of jobs to run in parallel.
          Using n_jobs > 1 for small models or datasets might be slower.
  
      batch_size: int (default: 1000)
          Number of data used to compute weights in a batch.
  
      seed: int
          The random seed to use for generating the intial values.
  
      show_progress: boolean (default: True)
          Whether to show a progress bar for iterations.
  
      Returns
      -------
      Estimated paramters (CPDs): list
          A list of estimated CPDs for the model.
  
      Examples
      --------
      >>> import numpy as np
      >>> import pandas as pd
      >>> from pgmpy.models import BayesianNetwork
      >>> from pgmpy.estimators import ExpectationMaximization as EM
      >>> data = pd.DataFrame(np.random.randint(low=0, high=2, size=(1000, 3)),
      ...                       columns=['A', 'C', 'D'])
      >>> model = BayesianNetwork([('A', 'B'), ('C', 'B'), ('C', 'D')], latents={'B'})
      >>> estimator = EM(model, data)
      >>> estimator.get_parameters(latent_card={'B': 3})
      [<TabularCPD representing P(C:2) at 0x7f7b534251d0>,
      <TabularCPD representing P(B:3 | C:2, A:2) at 0x7f7b4dfd4da0>,
      <TabularCPD representing P(A:2) at 0x7f7b4dfd4fd0>,
      <TabularCPD representing P(D:2 | C:2) at 0x7f7b4df822b0>]
      """
      # Step 1: Parameter checks
      if latent_card is None:
          latent_card = {var: 2 for var in self.model_copy.latents}
  
      # Step 2: Create structures/variables to be used later.
      n_states_dict = {
          key: len(value) for key, value in self.state_names.items()
      }
      n_states_dict.update(latent_card)
      for var in self.model_copy.latents:
          self.state_names[var] = list(range(n_states_dict[var]))
  
      # Step 3: Initialize CPDs.
      # Step 3.1: Learn the CPDs of variables which don't involve
      #           latent variables using MLE.
      fixed_cpds = []
      fixed_cpd_vars = (
          set(self.model.nodes())
          - self.model.latents
          - set(
              chain(
                  *[
                      self.model.get_children(var)
                      for var in self.model.latents
                  ]
              )
          )
      )
  
      mle = MaximumLikelihoodEstimator.__new__(
          MaximumLikelihoodEstimator
      )
      mle.model = self.model
      mle.data = self.data
      mle.state_names = self.state_names
  
      for var in fixed_cpd_vars:
          fixed_cpds.append(mle.estimate_cpd(var))
  
      # Step 3.2: Randomly initialize the CPDs involving latent variables.
      latent_cpds = []
      vars_with_latents = set(self.model_copy.nodes()) - fixed_cpd_vars
      for node in vars_with_latents:
          parents = list(self.model_copy.predecessors(node))
          latent_cpds.append(
              TabularCPD.get_random(
                  variable=node,
                  evidence=parents,
                  cardinality={
                      var: n_states_dict[var]
                      for var in chain([node], parents)
                  },
                  state_names={
                      var: self.state_names[var]
                      for var in chain([node], parents)
                  },
                  seed=seed,
              )
          )
  
      self.model_copy.add_cpds(*list(chain(fixed_cpds, latent_cpds)))
  
      if show_progress and config.SHOW_PROGRESS:
          pbar = tqdm(total=max_iter)
  
      mle.model = self.model_copy
      # Step 4: Run the EM algorithm.
      for _ in range(max_iter):
          # Step 4.1: E-step: Expands the dataset and computes the likelihood of each
          #           possible state of latent variables.
          weighted_data = self._compute_weights(
              n_jobs, latent_card, batch_size
          )
          # Step 4.2: M-step: Uses the weights of the dataset to do a weighted MLE.
          new_cpds = fixed_cpds.copy()
          mle.data = weighted_data
          # mle = MaximumLikelihoodEstimator(self.model_copy, weighted_data)
          for var in vars_with_latents:
              new_cpds.append(mle.estimate_cpd(var, weighted=True))
  
          # Step 4.3: Check of convergence and max_iter
          if self._is_converged(new_cpds, atol=atol):
              if show_progress and config.SHOW_PROGRESS:
                  pbar.close()
              return new_cpds
  
          else:
              self.model_copy.cpds = new_cpds
              if show_progress and config.SHOW_PROGRESS:
                  pbar.update(1)
  
      return new_cpds
  
file_path: pgmpy/pgmpy/estimators/EM.py
imports: from itertools import chain, product
  from math import log
  import numpy
  import pandas
  from joblib import Parallel, delayed
  from tqdm.auto import tqdm
  from pgmpy import config
  from pgmpy.estimators import MaximumLikelihoodEstimator, ParameterEstimator
  from pgmpy.factors.discrete import TabularCPD
  from pgmpy.models import BayesianNetwork
label_desc: Use image node_id 6 for calling the ExpectationMaximization obj's underlying member method code with example usage: obj.get_parameters(latent_card, max_iter, atol, n_jobs, batch_size, seed, show_progress) and returns: new_cpds, new_cpds