class_docstr: This class uses Expectation-Maximization to learn parameters of a single latent variable in a bayesian network.
  We do so by also allowing the user to CONSTRAINT the optimisation
  These are elements that help the algorithm find a local optimal point closer to the point we think
  
  The setting is:
  Input:
      - a StructureModel representing the whole network or any sub-graph containing the Markov Blanket of the LV
      - data as a dataframe. The LV must be in the dataframe, with missing values represented by `np.nan`s
      - constraints:
          - Box - A hard constraint; forbids the solution to be outside of certain boundaries
          - Priors - establishes Dirichlet priors to every parameter
  run:
      - using the method `run` or manually alternating over E and M steps)
  Result:
      - CPTs involving the latent variable, learnt by EM, found in the attribute `cpds`
      - CPTs not involving the LV not learned (They must be learned separately by MLE.
      This is faster and the result is the same)
  
  Example:
  >>> em = EMSingleLatentVariable(sm=sm, data=data, lv_name=lv_name, node_states=node_states)
  >>> em.run() # run EM until convergence
  >>> # or run E and M steps separately
  >>> for i in range(10): # Run EM 10 times
  >>>     em.e_step()
  >>>     em.m_step()
docstr: Checks initial parameter dictionary
  
  Raises:
      ValueError: when the initial parameter dictionary keys are different from valid nodes, or
          when the CPD provided in the initial parameter dictionary has incorrect format
docstr_tok: ["Checks","initial","parameter","dictionary","Raises",":","ValueError",":","when","the","initial","parameter","dictionary","keys","are","different","from","valid","nodes",",","or","when","the","CPD","provided","in","the","initial","parameter","dictionary","has","incorrect","format"]
code: def _check_initial_params_dict(self):
      """
      Checks initial parameter dictionary
  
      Raises:
          ValueError: when the initial parameter dictionary keys are different from valid nodes, or
              when the CPD provided in the initial parameter dictionary has incorrect format
      """
      if sorted(self.valid_nodes) != sorted(self.initial_params.keys()):
          raise ValueError(
              "If `initial_params` is a dictionary, it has to map `valid nodes` to "
              "corresponding CPTs. A valid node is : L.V. or Successors(L.V.)"
          )
      for node in self.valid_nodes:
          df = self.initial_params[node]
          check = (
              isinstance(df, pd.DataFrame)
              and (df.index.name == node)
              and (list(df.index) == self.node_states[node])
          )
          check = check and (
              (
                  np.all(df.columns == "")
                  and (not self.sm.predecessors(node))
              )
              or (df.columns.names == list(self.sm.predecessors(node)))
          )
          if not check:  # pragma: no cover
              raise ValueError(
                  "CPTs provided in `initial_params` do not correspond to the expected format"
              )
  
imports: import logging
  import os
  from time import time
  from typing import Dict, List, Tuple, Union
  import numpy
  import pandas
  from joblib import Parallel, delayed
  from causalnex.structure import StructureModel
  from causalnex.utils.data_utils import chunk_data, count_unique_rows
  from causalnex.utils.pgmpy_utils import cpd_multiplication
label_desc: Use image node_id 18 for calling the EMSingleLatentVariable obj's underlying member method code with example usage: obj._check_initial_params_dict() without return types