class_docstr: Base class for graphical representation of Structural Equation Models(SEMs).
  
  All variables are by default assumed to have an associated error latent variable, therefore
  doesn't need to be specified.
  
  Parameters
  ----------
  ebunch: list/array-like
      List of edges in form of tuples. Each tuple can be of two possible shape:
          1. (u, v): This would add an edge from u to v without setting any parameter
                     for the edge.
          2. (u, v, parameter): This would add an edge from u to v and set the edge's
                      parameter to `parameter`.
  
  latents: list/array-like
      List of nodes which are latent. All other variables are considered observed.
  
  err_corr: list/array-like
      List of tuples representing edges between error terms. It can be of the following forms:
          1. (u, v): Add correlation between error terms of `u` and `v`. Doesn't set any variance or
                     covariance values.
          2. (u, v, covar): Adds correlation between the error terms of `u` and `v` and sets the
                            parameter to `covar`.
  
  err_var: dict (variable: variance)
      Sets variance for the error terms in the model.
  
  Examples
  --------
  Defining a model (Union sentiment model[1]) without setting any paramaters.
  >>> from pgmpy.models import SEMGraph
  >>> sem = SEMGraph(ebunch=[('deferenc', 'unionsen'), ('laboract', 'unionsen'),
  ...                        ('yrsmill', 'unionsen'), ('age', 'deferenc'),
  ...                        ('age', 'laboract'), ('deferenc', 'laboract')],
  ...                latents=[],
  ...                err_corr=[('yrsmill', 'age')],
  ...                err_var={})
  
  Defining a model (Education [2]) with all the parameters set. For not setting any
  parameter `np.NaN` can be explicitly passed.
  >>> sem_edu = SEMGraph(ebunch=[('intelligence', 'academic', 0.8), ('intelligence', 'scale_1', 0.7),
  ...                            ('intelligence', 'scale_2', 0.64), ('intelligence', 'scale_3', 0.73),
  ...                            ('intelligence', 'scale_4', 0.82), ('academic', 'SAT_score', 0.98),
  ...                            ('academic', 'High_school_gpa', 0.75), ('academic', 'ACT_score', 0.87)],
  ...                    latents=['intelligence', 'academic'],
  ...                    err_corr=[],
  ...                    err_var={'intelligence': 1})
  
  References
  ----------
  [1] McDonald, A, J., & Clelland, D. A. (1984). Textile Workers and Union Sentiment.
      Social Forces, 63(2), 502–521
  [2] https://en.wikipedia.org/wiki/Structural_equation_modeling#/
      media/File:Example_Structural_equation_model.svg
  
  Attributes
  ----------
  latents: list
      List of all the latent variables in the model except the error terms.
  
  observed: list
      List of all the observed variables in the model.
  
  graph: nx.DirectedGraph
      The graphical structure of the latent and observed variables except the error terms.
      The parameters are stored in the `weight` attribute of each edge.
  
  err_graph: nx.Graph
      An undirected graph representing the relations between the error terms of the model.
      The node of the graph has the same name as the variable but represents the error terms.
      The variance is stored in the `weight` attribute of the node and the covariance are stored
      in the `weight` attribute of the edge.
  
  full_graph_struct: nx.DiGraph
      Represents the full graph structure. The names of error terms start with `.` and
      new nodes are added for each correlation which starts with `..`.
class_docstr_tok: ["Base","class","for","graphical","representation","of","Structural","Equation","Models","(","SEMs",")",".","All","variables","are","by","default","assumed","to","have","an","associated","error","latent","variable",",","therefore","does","n't","need","to","be","specified",".","Parameters","--","--","--","--","--","ebunch",":","list\/array-like","List","of","edges","in","form","of","tuples",".","Each","tuple","can","be","of","two","possible","shape",":","1",".","(","u",",","v",")",":","This","would","add","an","edge","from","u","to","v","without","setting","any","parameter","for","the","edge",".","2",".","(","u",",","v",",","parameter",")",":","This","would","add","an","edge","from","u","to","v","and","set","the","edge's","parameter","to","`","parameter","`",".","latents",":","list\/array-like","List","of","nodes","which","are","latent",".","All","other","variables","are","considered","observed",".","err_corr",":","list\/array-like","List","of","tuples","representing","edges","between","error","terms",".","It","can","be","of","the","following","forms",":","1",".","(","u",",","v",")",":","Add","correlation","between","error","terms","of","`","u","`","and","`","v","`",".","Does","n't","set","any","variance","or","covariance","values",".","2",".","(","u",",","v",",","covar",")",":","Adds","correlation","between","the","error","terms","of","`","u","`","and","`","v","`","and","sets","the","parameter","to","`","covar","`",".","err_var",":","dict","(","variable",":","variance",")","Sets","variance","for","the","error","terms","in","the","model",".","Examples","--","--","--","--","Defining","a","model","(","Union","sentiment","model","[","1","]",")","without","setting","any","paramaters",".",">",">",">","from","pgmpy.models","import","SEMGraph",">",">",">","sem","=","SEMGraph","(","ebunch=","[","(","'deferenc","'",",","'unionsen","'",")",",","(","'laboract","'",",","'unionsen","'",")",",","...","(","'yrsmill","'",",","'unionsen","'",")",",","(","'age","'",",","'deferenc","'",")",",","...","(","'age","'",",","'laboract","'",")",",","(","'deferenc","'",",","'laboract","'",")","]",",","...","latents=","[","]",",","...","err_corr=","[","(","'yrsmill","'",",","'age","'",")","]",",","...","err_var=","{","}",")","Defining","a","model","(","Education","[","2","]",")","with","all","the","parameters","set",".","For","not","setting","any","parameter","`","np.NaN","`","can","be","explicitly","passed",".",">",">",">","sem_edu","=","SEMGraph","(","ebunch=","[","(","'intelligence","'",",","'academic","'",",","0.8",")",",","(","'intelligence","'",",","'scale_1","'",",","0.7",")",",","...","(","'intelligence","'",",","'scale_2","'",",","0.64",")",",","(","'intelligence","'",",","'scale_3","'",",","0.73",")",",","...","(","'intelligence","'",",","'scale_4","'",",","0.82",")",",","(","'academic","'",",","'SAT_score","'",",","0.98",")",",","...","(","'academic","'",",","'High_school_gpa","'",",","0.75",")",",","(","'academic","'",",","'ACT_score","'",",","0.87",")","]",",","...","latents=","[","'intelligence","'",",","'academic","'","]",",","...","err_corr=","[","]",",","...","err_var=","{","'intelligence","'",":","1","}",")","References","--","--","--","--","--","[","1","]","McDonald",",","A",",","J.",",","&","Clelland",",","D.","A",".","(","1984",")",".","Textile","Workers","and","Union","Sentiment",".","Social","Forces",",","63","(","2",")",",","502\u2013521","[","2","]","https",":","\/\/en.wikipedia.org\/wiki\/Structural_equation_modeling","#","\/","media\/File",":","Example_Structural_equation_model.svg","Attributes","--","--","--","--","--","latents",":","list","List","of","all","the","latent","variables","in","the","model","except","the","error","terms",".","observed",":","list","List","of","all","the","observed","variables","in","the","model",".","graph",":","nx.DirectedGraph","The","graphical","structure","of","the","latent","and","observed","variables","except","the","error","terms",".","The","parameters","are","stored","in","the","`","weight","`","attribute","of","each","edge",".","err_graph",":","nx.Graph","An","undirected","graph","representing","the","relations","between","the","error","terms","of","the","model",".","The","node","of","the","graph","has","the","same","name","as","the","variable","but","represents","the","error","terms",".","The","variance","is","stored","in","the","`","weight","`","attribute","of","the","node","and","the","covariance","are","stored","in","the","`","weight","`","attribute","of","the","edge",".","full_graph_struct",":","nx.DiGraph","Represents","the","full","graph","structure",".","The","names","of","error","terms","start","with","`",".","`","and","new","nodes","are","added","for","each","correlation","which","starts","with","`","..","`","."]
docstr: Transforms the graph structure of SEM so that the d-separation criterion is
  applicable for finding IVs. The method transforms the graph for finding MIIV
  for the estimation of X 
  ightarrow Y given the scaling indicator for all the
  parent latent variables.
  
  Parameters
  ----------
  X: node
      The explantory variable.
  
  Y: node
      The dependent variable.
  
  scaling_indicators: dict
      Scaling indicator for each latent variable in the model.
  
  Returns
  -------
  nx.DiGraph: The transformed full graph structure.
  
  Examples
  --------
  >>> from pgmpy.models import SEMGraph
  >>> model = SEMGraph(ebunch=[('xi1', 'eta1'), ('xi1', 'x1'), ('xi1', 'x2'),
  ...                          ('eta1', 'y1'), ('eta1', 'y2')],
  ...                  latents=['xi1', 'eta1'])
  >>> model._iv_transformations('xi1', 'eta1',
  ...                           scaling_indicators={'xi1': 'x1', 'eta1': 'y1'})
docstr_tok: ["Transforms","the","graph","structure","of","SEM","so","that","the","d-separation","criterion","is","applicable","for","finding","IVs",".","The","method","transforms","the","graph","for","finding","MIIV","for","the","estimation","of","X","ightarrow","Y","given","the","scaling","indicator","for","all","the","parent","latent","variables",".","Parameters","--","--","--","--","--","X",":","node","The","explantory","variable",".","Y",":","node","The","dependent","variable",".","scaling_indicators",":","dict","Scaling","indicator","for","each","latent","variable","in","the","model",".","Returns","--","--","--","-","nx.DiGraph",":","The","transformed","full","graph","structure",".","Examples","--","--","--","--",">",">",">","from","pgmpy.models","import","SEMGraph",">",">",">","model","=","SEMGraph","(","ebunch=","[","(","'xi1","'",",","'eta1","'",")",",","(","'xi1","'",",","'x1","'",")",",","(","'xi1","'",",","'x2","'",")",",","...","(","'eta1","'",",","'y1","'",")",",","(","'eta1","'",",","'y2","'",")","]",",","...","latents=","[","'xi1","'",",","'eta1","'","]",")",">",">",">","model._iv_transformations","(","'xi1","'",",","'eta1","'",",","...","scaling_indicators=","{","'xi1","'",":","'x1","'",",","'eta1","'",":","'y1","'","}",")"]
code: def _iv_transformations(self, X, Y, scaling_indicators={}):
      """
      Transforms the graph structure of SEM so that the d-separation criterion is
      applicable for finding IVs. The method transforms the graph for finding MIIV
      for the estimation of X \rightarrow Y given the scaling indicator for all the
      parent latent variables.
  
      Parameters
      ----------
      X: node
          The explantory variable.
  
      Y: node
          The dependent variable.
  
      scaling_indicators: dict
          Scaling indicator for each latent variable in the model.
  
      Returns
      -------
      nx.DiGraph: The transformed full graph structure.
  
      Examples
      --------
      >>> from pgmpy.models import SEMGraph
      >>> model = SEMGraph(ebunch=[('xi1', 'eta1'), ('xi1', 'x1'), ('xi1', 'x2'),
      ...                          ('eta1', 'y1'), ('eta1', 'y2')],
      ...                  latents=['xi1', 'eta1'])
      >>> model._iv_transformations('xi1', 'eta1',
      ...                           scaling_indicators={'xi1': 'x1', 'eta1': 'y1'})
      """
      full_graph = self.full_graph_struct.copy()
  
      if not (X, Y) in full_graph.edges():
          raise ValueError(
              f"The edge from {X} -> {Y} doesn't exist in the graph"
          )
  
      if (X in self.observed) and (Y in self.observed):
          full_graph.remove_edge(X, Y)
          return full_graph, Y
  
      elif Y in self.latents:
          full_graph.add_edge("." + Y, scaling_indicators[Y])
          dependent_var = scaling_indicators[Y]
      else:
          dependent_var = Y
  
      for parent_y in self.graph.predecessors(Y):
          # Remove edge even when the parent is observed ????
          full_graph.remove_edge(parent_y, Y)
          if parent_y in self.latents:
              full_graph.add_edge(
                  "." + scaling_indicators[parent_y], dependent_var
              )
  
      return full_graph, dependent_var
  
imports: import itertools
  import networkx
  import numpy
  import pandas
  from networkx.algorithms.dag import descendants
  from pyparsing import OneOrMore, Optional, Suppress, Word, alphanums, nums
  from pgmpy.base import DAG
  from pgmpy.global_vars import logger
label_desc: Use image node_id 5 for calling the SEMGraph obj's underlying member method code with example usage: obj._iv_transformations(X, Y, scaling_indicators) and returns: full_graph,  dependent_var, full_graph,  Y