Written and maintained by CASRAI Editorial Board
Last updated
Researchers searching for scikit-learn logistic regression usually need to fit a classifier, understand which parameters matter, and report the model so someone else can reproduce it. This guide covers sklearn.linear_model.LogisticRegression as documented for scikit-learn 1.9, including the 1.8 change that deprecated the penalty argument, a solver decision table taken from the user guide, and a reporting checklist. The same class answers the searches logistic regression sklearn, logistic regression scikit and scikit-learn logistic regression.
What it is used for in research
LogisticRegression models the probability of a class from a set of features, for binary or multiclass outcomes, with optional L1, L2 or elastic-net regularization. It is a prediction tool first: it returns coefficients and probabilities, but not the p-values and confidence intervals a classical inference table reports. The scikit-learn documentation states that p-values and confidence intervals can be obtained for unpenalized regression, that the statsmodels package supports this natively, and that within scikit-learn one could use bootstrapping instead (user guide, section 1.1.11, checked 2026-11-07). For a workflow built on that package family, see our guide to statsmodels OLS.
Install or access
The official installation route is pip install -U scikit-learn; the project’s installation page at scikit-learn.org lists the other supported routes. Check your version with import sklearn; print(sklearn.__version__) and record it, because the parameter set changed in 1.8 (see below). New to the library? Start with our scikit-learn tutorial.
Step-by-step: fit, predict and inspect a model
This example uses the breast cancer dataset bundled with scikit-learn, so it needs no download. Standardizing first matters: the user guide’s solver table marks sag and saga as not robust to unscaled data, and penalized fits depend on feature scale.
- Split the data, stratifying on the outcome (see train-test split in Python).
- Build a pipeline so the scaler is fitted on training data only.
- Fit, then call
predict,predict_probaandscore.
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, stratify=y, random_state=0)
model = make_pipeline(StandardScaler(), LogisticRegression(C=1.0, max_iter=1000))
model.fit(X_train, y_train)
clf = model[-1]
print(clf.classes_, clf.coef_.shape, clf.intercept_.shape, clf.n_iter_)
print(model.score(X_test, y_test))
print(model.predict_proba(X_test[:1]), model.predict(X_test[:1]))
Output and how to read it
We ran this code with scikit-learn 1.9.0 on 2026-11-07. It printed classes [0 1], a coef_ shape of (1, 30), an intercept_ shape of (1,), n_iter_ of 18, and a test accuracy of 0.958 on this split. For the first test row, predict_proba returned about 0.0042 for class 0 and 0.9958 for class 1, and predict returned 1.
- coef_ has shape (1, n_features) for a binary problem and (n_classes, n_features) otherwise; intercept_ holds the intercept term(s) (API reference, attributes section).
- predict_proba columns are ordered as
classes_, so read column order from that attribute rather than assuming it. - score is mean accuracy. For other metrics see how to calculate AUC and the Brier score, which assess discrimination and probability calibration respectively.
- Odds ratios: with a standardized pipeline each coefficient is a change in log-odds per one standard deviation of that feature, and exponentiating it gives the corresponding odds ratio (see odds ratio). This is standard logistic-regression mathematics (editorial note, not a statement from the scikit-learn page), and it describes a penalized fit, so treat it as descriptive.
- n_iter_ reports iterations used; if it reaches
max_iteryou will see a ConvergenceWarning.
Parameters that matter (scikit-learn 1.9)
The documented signature for 1.9.1 is LogisticRegression(penalty='deprecated', *, C=1.0, l1_ratio=0.0, dual=False, tol=0.0001, fit_intercept=True, intercept_scaling=1, class_weight=None, random_state=None, solver='lbfgs', max_iter=100, verbose=0, warm_start=False, n_jobs=None) (API reference, checked 2026-11-07).
The 1.8 penalty deprecation: l1_ratio and C
The penalty argument was deprecated in 1.8 and is slated for removal in 1.10; the l1_ratio default changed from None to 0.0 in 1.8, and n_jobs was also deprecated in 1.8 (it has no effect) and will be removed in 1.10. Older tutorials that write penalty='l1' therefore map as follows:
| Regularization wanted | Current setting |
|---|---|
| L2 | l1_ratio=0 (the default) |
| L1 | l1_ratio=1 |
| Elastic net | 0 < l1_ratio < 1 |
| No penalty | C=np.inf |
C is the inverse of regularization strength and must be a positive float; as with support vector machines, smaller values specify stronger regularization. For the elastic-net background see elastic net regression, and for why strong or absent regularization matters for generalization see what is overfitting.
Choosing a solver
The default solver is lbfgs (changed from liblinear in version 0.22); newton-cholesky was added in 1.2. The table restates the user guide’s solver comparison.
| Solver | L1 penalty | Elastic net | No penalty | Multinomial multiclass | Robust to unscaled data |
|---|---|---|---|---|---|
| lbfgs | No | No | Yes | Yes | Yes |
| liblinear | Yes | No | No | No | Yes |
| newton-cg | No | No | Yes | Yes | Yes |
| newton-cholesky | No | No | Yes | Yes | Yes |
| sag | No | No | Yes | Yes | No |
| saga | Yes | Yes | Yes | Yes | No |
The user guide also lists sag and saga as the faster choices for large datasets, and notes that liblinear penalizes the intercept. liblinear cannot learn a true multinomial model; the documentation suggests wrapping it in OneVsRestClassifier for multiclass problems, and says minimizing the multinomial loss is expected to give better calibrated results than a one-vs-rest scheme.
Class imbalance and reproducibility
class_weight='balanced' uses weights of n_samples / (n_classes * np.bincount(y)). Set random_state where the chosen solver uses randomness, and raise max_iter if you see convergence warnings. An elastic-net example from the documentation is LogisticRegression(l1_ratio=0.5, C=1.0, solver='saga', max_iter=1000); the unpenalized form is LogisticRegression(C=float('inf')).
Troubleshooting
- ConvergenceWarning: the solver stopped at
max_iterwithcoef_not converged. Standardize the features, then raisemax_iter. The solver table shows sag and saga are the ones that are not robust to unscaled data. - Deprecation warning mentioning penalty: replace
penaltywithl1_ratioorC=np.infas mapped above. - Error that a solver does not support your settings: check the solver table; L1 needs liblinear or saga, and elastic net needs saga.
- Probabilities in unexpected columns: read
classes_.
Free alternatives and related tools
| Need | Option | Basis |
|---|---|---|
| P-values and confidence intervals for unpenalized logistic regression | statsmodels | Named in the scikit-learn user guide as natively supporting these |
| Bootstrapped uncertainty within scikit-learn | Resampling around LogisticRegression | Suggested in the same passage |
| Multiclass with liblinear | OneVsRestClassifier wrapper | Suggested in the LogisticRegression documentation |
Reporting checklist
For a methods section or replication package, record: the scikit-learn version; C and l1_ratio (or the unpenalized setting); solver; class_weight; max_iter and whether any ConvergenceWarning appeared; random_state; and whether features were standardized and how the split was made.
FAQ
What is the default regularization in sklearn LogisticRegression?
L2 regularization with C=1.0. In scikit-learn 1.8 and later, this is expressed as l1_ratio=0, the default; the older penalty argument is deprecated.
How do I turn regularization off?
Set C=np.inf, which the documentation says gives unpenalized logistic regression. Liblinear does not support the no-penalty option.
Does scikit-learn give p-values for logistic regression?
Not from LogisticRegression itself. The documentation points to statsmodels for unpenalized models, or bootstrapping within scikit-learn.
Which solver should I use?
The default lbfgs handles L2 and no penalty, including multinomial multiclass. Use liblinear or saga for L1, and saga for elastic net. See the table above.
Is this the same as multivariate logistic regression?
LogisticRegression accepts many features, and with more than two classes it can fit a multinomial model with all solvers except liblinear. The statistical term multivariate is sometimes used for multiple outcome variables, which this class does not model.
Sources
- scikit-learn documentation, sklearn.linear_model.LogisticRegression (version 1.9.1): https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html. Date checked: 2026-11-07.
- scikit-learn user guide, section 1.1.11 Logistic regression: https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression. Date checked: 2026-11-07.







