'Fit the model according to the given training data.
Parameters
X : {array-like, sparse matrix}, shape (n_samples, n_features)
Training vector, where n_samples is the number of samples and
n_features is the number of features.
y : array-like, shape (n_samples,)
Target vector relative to X.
sample_weight : array-like, shape (n_samples,) optional
Array of weights that are assigned to individual samples.
If not provided, then each sample is given unit weight.
Returns
self : object
Returns self.'

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

    _check_solver_option(self.solver, self.multi_class, self.penalty, self.dual)
    if ((not isinstance(self.max_iter, numbers.Number)) or (self.max_iter < 0)):
        raise ValueError(('Maximum    number    of    iteration    must    be    positive;    got    (max_iter=%r)' % self.max_iter))
    if ((not isinstance(self.tol, numbers.Number)) or (self.tol < 0)):
        raise ValueError(('Tolerance    for    stopping    criteria    must    be    positive;    got    (tol=%r)' % self.tol))
    (X, y) = check_X_y(X, y, accept_sparse='csr', dtype=np.float64, order='C')
    check_classification_targets(y)
    class_weight = self.class_weight
    label_encoder = LabelEncoder().fit(y)
    y = label_encoder.transform(y)
    if isinstance(class_weight, dict):
        class_weight = dict(((label_encoder.transform([cls])[0], v) for (cls, v) in class_weight.items()))
    classes = self.classes_ = label_encoder.classes_
    encoded_labels = label_encoder.transform(label_encoder.classes_)
    if (self.solver in ['sag', 'saga']):
        max_squared_sum = row_norms(X, squared=True).max()
    else:
        max_squared_sum = None
    cv = check_cv(self.cv, y, classifier=True)
    folds = list(cv.split(X, y))
    n_classes = len(encoded_labels)
    if (n_classes < 2):
        raise ValueError(('This    solver    needs    samples    of    at    least    2    classes    in    the    data,    but    the    data    contains    only    one    class:    %r' % classes[0]))
    if (n_classes == 2):
        n_classes = 1
        encoded_labels = encoded_labels[1:]
        classes = classes[1:]
    if (self.multi_class == 'multinomial'):
        iter_encoded_labels = iter_classes = [None]
    else:
        iter_encoded_labels = encoded_labels
        iter_classes = classes
    if (class_weight == 'balanced'):
        class_weight = compute_class_weight(class_weight, np.arange(len(self.classes_)), y)
        class_weight = dict(enumerate(class_weight))
    path_func = delayed(_log_reg_scoring_path)
    if (self.solver in ['sag', 'saga']):
        backend = 'threading'
    else:
        backend = 'multiprocessing'
    fold_coefs_ = Parallel(n_jobs=self.n_jobs, verbose=self.verbose, backend=backend)((path_func(X, y, train, test, pos_class=label, Cs=self.Cs, fit_intercept=self.fit_intercept, penalty=self.penalty, dual=self.dual, solver=self.solver, tol=self.tol, max_iter=self.max_iter, verbose=self.verbose, class_weight=class_weight, scoring=self.scoring, multi_class=self.multi_class, intercept_scaling=self.intercept_scaling, random_state=self.random_state, max_squared_sum=max_squared_sum, sample_weight=sample_weight) for label in iter_encoded_labels for (train, test) in folds))
    if (self.multi_class == 'multinomial'):
        (multi_coefs_paths, Cs, multi_scores, n_iter_) = zip(*fold_coefs_)
        multi_coefs_paths = np.asarray(multi_coefs_paths)
        multi_scores = np.asarray(multi_scores)
        coefs_paths = np.rollaxis(multi_coefs_paths, 2, 0)
        scores = np.tile(multi_scores, (n_classes, 1, 1))
        self.Cs_ = Cs[0]
        self.n_iter_ = np.reshape(n_iter_, (1, len(folds), len(self.Cs_)))
    else:
        (coefs_paths, Cs, scores, n_iter_) = zip(*fold_coefs_)
        self.Cs_ = Cs[0]
        coefs_paths = np.reshape(coefs_paths, (n_classes, len(folds), len(self.Cs_), (-1)))
        self.n_iter_ = np.reshape(n_iter_, (n_classes, len(folds), len(self.Cs_)))
    self.coefs_paths_ = dict(zip(classes, coefs_paths))
    scores = np.reshape(scores, (n_classes, len(folds), (-1)))
    self.scores_ = dict(zip(classes, scores))
    self.C_ = list()
    self.coef_ = np.empty((n_classes, X.shape[1]))
    self.intercept_ = np.zeros(n_classes)
    if (self.multi_class == 'multinomial'):
        scores = multi_scores
        coefs_paths = multi_coefs_paths
    for (index, (cls, encoded_label)) in enumerate(zip(iter_classes, iter_encoded_labels)):
        if (self.multi_class == 'ovr'):
            scores = self.scores_[cls]
            coefs_paths = self.coefs_paths_[cls]
        if self.refit:
            best_index = scores.sum(axis=0).argmax()
            C_ = self.Cs_[best_index]
            self.C_.append(C_)
            if (self.multi_class == 'multinomial'):
                coef_init = np.mean(coefs_paths[:, best_index, :, :], axis=0)
            else:
                coef_init = np.mean(coefs_paths[:, best_index, :], axis=0)
            (w, _, _) = logistic_regression_path(X, y, pos_class=encoded_label, Cs=[C_], solver=self.solver, fit_intercept=self.fit_intercept, coef=coef_init, max_iter=self.max_iter, tol=self.tol, penalty=self.penalty, class_weight=class_weight, multi_class=self.multi_class, verbose=max(0, (self.verbose - 1)), random_state=self.random_state, check_input=False, max_squared_sum=max_squared_sum, sample_weight=sample_weight)
            w = w[0]
        else:
            best_indices = np.argmax(scores, axis=1)
            w = np.mean([coefs_paths[i][best_indices[i]] for i in range(len(folds))], axis=0)
            self.C_.append(np.mean(self.Cs_[best_indices]))
        if (self.multi_class == 'multinomial'):
            self.C_ = np.tile(self.C_, n_classes)
            self.coef_ = w[:, :X.shape[1]]
            if self.fit_intercept:
                self.intercept_ = w[:, (-1)]
        else:
            self.coef_[index] = w[:X.shape[1]]
            if self.fit_intercept:
                self.intercept_[index] = w[(-1)]
    self.C_ = np.asarray(self.C_)
    return self
