LogisticRegression: что делать с ConvergenceWarning

Скрипт напечатал ConvergenceWarning, затем сохранил модель и прогнозы. Значит ли это, что обучение закончено нормально? Estimator уже может давать ответы, но оптимизатор сообщил, что не выполнил условие остановки за доступное число итераций.

Сначала прочитать причину остановки

ConvergenceWarning относится к процедуре поиска параметров. Наличие predict после fit не отменяет предупреждение: модель использует текущее найденное приближение. Не стоит просто скрывать сообщение общим фильтром warnings. Зафиксируйте solver, max_iter, масштаб входов и n_iter_, чтобы понять, какой лимит был достигнут.

Масштабы признаков могут заметно влиять на работу оптимизатора. В примере StandardScaler находится внутри Pipeline и обучается вместе с моделью. Эта конструкция сохраняет единый путь применения преобразования. Здесь рассматриваем именно остановку обучения: сравнение качества и выбор регуляризации требуют отдельных экспериментов.

Повторить обучение с достаточным лимитом

Первый запуск намеренно ограничен одной итерацией, поэтому предупреждение ожидается и перехватывается локально. Второй использует тот же вход, solver и tol, но больший max_iter. Проверяем отсутствие ConvergenceWarning и то, что фактическое число итераций не дошло до лимита.

Если увеличение лимита не помогает, посмотрите на подготовку входа и выбранный solver. Значение max_iter не является универсальной настройкой качества. Оно даёт алгоритму время выполнить уже выбранную задачу оптимизации.

import warnings
from sklearn.datasets import load_iris
from sklearn.exceptions import ConvergenceWarning
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

X, y = load_iris(return_X_y=True)
def train(limit):
    model = make_pipeline(StandardScaler(),
                          LogisticRegression(max_iter=limit, tol=1e-6))
    with warnings.catch_warnings(record=True) as caught:
        warnings.simplefilter("always", ConvergenceWarning)
        model.fit(X, y)
    return model, [w for w in caught if issubclass(w.category, ConvergenceWarning)]

short, short_warnings = train(1)
ready, ready_warnings = train(500)
assert short_warnings
assert not ready_warnings
iterations = ready[-1].n_iter_.tolist()
assert max(iterations) < 500
assert len(ready.predict(X[:3])) == 3
print("iterations:", iterations)

Сделать предупреждение видимым в автоматическом запуске

В обучающем процессе сохраните предупреждения рядом с параметрами и фактическим числом итераций. Можно считать ConvergenceWarning ошибкой конкретного этапа приёмки, если команда требует успешной остановки до публикации. Тогда решение о продолжении будет явным, а предупреждение не потеряется среди сотен строк вывода.

После исправления процедуры обучения выполните обычную проверку модели на отложенных данных. Исчезновение предупреждения подтверждает условие оптимизатора, а не полезность прогноза. Это два разных основания для принятия результата.

Закрепить базовую операцию

В открытом уроке LogisticRegression вы обучите классификатор и вызовете predict. Добавьте к этому запуску наблюдение за предупреждениями и фактическими итерациями. Откройте урок «LogisticRegression: fit, predict и classes_». Затем вернитесь к сценарию статьи и проверьте его на своём небольшом наборе. Посмотрите программу курса первой ML-модели, чтобы пройти путь от обучения к использованию результата.

Продолжить на практике