class_docstr: Represents any parametric distribution that can be modeled by scipy.
docstr: Tries to find the best fitting continuous parametric distribution of given samples. This is done by fitting
  different parametric models and selecting the one with the smallest KL divergence between observed and generated
  samples.
docstr_tok: ["Tries","to","find","the","best","fitting","continuous","parametric","distribution","of","given","samples",".","This","is","done","by","fitting","different","parametric","models","and","selecting","the","one","with","the","smallest","KL","divergence","between","observed","and","generated","samples","."]
code: def find_suitable_continuous_distribution(
      distribution_samples: np.ndarray,
      divergence_threshold: float = 10**-2,
  ) -> Tuple[rv_continuous, Dict[str, float]]:
      """Tries to find the best fitting continuous parametric distribution of given samples. This is done by fitting
      different parametric models and selecting the one with the smallest KL divergence between observed and generated
      samples.
      """
      distribution_samples = shape_into_2d(distribution_samples)
  
      currently_best_distribution = norm
      currently_best_parameters = (0.0, 1.0)
      currently_smallest_divergence = np.inf
  
      # Estimate distribution parameters from data.
      for distribution in _CONTINUOUS_DISTRIBUTIONS.values():
          # Ignore warnings from fitting process.
          with warnings.catch_warnings():
              warnings.filterwarnings("ignore")
  
              try:
                  # Fit distribution to data.
                  params = distribution.fit(distribution_samples)
              except ValueError:
                  # Some distributions might not be compatible with the data.
                  continue
  
              # Separate parts of parameters.
              arg = params[:-2]
              loc = params[-2]
              scale = params[-1]
  
              generated_samples = distribution.rvs(
                  size=distribution_samples.shape[0],
                  loc=loc,
                  scale=scale,
                  *arg,
              )
  
              # Check the KL divergence between the distribution of the given and fitted distribution.
              from dowhy.gcm.divergence import (
                  estimate_kl_divergence_continuous_knn,
              )
  
              divergence = estimate_kl_divergence_continuous_knn(
                  distribution_samples, generated_samples
              )
              if divergence < divergence_threshold:
                  currently_best_distribution = distribution
                  currently_best_parameters = params
                  break
  
              # Identify if this distribution is better.
              if currently_smallest_divergence > divergence:
                  currently_best_distribution = distribution
                  currently_best_parameters = params
                  currently_smallest_divergence = divergence
  
      return (
          currently_best_distribution,
          ScipyDistribution.map_scipy_distribution_parameters_to_names(
              currently_best_distribution, currently_best_parameters
          ),
      )
  
imports: import warnings
  from typing import Dict, Optional, Tuple, Union
  import numpy
  import scipy
  from scipy.stats import norm, rv_continuous, rv_discrete
  from sklearn.cluster import KMeans
  from sklearn.metrics import silhouette_score
  from sklearn.mixture import BayesianGaussianMixture
  from dowhy.gcm.causal_mechanisms import StochasticModel
  from dowhy.gcm.util.general import shape_into_2d
label_desc: Use image node_id 7 for calling the ScipyDistribution obj's underlying member method code with example usage: obj.find_suitable_continuous_distribution(distribution_samples, divergence_threshold) and returns: currently_best_distribution,  ScipyDistribution