'Compute the centroids on X by chunking it into mini-batches.
Parameters
X : array-like or sparse matrix, shape=(n_samples, n_features)
Training instances to cluster.'

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

    random_state = check_random_state(self.random_state)
    X = check_array(X, accept_sparse='csr', order='C', dtype=[np.float64, np.float32])
    (n_samples, n_features) = X.shape
    if (n_samples < self.n_clusters):
        raise ValueError('Number    of    samples    smaller    than    number    of    clusters.')
    n_init = self.n_init
    if hasattr(self.init, '__array__'):
        self.init = np.ascontiguousarray(self.init, dtype=X.dtype)
        if (n_init != 1):
            warnings.warn(('Explicit    initial    center    position    passed:    performing    only    one    init    in    MiniBatchKMeans    instead    of    n_init=%d' % self.n_init), RuntimeWarning, stacklevel=2)
            n_init = 1
    x_squared_norms = row_norms(X, squared=True)
    if (self.tol > 0.0):
        tol = _tolerance(X, self.tol)
        old_center_buffer = np.zeros(n_features, dtype=X.dtype)
    else:
        tol = 0.0
        old_center_buffer = np.zeros(0, dtype=X.dtype)
    distances = np.zeros(self.batch_size, dtype=X.dtype)
    n_batches = int(np.ceil((float(n_samples) / self.batch_size)))
    n_iter = int((self.max_iter * n_batches))
    init_size = self.init_size
    if (init_size is None):
        init_size = (3 * self.batch_size)
    if (init_size > n_samples):
        init_size = n_samples
    self.init_size_ = init_size
    validation_indices = random_state.randint(0, n_samples, init_size)
    X_valid = X[validation_indices]
    x_squared_norms_valid = x_squared_norms[validation_indices]
    best_inertia = None
    for init_idx in range(n_init):
        if self.verbose:
            print ('Init    %d/%d    with    method:    %s' % ((init_idx + 1), n_init, self.init))
        counts = np.zeros(self.n_clusters, dtype=np.int32)
        cluster_centers = _init_centroids(X, self.n_clusters, self.init, random_state=random_state, x_squared_norms=x_squared_norms, init_size=init_size)
        (batch_inertia, centers_squared_diff) = _mini_batch_step(X_valid, x_squared_norms[validation_indices], cluster_centers, counts, old_center_buffer, False, distances=None, verbose=self.verbose)
        (_, inertia) = _labels_inertia(X_valid, x_squared_norms_valid, cluster_centers)
        if self.verbose:
            print ('Inertia    for    init    %d/%d:    %f' % ((init_idx + 1), n_init, inertia))
        if ((best_inertia is None) or (inertia < best_inertia)):
            self.cluster_centers_ = cluster_centers
            self.counts_ = counts
            best_inertia = inertia
    convergence_context = {}
    for iteration_idx in range(n_iter):
        minibatch_indices = random_state.randint(0, n_samples, self.batch_size)
        (batch_inertia, centers_squared_diff) = _mini_batch_step(X[minibatch_indices], x_squared_norms[minibatch_indices], self.cluster_centers_, self.counts_, old_center_buffer, (tol > 0.0), distances=distances, random_reassign=(((iteration_idx + 1) % (10 + self.counts_.min())) == 0), random_state=random_state, reassignment_ratio=self.reassignment_ratio, verbose=self.verbose)
        if _mini_batch_convergence(self, iteration_idx, n_iter, tol, n_samples, centers_squared_diff, batch_inertia, convergence_context, verbose=self.verbose):
            break
    self.n_iter_ = (iteration_idx + 1)
    if self.compute_labels:
        (self.labels_, self.inertia_) = self._labels_inertia_minibatch(X)
    return self
