class_docstr: Variational Inference for the Infinite Gaussian Mixture Model.
  
  DPGMM stands for Dirichlet Process Gaussian Mixture Model, and it
  is an infinite mixture model with the Dirichlet Process as a prior
  distribution on the number of clusters. In practice the
  approximate inference algorithm uses a truncated distribution with
  a fixed maximum number of components, but almost always the number
  of components actually used depends on the data.
  
  Stick-breaking Representation of a Gaussian mixture model
  probability distribution. This class allows for easy and efficient
  inference of an approximate posterior distribution over the
  parameters of a Gaussian mixture model with a variable number of
  components (smaller than the truncation parameter n_components).
  
  Initialization is with normally-distributed means and identity
  covariance, for proper convergence.
  
  Read more in the :ref:`User Guide <dpgmm>`.
  
  Parameters
  ----------
  n_components: int, default 1
      Number of mixture components.
  
  covariance_type: string, default 'diag'
      String describing the type of covariance parameters to
      use.  Must be one of 'spherical', 'tied', 'diag', 'full'.
  
  alpha: float, default 1
      Real number representing the concentration parameter of
      the dirichlet process. Intuitively, the Dirichlet Process
      is as likely to start a new cluster for a point as it is
      to add that point to a cluster with alpha elements. A
      higher alpha means more clusters, as the expected number
      of clusters is ``alpha*log(N)``.
  
  tol : float, default 1e-3
      Convergence threshold.
  
  n_iter : int, default 10
      Maximum number of iterations to perform before convergence.
  
  params : string, default 'wmc'
      Controls which parameters are updated in the training
      process.  Can contain any combination of 'w' for weights,
      'm' for means, and 'c' for covars.
  
  init_params : string, default 'wmc'
      Controls which parameters are updated in the initialization
      process.  Can contain any combination of 'w' for weights,
      'm' for means, and 'c' for covars.  Defaults to 'wmc'.
  
  verbose : int, default 0
      Controls output verbosity.
  
  Attributes
  ----------
  covariance_type : string
      String describing the type of covariance parameters used by
      the DP-GMM.  Must be one of 'spherical', 'tied', 'diag', 'full'.
  
  n_components : int
      Number of mixture components.
  
  weights_ : array, shape (`n_components`,)
      Mixing weights for each mixture component.
  
  means_ : array, shape (`n_components`, `n_features`)
      Mean parameters for each mixture component.
  
  precs_ : array
      Precision (inverse covariance) parameters for each mixture
      component.  The shape depends on `covariance_type`::
  
          (`n_components`, 'n_features')                if 'spherical',
          (`n_features`, `n_features`)                  if 'tied',
          (`n_components`, `n_features`)                if 'diag',
          (`n_components`, `n_features`, `n_features`)  if 'full'
  
  converged_ : bool
      True when convergence was reached in fit(), False otherwise.
  
  See Also
  --------
  GMM : Finite Gaussian mixture model fit with EM
  
  VBGMM : Finite Gaussian mixture model fit with a variational
      algorithm, better for situations where there might be too little
      data to get a good estimate of the covariance matrix.
docstr: Estimate model parameters with the variational
  algorithm.
  
  For a full derivation and description of the algorithm see
  doc/modules/dp-derivation.rst
  or
  http://scikit-learn.org/stable/modules/dp-derivation.html
  
  A initialization step is performed before entering the em
  algorithm. If you want to avoid this step, set the keyword
  argument init_params to the empty string '' when creating
  the object. Likewise, if you would like just to do an
  initialization, set n_iter=0.
  
  Parameters
  ----------
  X : array_like, shape (n, n_features)
      List of n_features-dimensional data points.  Each row
      corresponds to a single data point.
  
  Returns
  -------
  responsibilities : array, shape (n_samples, n_components)
      Posterior probabilities of each mixture component for each
      observation.
docstr_tok: ["Estimate","model","parameters","with","the","variational","algorithm",".","For","a","full","derivation","and","description","of","the","algorithm","see","doc\/modules\/dp-derivation.rst","or","http",":","\/\/scikit-learn.org\/stable\/modules\/dp-derivation.html","A","initialization","step","is","performed","before","entering","the","em","algorithm",".","If","you","want","to","avoid","this","step",",","set","the","keyword","argument","init_params","to","the","empty","string","``","when","creating","the","object",".","Likewise",",","if","you","would","like","just","to","do","an","initialization",",","set","n_iter=0",".","Parameters","--","--","--","--","--","X",":","array_like",",","shape","(","n",",","n_features",")","List","of","n_features-dimensional","data","points",".","Each","row","corresponds","to","a","single","data","point",".","Returns","--","--","--","-","responsibilities",":","array",",","shape","(","n_samples",",","n_components",")","Posterior","probabilities","of","each","mixture","component","for","each","observation","."]
code: def _fit(self, X, y=None):
      """Estimate model parameters with the variational
      algorithm.
  
      For a full derivation and description of the algorithm see
      doc/modules/dp-derivation.rst
      or
      http://scikit-learn.org/stable/modules/dp-derivation.html
  
      A initialization step is performed before entering the em
      algorithm. If you want to avoid this step, set the keyword
      argument init_params to the empty string '' when creating
      the object. Likewise, if you would like just to do an
      initialization, set n_iter=0.
  
      Parameters
      ----------
      X : array_like, shape (n, n_features)
          List of n_features-dimensional data points.  Each row
          corresponds to a single data point.
  
      Returns
      -------
      responsibilities : array, shape (n_samples, n_components)
          Posterior probabilities of each mixture component for each
          observation.
      """
      self.random_state_ = check_random_state(self.random_state)
  
      # initialization step
      X = check_array(X)
      if X.ndim == 1:
          X = X[:, np.newaxis]
  
      n_samples, n_features = X.shape
      z = np.ones((n_samples, self.n_components))
      z /= self.n_components
  
      self._initial_bound = -0.5 * n_features * np.log(2 * np.pi)
      self._initial_bound -= np.log(2 * np.pi * np.e)
  
      if (self.init_params != "") or not hasattr(self, "gamma_"):
          self._initialize_gamma()
  
      if "m" in self.init_params or not hasattr(self, "means_"):
          self.means_ = (
              cluster.KMeans(
                  n_clusters=self.n_components,
                  random_state=self.random_state_,
              )
              .fit(X)
              .cluster_centers_[::-1]
          )
  
      if "w" in self.init_params or not hasattr(self, "weights_"):
          self.weights_ = np.tile(
              1.0 / self.n_components, self.n_components
          )
  
      if "c" in self.init_params or not hasattr(self, "precs_"):
          if self.covariance_type == "spherical":
              self.dof_ = np.ones(self.n_components)
              self.scale_ = np.ones(self.n_components)
              self.precs_ = np.ones((self.n_components, n_features))
              self.bound_prec_ = (
                  0.5
                  * n_features
                  * (digamma(self.dof_) - np.log(self.scale_))
              )
          elif self.covariance_type == "diag":
              self.dof_ = 1 + 0.5 * n_features
              self.dof_ *= np.ones((self.n_components, n_features))
              self.scale_ = np.ones((self.n_components, n_features))
              self.precs_ = np.ones((self.n_components, n_features))
              self.bound_prec_ = 0.5 * (
                  np.sum(digamma(self.dof_) - np.log(self.scale_), 1)
              )
              self.bound_prec_ -= 0.5 * np.sum(self.precs_, 1)
          elif self.covariance_type == "tied":
              self.dof_ = 1.0
              self.scale_ = np.identity(n_features)
              self.precs_ = np.identity(n_features)
              self.det_scale_ = 1.0
              self.bound_prec_ = 0.5 * wishart_log_det(
                  self.dof_, self.scale_, self.det_scale_, n_features
              )
              self.bound_prec_ -= (
                  0.5 * self.dof_ * np.trace(self.scale_)
              )
          elif self.covariance_type == "full":
              self.dof_ = 1 + self.n_components + n_samples
              self.dof_ *= np.ones(self.n_components)
              self.scale_ = [
                  2 * np.identity(n_features)
                  for _ in range(self.n_components)
              ]
              self.precs_ = [
                  np.identity(n_features)
                  for _ in range(self.n_components)
              ]
              self.det_scale_ = np.ones(self.n_components)
              self.bound_prec_ = np.zeros(self.n_components)
              for k in range(self.n_components):
                  self.bound_prec_[k] = wishart_log_det(
                      self.dof_[k],
                      self.scale_[k],
                      self.det_scale_[k],
                      n_features,
                  )
                  self.bound_prec_[k] -= self.dof_[k] * np.trace(
                      self.scale_[k]
                  )
              self.bound_prec_ *= 0.5
  
      # EM algorithms
      current_log_likelihood = None
      # reset self.converged_ to False
      self.converged_ = False
  
      for i in range(self.n_iter):
          prev_log_likelihood = current_log_likelihood
          # Expectation step
          curr_logprob, z = self.score_samples(X)
  
          current_log_likelihood = (
              curr_logprob.mean() + self._logprior(z) / n_samples
          )
  
          # Check for convergence.
          if prev_log_likelihood is not None:
              change = abs(current_log_likelihood - prev_log_likelihood)
              if change < self.tol:
                  self.converged_ = True
                  break
  
          # Maximization step
          self._do_mstep(X, z, self.params)
  
      if self.n_iter == 0:
          # Need to make sure that there is a z value to output
          # Output zeros because it was just a quick initialization
          z = np.zeros((X.shape[0], self.n_components))
  
      self._set_weights()
  
      return z
  
imports: from __future__ import print_function
  import numpy
  from scipy.special import digamma, gammaln
  from scipy import linalg
  from scipy.spatial.distance import cdist
  from ..externals.six.moves import xrange
  from ..utils import check_random_state, check_array, deprecated
  from ..utils.extmath import logsumexp, pinvh, squared_norm
  from ..utils.validation import check_is_fitted
  from ..None import cluster
  from .gmm import _GMMBase
label_desc: Use image node_id 19 for calling the _DPGMMBase obj's underlying member method code with example usage: obj._fit(X, y) and returns: z