Error database

ConvergenceWarning: lbfgs failed to converge (scikit-learn)

The optimiser hit its iteration limit before settling. Scale your features first — that fixes most cases — and raise max_iter second.

The message you saw
ConvergenceWarning: lbfgs failed to converge (scikit-learn)

By Updated

The error

Output
ConvergenceWarning: lbfgs failed to converge (status=1):
STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.

Increase the number of iterations (max_iter) or scale the data as shown in:
    https://scikit-learn.org/stable/modules/preprocessing.html

What it means

This is a warning, not an error — you still have a fitted model. lbfgs is the optimisation algorithm behind LogisticRegression and friends: it walks downhill on the loss function until the steps become tiny. Here it ran out of its iteration budget (default 100) while the steps were still large. The coefficients you got are wherever it happened to stop, which may or may not be good.

Why it happens

The message suggests raising max_iter, but that treats the symptom. The usual disease is unscaled features. When one column ranges 0-1 and another 0-500,000, the loss surface becomes a long narrow valley. The optimiser zigzags along it and 100 iterations are nowhere near enough. Scaled features make the valley round, and the same problem converges in a handful of steps.

How to fix it

1. Scale the features — inside a pipeline. This is the real fix in most cases.

python
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

model = make_pipeline(StandardScaler(), LogisticRegression())
model.fit(X_train, y_train)

StandardScaler shifts each feature to mean 0 and spread 1. The pipeline guarantees the scaler is fitted on training data only and applied identically at prediction time.

2. Raise max_iter if the warning persists.

python
LogisticRegression(max_iter=1000)

Harmless: iterating longer costs a little time, nothing else. If 1000 is still not enough on scaled data, something else is off — often near-duplicate columns or perfectly separable data.

3. Consider a different solver for unusual shapes of data.

python
LogisticRegression(solver="liblinear")   # small datasets
LogisticRegression(solver="saga")        # very large or sparse datasets

4. Do not silence the warning without fixing it. Suppressing it leaves you with a half-optimised model that quietly underperforms.

How to prevent it

Make make_pipeline(StandardScaler(), <linear model>) your default habit for anything with coefficients — logistic and linear regression, SVMs, neural networks. Tree models (random forests, gradient boosting) do not need scaling, which is one reason they are so forgiving.