'Fit the hierarchical clustering on the data
Parameters
X : array-like, shape = [n_samples, n_features]
The samples a.k.a. observations.
Returns
self'

def fit(self, X, y=None):

    X = check_array(X, ensure_min_samples=2, estimator=self)
    memory = self.memory
    if (memory is None):
        memory = Memory(cachedir=None, verbose=0)
    elif isinstance(memory, six.string_types):
        memory = Memory(cachedir=memory, verbose=0)
    elif (not isinstance(memory, Memory)):
        raise ValueError("'memory'    should    either    be    a    string    or    a    sklearn.externals.joblib.Memory    instance,    got    'memory={!r}'    instead.".format(type(memory)))
    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'):
        compute_full_tree = (self.n_clusters < max(100, (0.02 * n_samples)))
    n_clusters = self.n_clusters
    if compute_full_tree:
        n_clusters = None
    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)
    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)
        labels = np.copy(labels[:n_samples])
        self.labels_ = np.searchsorted(np.unique(labels), labels)
    return self
