Модуль 5. Линейные модели и метрики¶
Чему вы научитесь в этом модуле
- Собирать логистическую регрессию из компонентов, подготовленных в модуле 4, и проверять правильность градиента с помощью gradient check.
- Объяснять, почему для задач классификации используют log loss, а не среднеквадратичную ошибку (MSE) — через анализ градиента, а не по традиции.
- Демонстрировать на данных, что accuracy (доля правильных ответов), равная 0.95, может означать, что модель работает хуже, чем полное отсутствие модели.
- Обоснованно выбирать между ROC-AUC и PR-AUC, исходя из доли положительного класса в данных.
- Понимать, что порог классификации — это решение, которое принимаете вы, а не встроенное свойство модели.
Время: примерно две недели. Пререквизиты: модуль 4.
Ноутбук: открыть в Colab · notebooks/05-linear-models-and-metrics.ipynb
Зачем нужен этот модуль¶
Часть I дала базовые инструменты: статистику, линейную алгебру, производные и оптимизацию. Часть II даёт первые настоящие модели, и у них двойная роль.
Они полезны сами по себе: линейная модель по сей день решает множество прикладных задач и остаётся единственной моделью, чьи веса можно показать юристу или врачу и получить осмысленную интерпретацию. Но ещё важнее их вторая роль — это базовые линии (эталоны для сравнения), с которыми будет сопоставляться всё остальное в курсе. Из модуля 1 мы знаем, что утверждение без базы сравнения пусто. В этом модуле такие базы появляются.
Половина модуля посвящена метрикам качества, и это не второстепенное дополнение. На практике правильно выбрать метрику зачастую труднее, чем обучить модель, и ошибка в выборе метрики обходится дороже, чем ошибка в выборе алгоритма.
Логистическая регрессия¶
Линейная регрессия из модуля 3 предсказывает произвольное вещественное число. Для задач классификации нам нужно предсказывать вероятность — величину, принимающую значения строго от нуля до единицы.
Решение устроено просто: берём линейную комбинацию признаков \(z = w \cdot x\) (которая может принимать любое значение от \(-\infty\) до \(+\infty\)) и пропускаем её через сигмоиду, которая «сжимает» любое число в отрезок \([0, 1]\):
Функция потерь представляет собой логарифм правдоподобия, взятый со знаком «минус». Она называется log loss (логарифмическая потеря, или бинарная кросс-энтропия):
Смысл этой формулы можно прочитать напрямую: за уверенный правильный ответ штраф практически нулевой, а за уверенный неправильный — штраф стремится к бесконечности. Иными словами, модель наказывается за уверенность в ошибке значительно сильнее, чем за общую неуверенность.
Градиент log loss по весам был выведен в модуле 4 и оказался равен \((p - y)\,x\). Таким образом, всё необходимое для обучения модели уже готово: осталось лишь собрать цикл градиентного спуска.
Почему нельзя использовать MSE для классификации
Среднеквадратичная ошибка (MSE) для классификации формально «работает» — но приводит к некорректному поведению при обучении.
Возьмём объект, принадлежащий классу 1, на котором модель грубо ошибается: предсказанная вероятность \(p = 0.01\). Градиент MSE, пропущенный через сигмоиду, содержит множитель \(\sigma'(z) = p(1-p) = 0.0099\) — практически ноль. Это означает, что чем сильнее модель ошибается на данном объекте, тем слабее обучающий сигнал, направленный на исправление этой ошибки. Обучение фактически «застревает» именно там, где корректировка нужнее всего.
У log loss этот множитель полностью сокращается — это и было то самое алгебраическое сокращение, которое мы наблюдали в модуле 4. Итоговый градиент равен \((p - y)\,x\), и при \(p = 0.01\) и \(y = 1\) он оказывается максимальным по модулю.
Log loss используют для классификации не по сложившейся традиции, а потому, что MSE подавляет обучающий сигнал на самых трудных и важных примерах.
Регуляризация¶
В модуле 3 мы увидели, что коллинеарные (почти линейно зависимые) признаки раздувают веса модели до огромных значений. В модуле 2 — что слишком гибкая функция подстраивается под шум вместо закономерности. Регуляризация лечит обе эти проблемы одним простым приёмом — добавлением штрафа за большие значения весов к функции потерь.
L2-регуляризация (ridge): к функции потерь добавляется слагаемое \(\lambda\|w\|^2\) (сумма квадратов всех весов). Веса при этом «сжимаются» к нулю, но не становятся ровно нулевыми. Коллинеарные признаки перестают разгонять веса в плюс и минус бесконтрольно: штраф за большие значения делает симметричное решение (когда веса распределены поровну между похожими признаками) более выгодным.
Оптимизатор и сам выполняет роль регуляризатора
Градиентный спуск, стартующий из нулевой точки, приходит к решению с наименьшей нормой (длиной) вектора весов среди всех подходящих решений. При наличии коллинеарных признаков это означает, что он сам поделит вес между «двойниками» поровну, без всякого явного штрафа. Разъехавшиеся в плюс и минус бесконечность веса, которые мы наблюдали в модуле 3, были получены точным аналитическим решателем, а не градиентным спуском.
Это явление называется неявной регуляризацией, и из него следует важный практический вывод: выбор оптимизатора влияет на то, какое именно решение из множества равноценных вы получите. Формулировка задачи одна и та же, а ответы могут существенно различаться. В ноутбуке это демонстрируется на конкретных числах.
L1-регуляризация (lasso): к потере добавляется \(\lambda\sum|w_i|\) (сумма модулей весов). В отличие от L2, часть весов при L1-регуляризации становится ровно нулём. Таким образом, отбор признаков (определение наиболее значимых) происходит как побочный эффект процесса оптимизации.
Различие между L1 и L2 объясняется геометрически. Линии уровня L2-штрафа (множества точек с одинаковым значением \(\|w\|^2\)) — это окружности, и точка касания с ними практически никогда не приходится на координатную ось. Линии уровня L1-штрафа — это ромбы с вершинами на координатных осях, и касание чаще всего происходит именно в вершине ромба, то есть при нулевом значении соответствующего веса.
Параметр \(\lambda\) (сила регуляризации) подбирается на валидационной выборке. Не на тестовой — почему именно так, подробно разбирается в модуле 7.
Метрики качества, и почему accuracy обманчива¶
Теперь переходим к самой важной теме модуля.
Accuracy (доля правильных ответов) — на первый взгляд самая естественная метрика качества классификации. Однако на практике она почти всегда оказывается бесполезной.
Вернитесь к примеру из модуля 2: болезнь встречается у одного человека из тысячи. Классификатор, который всегда отвечает «здоров», автоматически получает accuracy = 0.999. Это та самая тривиальная база из модуля 1, и побить её содержательной моделью — задача нетривиальная. Любое значение accuracy бессмысленно, если рядом не указана доля положительного класса в данных.
Что нужно считать вместо accuracy. Начнём с четырёх базовых чисел, образующих матрицу ошибок (confusion matrix):
| Модель предсказала 1 | Модель предсказала 0 | |
|---|---|---|
| На самом деле 1 | TP (истинно положительные) | FN (ложно отрицательные) |
| На самом деле 0 | FP (ложно положительные) | TN (истинно отрицательные) |
Из этих четырёх чисел строятся две основные метрики, отвечающие на разные вопросы.
Precision (точность) \(= \dfrac{TP}{TP + FP}\) — из всех объектов, которые модель назвала положительными, какая доля действительно является положительной. Отвечает на вопрос: можно ли доверять каждому конкретному срабатыванию модели.
Recall (полнота) \(= \dfrac{TP}{TP + FN}\) — из всех настоящих положительных объектов, какую долю модель обнаружила. Отвечает на вопрос: какую долю интересующих нас объектов мы пропустили.
Эти две метрики находятся в постоянном противоборстве: понизите порог классификации — recall вырастет (модель будет находить больше положительных), но precision упадёт (вырастет количество ложных срабатываний). Повысите порог — произойдёт обратное.
F1-мера — гармоническое среднее precision и recall. Удобна как единственное число для сравнения, но опасна как целевая метрика для оптимизации: она неявно предполагает, что пропуск положительного объекта и ложное срабатывание обходятся одинаково. В медицинской диагностике, обнаружении мошенничества и модерации контента это, как правило, совсем не так.
Порог классификации — это ваше решение, а не свойство модели
Модель выдаёт вероятность (непрерывное число от 0 до 1). Превращение этой вероятности в бинарный ответ «да» или «нет» — это отдельный шаг, и этот шаг делаете именно вы.
Порог 0.5 не является ни встроенным свойством модели, ни разумным значением по умолчанию. Правильный порог определяется ценой ошибок каждого типа. Пропустить мошенническую транзакцию стоит одну сумму, а зря заблокировать честную — другую, и порог обязан отражать соотношение этих стоимостей.
Сравнение двух моделей по метрике качества при фиксированном пороге 0.5 нередко сравнивает не сами модели, а то, насколько удачно порог 0.5 подходит каждой из них.
ROC-AUC и PR-AUC¶
Чтобы избавиться от зависимости метрики от конкретного порога, качество оценивают по всем возможным порогам одновременно.
ROC-кривая показывает зависимость recall (доли обнаруженных положительных объектов) от доли ложных срабатываний среди отрицательных объектов при различных порогах. Площадь под этой кривой, ROC-AUC, имеет наглядную интерпретацию: это вероятность того, что случайно выбранный положительный объект получит от модели более высокий балл (вероятность), чем случайно выбранный отрицательный. Случайная (бесполезная) модель даёт ROC-AUC = 0.5, идеальная — 1.0.
PR-кривая показывает зависимость precision от recall при различных порогах. Площадь под ней — PR-AUC.
Различие между двумя метриками проявляется при редком положительном классе. В знаменателе доли ложных срабатываний (которая используется в ROC) стоит общее число отрицательных объектов, а их обычно очень много. Поэтому тысяча ложных срабатываний на миллион отрицательных объектов почти не сдвигает ROC-кривую. А вот precision при этом резко падает, потому что в её знаменателе — только объекты, предсказанные как положительные, и тысяча ложных среди, скажем, полутора тысяч предсказанных — это уже катастрофа.
Практическое правило. Если классы примерно сбалансированы — используйте ROC-AUC. Если положительных объектов лишь единицы процентов — используйте PR-AUC. ROC-AUC = 0.95 на задаче с долей положительных 0.1 % может соответствовать precision всего в несколько процентов, и это не противоречие, а прямое следствие арифметики.
Калибровка¶
Последнее свойство модели, о котором часто забывают.
Модель считается калиброванной, если среди объектов, которым она присвоила вероятность 0.8, действительно примерно 80 % оказываются положительными. Иными словами, предсказанные вероятности соответствуют реальным частотам.
Ранжирование и калибровка — это разные вещи. Модель может безупречно упорядочивать объекты по степени их «положительности» (AUC = 1.0) и при этом выдавать совершенно бессмысленные абсолютные значения вероятностей.
Калибровка важна в тех случаях, когда предсказанная вероятность используется в количественных расчётах, а не только для сортировки: при вычислении ожидаемой прибыли, при установке порога на основе стоимости ошибок, при объединении предсказаний из нескольких источников. Проверяется калибровка с помощью диаграммы надёжности (calibration plot): предсказания разбиваются на группы (корзины) по уровню предсказанной вероятности, и для каждой группы сравнивается средняя предсказанная вероятность с фактической долей положительных объектов.
Логистическая регрессия, как правило, калибрована неплохо «из коробки» — это прямое следствие использования log loss. Деревья решений и градиентный бустинг из модуля 6 — обычно нет.
Практическая часть¶
Часть 1. Работа с ноутбуком¶
Откройте notebooks/05-linear-models-and-metrics.ipynb.
Что содержится внутри:
- Логистическая регрессия с нуля, проверенная gradient check из модуля 4.
- MSE против log loss: наблюдаем за градиентом на объекте, в котором модель уверенно ошибается.
- Несбалансированные данные: accuracy = 0.98 у модели, которая не обнаружила ни одного положительного объекта.
- Precision, recall и порог как регулируемая «ручка». Визуализация кривой компромисса.
- ROC-AUC против PR-AUC при доле положительных 50 %, 5 % и 0.5 %.
- Диаграмма надёжности: что такое хорошая калибровка и как выглядит её отсутствие.
- Ridge на коллинеарных признаках из модуля 3: веса перестают расходиться в бесконечность.
Часть 2. Выбор метрики под задачу¶
Выберите любую задачу бинарной классификации из реальной жизни: фильтрация спама, прогнозирование оттока клиентов, обнаружение производственного брака, выявление подозрительных платежей.
Письменно, до написания любого кода:
- Какова цена ложного срабатывания. Выразите в деньгах, потраченном времени или потере доверия.
- Какова цена пропуска (необнаруженного положительного объекта). В тех же единицах.
- Исходя из соотношения этих двух цен — какой порог классификации представляется разумным.
- Какая метрика наилучшим образом отражает вашу задачу и почему это не F1-мера.
- Какая доля положительного класса ожидается в ваших данных. Из этого — что использовать: ROC-AUC или PR-AUC.
Пять ответов на полстраницы. Это и есть постановка задачи; всё остальное — техническая реализация.
Задание¶
- Реализуйте логистическую регрессию с L2-штрафом. Проверьте правильность градиента с помощью gradient check.
- Сгенерируйте данные с долей положительных объектов 1 %. Обучите модель и найдите порог, который максимизирует F1-меру. Сравните его с порогом 0.5.
- Постройте две модели, имеющие одинаковый ROC-AUC, но заметно различающийся PR-AUC. Объясните, чем модели отличаются по своему поведению.
- Возьмите предсказания обученной модели и постройте диаграмму надёжности. Откалибруйте модель с помощью изотонической регрессии или простого усреднения по корзинам. Изменился ли AUC после калибровки?
- На коллинеарных данных сравните веса модели без регуляризации и с L2-регуляризацией при трёх различных значениях \(\lambda\). Визуализируйте, как веса стремятся к нулю по мере увеличения \(\lambda\).
Проверка усвоения¶
- Почему для классификации используется log loss, а не MSE? Дайте ответ через анализ градиента.
- Accuracy составляет 0.99. Какой первый вопрос вы зададите?
- Чем precision отличается от recall — объясните словами, без формул?
- Почему F1-мера — плохая целевая метрика для системы обнаружения мошенничества?
- Откуда берётся значение порога классификации, если не из числа 0.5?
- Как прочитать ROC-AUC одной фразой, используя понятие двух случайно выбранных объектов?
- В каких случаях PR-AUC информативнее ROC-AUC и почему?
- Модель имеет AUC = 1.0, но при этом плохо калибрована. Как такое возможно?
Что дальше¶
В модуле 6 появляются деревья решений, а вместе с ними — семейство методов (ансамбли и градиентный бустинг), которое на табличных данных по сей день обыгрывает нейронные сети. Это будет главная базовая линия всего курса, и в частях III–VI любому новому методу придётся побеждать её честно.
Метрика выбирается исходя из цены ошибки, а не из привычки. Порог — тоже.