class_docstr: Class for sampling methods specific to Bayesian Models
  
  Parameters
  ----------
  model: instance of BayesianNetwork
      model on which inference queries will be computed
class_docstr_tok: ["Class","for","sampling","methods","specific","to","Bayesian","Models","Parameters","--","--","--","--","--","model",":","instance","of","BayesianNetwork","model","on","which","inference","queries","will","be","computed"]
docstr: Generates weighted sample(s) from joint distribution of the Bayesian
  Network, that comply with the given evidence.
  'Probabilistic Graphical Model Principles and Techniques', Koller and
  Friedman, Algorithm 12.2 pp 493.
  
  Parameters
  ----------
  evidence: list of `pgmpy.factor.State` namedtuples
      None if no evidence
  
  size: int
      size of sample to be generated
  
  include_latents: boolean
      Whether to include the latent variable values in the generated samples.
  
  seed: int (default: None)
      If a value is provided, sets the seed for numpy.random.
  
  show_progress: boolean
      Whether to show a progress bar of samples getting generated.
  
  n_jobs: int (default: -1)
      The number of CPU cores to use. Default uses all cores.
  
  Returns
  -------
  sampled: A pandas.DataFrame
      The generated samples with corresponding weights
  
  Examples
  --------
  >>> from pgmpy.factors.discrete import State
  >>> from pgmpy.models import BayesianNetwork
  >>> from pgmpy.factors.discrete import TabularCPD
  >>> from pgmpy.sampling import BayesianModelSampling
  >>> student = BayesianNetwork([('diff', 'grade'), ('intel', 'grade')])
  >>> cpd_d = TabularCPD('diff', 2, [[0.6], [0.4]])
  >>> cpd_i = TabularCPD('intel', 2, [[0.7], [0.3]])
  >>> cpd_g = TabularCPD('grade', 3, [[0.3, 0.05, 0.9, 0.5], [0.4, 0.25,
  ...         0.08, 0.3], [0.3, 0.7, 0.02, 0.2]],
  ...         ['intel', 'diff'], [2, 2])
  >>> student.add_cpds(cpd_d, cpd_i, cpd_g)
  >>> inference = BayesianModelSampling(student)
  >>> evidence = [State('diff', 0)]
  >>> inference.likelihood_weighted_sample(evidence=evidence, size=2, return_type='recarray')
  rec.array([(0, 0, 1, 0.6), (0, 0, 2, 0.6)], dtype=
            [('diff', '<i8'), ('intel', '<i8'), ('grade', '<i8'), ('_weight', '<f8')])
docstr_tok: ["Generates","weighted","sample","(","s",")","from","joint","distribution","of","the","Bayesian","Network",",","that","comply","with","the","given","evidence",".","'Probabilistic","Graphical","Model","Principles","and","Techniques","'",",","Koller","and","Friedman",",","Algorithm","12.2","pp","493",".","Parameters","--","--","--","--","--","evidence",":","list","of","`","pgmpy.factor.State","`","namedtuples","None","if","no","evidence","size",":","int","size","of","sample","to","be","generated","include_latents",":","boolean","Whether","to","include","the","latent","variable","values","in","the","generated","samples",".","seed",":","int","(","default",":","None",")","If","a","value","is","provided",",","sets","the","seed","for","numpy.random",".","show_progress",":","boolean","Whether","to","show","a","progress","bar","of","samples","getting","generated",".","n_jobs",":","int","(","default",":","-1",")","The","number","of","CPU","cores","to","use",".","Default","uses","all","cores",".","Returns","--","--","--","-","sampled",":","A","pandas.DataFrame","The","generated","samples","with","corresponding","weights","Examples","--","--","--","--",">",">",">","from","pgmpy.factors.discrete","import","State",">",">",">","from","pgmpy.models","import","BayesianNetwork",">",">",">","from","pgmpy.factors.discrete","import","TabularCPD",">",">",">","from","pgmpy.sampling","import","BayesianModelSampling",">",">",">","student","=","BayesianNetwork","(","[","(","'diff","'",",","'grade","'",")",",","(","'intel","'",",","'grade","'",")","]",")",">",">",">","cpd_d","=","TabularCPD","(","'diff","'",",","2",",","[","[","0.6","]",",","[","0.4","]","]",")",">",">",">","cpd_i","=","TabularCPD","(","'intel","'",",","2",",","[","[","0.7","]",",","[","0.3","]","]",")",">",">",">","cpd_g","=","TabularCPD","(","'grade","'",",","3",",","[","[","0.3",",","0.05",",","0.9",",","0.5","]",",","[","0.4",",","0.25",",","...","0.08",",","0.3","]",",","[","0.3",",","0.7",",","0.02",",","0.2","]","]",",","...","[","'intel","'",",","'diff","'","]",",","[","2",",","2","]",")",">",">",">","student.add_cpds","(","cpd_d",",","cpd_i",",","cpd_g",")",">",">",">","inference","=","BayesianModelSampling","(","student",")",">",">",">","evidence","=","[","State","(","'diff","'",",","0",")","]",">",">",">","inference.likelihood_weighted_sample","(","evidence=evidence",",","size=2",",","return_type='recarray","'",")","rec.array","(","[","(","0",",","0",",","1",",","0.6",")",",","(","0",",","0",",","2",",","0.6",")","]",",","dtype=","[","(","'diff","'",",","'","<","i8","'",")",",","(","'intel","'",",","'","<","i8","'",")",",","(","'grade","'",",","'","<","i8","'",")",",","(","'_weight","'",",","'","<","f8","'",")","]",")"]
code: def likelihood_weighted_sample(
      self,
      evidence=[],
      size=1,
      include_latents=False,
      seed=None,
      show_progress=True,
      n_jobs=-1,
  ):
      """
      Generates weighted sample(s) from joint distribution of the Bayesian
      Network, that comply with the given evidence.
      'Probabilistic Graphical Model Principles and Techniques', Koller and
      Friedman, Algorithm 12.2 pp 493.
  
      Parameters
      ----------
      evidence: list of `pgmpy.factor.State` namedtuples
          None if no evidence
  
      size: int
          size of sample to be generated
  
      include_latents: boolean
          Whether to include the latent variable values in the generated samples.
  
      seed: int (default: None)
          If a value is provided, sets the seed for numpy.random.
  
      show_progress: boolean
          Whether to show a progress bar of samples getting generated.
  
      n_jobs: int (default: -1)
          The number of CPU cores to use. Default uses all cores.
  
      Returns
      -------
      sampled: A pandas.DataFrame
          The generated samples with corresponding weights
  
      Examples
      --------
      >>> from pgmpy.factors.discrete import State
      >>> from pgmpy.models import BayesianNetwork
      >>> from pgmpy.factors.discrete import TabularCPD
      >>> from pgmpy.sampling import BayesianModelSampling
      >>> student = BayesianNetwork([('diff', 'grade'), ('intel', 'grade')])
      >>> cpd_d = TabularCPD('diff', 2, [[0.6], [0.4]])
      >>> cpd_i = TabularCPD('intel', 2, [[0.7], [0.3]])
      >>> cpd_g = TabularCPD('grade', 3, [[0.3, 0.05, 0.9, 0.5], [0.4, 0.25,
      ...         0.08, 0.3], [0.3, 0.7, 0.02, 0.2]],
      ...         ['intel', 'diff'], [2, 2])
      >>> student.add_cpds(cpd_d, cpd_i, cpd_g)
      >>> inference = BayesianModelSampling(student)
      >>> evidence = [State('diff', 0)]
      >>> inference.likelihood_weighted_sample(evidence=evidence, size=2, return_type='recarray')
      rec.array([(0, 0, 1, 0.6), (0, 0, 2, 0.6)], dtype=
                [('diff', '<i8'), ('intel', '<i8'), ('grade', '<i8'), ('_weight', '<f8')])
      """
      if seed is not None:
          np.random.seed(seed)
  
      # Convert evidence state names to number
      evidence = [
          (var, self.model.get_cpds(var).get_state_no(var, state))
          for var, state in evidence
      ]
  
      # Prepare the return dataframe
      sampled = pd.DataFrame(columns=list(self.model.nodes()))
      sampled["_weight"] = np.ones(size)
      evidence_dict = dict(evidence)
  
      if show_progress and config.SHOW_PROGRESS:
          pbar = tqdm(self.topological_order)
      else:
          pbar = self.topological_order
  
      # Do the sampling
      for node in pbar:
          if show_progress and config.SHOW_PROGRESS:
              pbar.set_description(f"Generating for node: {node}")
  
          cpd = self.model.get_cpds(node)
          states = range(self.cardinality[node])
          evidence = cpd.get_evidence()
  
          if evidence:
              evidence_values = np.vstack(
                  [sampled[i] for i in evidence]
              )
  
              unique, inverse = np.unique(
                  evidence_values.T, axis=0, return_inverse=True
              )
              unique = [tuple(u) for u in unique]
              (
                  state_to_index,
                  index_to_weight,
              ) = self.pre_compute_reduce_maps(
                  variable=node,
                  evidence=evidence,
                  state_combinations=unique,
              )
              weight_index = np.array(
                  [state_to_index[tuple(u)] for u in unique]
              )[inverse]
  
              if node in evidence_dict:
                  evidence_value = evidence_dict[node]
                  sampled[node] = evidence_value
                  sampled.loc[:, "_weight"] *= np.array(
                      list(
                          map(
                              lambda i: index_to_weight[
                                  weight_index[i]
                              ][evidence_value],
                              range(size),
                          )
                      )
                  )
              else:
                  sampled[node] = sample_discrete_maps(
                      states, weight_index, index_to_weight, size
                  )
          else:
              if node in evidence_dict:
                  sampled[node] = evidence_dict[node]
                  sampled.loc[:, "_weight"] *= np.array(
                      list(
                          map(
                              lambda _: cpd.values[evidence_dict[node]],
                              range(size),
                          )
                      )
                  )
              else:
                  sampled[node] = sample_discrete(
                      states, cpd.values, size
                  )
  
      # Postprocess the samples: Change state numbers to names, remove latents.
      samples_df = _return_samples(sampled, self.state_names_map)
      if not include_latents:
          samples_df.drop(self.model.latents, axis=1, inplace=True)
      return samples_df
  
imports: import itertools
  from collections import namedtuple
  import networkx
  import numpy
  import pandas
  import torch
  from joblib import Parallel, delayed
  from tqdm.auto import tqdm
  from pgmpy import config
  from pgmpy.factors import factor_product
  from pgmpy.models import BayesianNetwork, MarkovChain, MarkovNetwork
  from pgmpy.sampling import BayesianModelInference, _return_samples
  from pgmpy.utils.mathext import sample_discrete, sample_discrete_maps
label_desc: Use image node_id 4 for calling the BayesianModelSampling obj's underlying member method code with example usage: obj.likelihood_weighted_sample(evidence, size, include_latents, seed, show_progress, n_jobs) and returns: samples_df