class_docstr: Agglomerative Clustering
  
  Recursively merges the pair of clusters that minimally increases
  a given linkage distance.
  
  Read more in the :ref:`User Guide <hierarchical_clustering>`.
  
  Parameters
  ----------
  n_clusters : int, default=2
      The number of clusters to find.
  
  connectivity : array-like or callable, optional
      Connectivity matrix. Defines for each sample the neighboring
      samples following a given structure of the data.
      This can be a connectivity matrix itself or a callable that transforms
      the data into a connectivity matrix, such as derived from
      kneighbors_graph. Default is None, i.e, the
      hierarchical clustering algorithm is unstructured.
  
  affinity : string or callable, default: "euclidean"
      Metric used to compute the linkage. Can be "euclidean", "l1", "l2",
      "manhattan", "cosine", or 'precomputed'.
      If linkage is "ward", only "euclidean" is accepted.
  
  memory : Instance of joblib.Memory or string (optional)
      Used to cache the output of the computation of the tree.
      By default, no caching is done. If a string is given, it is the
      path to the caching directory.
  
  compute_full_tree : bool or 'auto' (optional)
      Stop early the construction of the tree at n_clusters. This is
      useful to decrease computation time if the number of clusters is
      not small compared to the number of samples. This option is
      useful only when specifying a connectivity matrix. Note also that
      when varying the number of clusters and using caching, it may
      be advantageous to compute the full tree.
  
  linkage : {"ward", "complete", "average"}, optional, default: "ward"
      Which linkage criterion to use. The linkage criterion determines which
      distance to use between sets of observation. The algorithm will merge
      the pairs of cluster that minimize this criterion.
  
      - ward minimizes the variance of the clusters being merged.
      - average uses the average of the distances of each observation of
        the two sets.
      - complete or maximum linkage uses the maximum distances between
        all observations of the two sets.
  
  pooling_func : callable, default=np.mean
      This combines the values of agglomerated features into a single
      value, and should accept an array of shape [M, N] and the keyword
      argument ``axis=1``, and reduce it to an array of size [M].
  
  Attributes
  ----------
  labels_ : array [n_samples]
      cluster labels for each point
  
  n_leaves_ : int
      Number of leaves in the hierarchical tree.
  
  n_components_ : int
      The estimated number of connected components in the graph.
  
  children_ : array-like, shape (n_nodes-1, 2)
      The children of each non-leaf node. Values less than `n_samples`
      correspond to leaves of the tree which are the original samples.
      A node `i` greater than or equal to `n_samples` is a non-leaf
      node and has children `children_[i - n_samples]`. Alternatively
      at the i-th iteration, children[i][0] and children[i][1]
      are merged to form node `n_samples + i`
docstr: Fit the hierarchical clustering on the data
  
  Parameters
  ----------
  X : array-like, shape = [n_samples, n_features]
      The samples a.k.a. observations.
  
  Returns
  -------
  self
docstr_tok: ["Fit","the","hierarchical","clustering","on","the","data","Parameters","--","--","--","--","--","X",":","array-like",",","shape","=","[","n_samples",",","n_features","]","The","samples","a.k.a",".","observations",".","Returns","--","--","--","-","self"]
code: def fit(self, X, y=None):
      """Fit the hierarchical clustering on the data
  
      Parameters
      ----------
      X : array-like, shape = [n_samples, n_features]
          The samples a.k.a. observations.
  
      Returns
      -------
      self
      """
      X = check_array(X, ensure_min_samples=2, estimator=self)
      memory = self.memory
      if isinstance(memory, six.string_types):
          memory = Memory(cachedir=memory, verbose=0)
  
      if self.n_clusters <= 0:
          raise ValueError(
              "n_clusters should be an integer greater than 0."
              " %s was provided." % str(self.n_clusters)
          )
  
      if self.linkage == "ward" and self.affinity != "euclidean":
          raise ValueError(
              "%s was provided as affinity. Ward can only "
              "work with euclidean distances." % (self.affinity,)
          )
  
      if self.linkage not in _TREE_BUILDERS:
          raise ValueError(
              "Unknown linkage type %s."
              "Valid options are %s"
              % (self.linkage, _TREE_BUILDERS.keys())
          )
      tree_builder = _TREE_BUILDERS[self.linkage]
  
      connectivity = self.connectivity
      if self.connectivity is not None:
          if callable(self.connectivity):
              connectivity = self.connectivity(X)
          connectivity = check_array(
              connectivity, accept_sparse=["csr", "coo", "lil"]
          )
  
      n_samples = len(X)
      compute_full_tree = self.compute_full_tree
      if self.connectivity is None:
          compute_full_tree = True
      if compute_full_tree == "auto":
          # Early stopping is likely to give a speed up only for
          # a large number of clusters. The actual threshold
          # implemented here is heuristic
          compute_full_tree = self.n_clusters < max(
              100, 0.02 * n_samples
          )
      n_clusters = self.n_clusters
      if compute_full_tree:
          n_clusters = None
  
      # Construct the tree
      kwargs = {}
      if self.linkage != "ward":
          kwargs["linkage"] = self.linkage
          kwargs["affinity"] = self.affinity
      (
          self.children_,
          self.n_components_,
          self.n_leaves_,
          parents,
      ) = memory.cache(tree_builder)(
          X, connectivity, n_clusters=n_clusters, **kwargs
      )
      # Cut the tree
      if compute_full_tree:
          self.labels_ = _hc_cut(
              self.n_clusters, self.children_, self.n_leaves_
          )
      else:
          labels = _hierarchical.hc_get_heads(parents, copy=False)
          # copy to avoid holding a reference on the original array
          labels = np.copy(labels[:n_samples])
          # Reassign cluster numbers
          self.labels_ = np.searchsorted(np.unique(labels), labels)
      return self
  
imports: from heapq import heapify, heappop, heappush, heappushpop
  import warnings
  import numpy
  from scipy import sparse
  from ..base import BaseEstimator, ClusterMixin
  from ..externals.joblib import Memory
  from ..externals import six
  from ..metrics.pairwise import paired_distances, pairwise_distances
  from ..utils import check_array
  from ..utils.sparsetools import connected_components
  from .None import _hierarchical
  from ._feature_agglomeration import AgglomerationTransform
  from ..utils.fast_dict import IntFloatDict
  from ..externals.six.moves import xrange
label_desc: Use image node_id 2 for calling the AgglomerativeClustering obj's underlying member method code with example usage: obj.fit(X, y) and returns: self