Логистическая регрессия: почему «регрессия» и где живёт граница решения

Предыдущий разбор — «Бинарная классификация: как машина отличает кота от не-кота» — прошёл механику насквозь: предсказание yˆ=σ(wTx+b), ошибка, градиентный спуск. Эта статья — продолжение урока: три вопроса, которые там остались за кадром. Почему модель с «классификационной» задачей называется регрессией? Что предсказание значит геометрически — где проходит черта между «котом» и «не-котом»? И откуда берётся самая изящная формула темы, dz=a−y, — в прошлый раз мы её приняли на веру и проверили числом, теперь выведем честно. Все формулы, как обычно, разобраны до числа: каждую можно пересчитать в столбик.

Почему «регрессия», если задача — классификация

Название сбивает с толку, и на то есть честная причина. Регрессия в машинном обучении — задача предсказать число: цену квартиры, температуру завтра, время в пути. Классификация — предсказать метку: «кот» или «не-кот». Наша модель обучается на метках, а называется регрессией. Почему?

Посмотри на формулу предсказания из «Бинарной классификации»:

yˆ=σ(wTx+b)=σ(z)

Внутри неё спрятана самая настоящая регрессия. Первый шаг — z=wTx+b — это линейная регрессия в чистом виде: взвешенная сумма признаков, та же формула, которой предсказывают цену квартиры. Сигмоида (σ) просто сжимает её результат в диапазон от 0 до 1 — чтобы число можно было читать как вероятность.

То есть модель сначала решает регрессию (считает число z), а потом превращает число в вероятность (ŷ). Имя подчёркивает первую половину, а задача — вторую. Исторический бонус: метод назван так в статистике задолго до нейросетей, и имя прилипло намертво.

Полезное следствие: yˆ — не «процент кота в картинке», а уверенность модели. Значение 0.7 означает «в 7 случаях из 10 это кот, в 3 — нет». На тренировке нас интересует вся шкала: чем ближе уверенность к правильному ответу (y), тем меньше штраф. А вот после обучения обычно вводят порог: yˆ≥0.5 — объявляем «кот», иначе «не-кот». Порог — это уже не модель, а правило принятия решения поверх неё, и он принадлежит следующему разделу.

Если можешь пересказать: внутри — линейная регрессия z, сигмоида (σ) сжимает её в вероятность; имя от первого, задача от второго, — двигаемся дальше.

Граница решения: где проходит черта

Порог yˆ=0.5 превращает формулу в черту на карте признаков. Найдём её — и увидим, что модель устроена геометрически проще, чем кажется.

Порог срабатывает, когда yˆ=0.5, то есть σ(z)=0.5. Взгляни на таблицу сигмоиды (σ) из «Бинарной классификации»: σ(0)=0.5, причём только ноль даёт ровно половину. Значит, порог соответствует z=0:

σ(z)=0.5⟺z=0

Запишем z=0 подробно для модели с двумя признаками (двух, чтобы черту можно было нарисовать на плоскости):

w1x1+w2x2+b=0

Возьмём конкретные веса (w): w1=2, w2=1, b=−3. Это не числа, подобранные обучением, — просто фиксированный пример, чтобы всё посчитать. Граница:

2x1+x2−3=0⇒x2=3−2x1

Это уравнение прямой: при x1=0 имеем x2=3, при x1=1.5 имеем x2=0. Вот она на плоскости вместе с точками двух классов:

Граница решения: прямая x2 = 3 − 2·x1 делит плоскость; треугольники (коты) над линией, квадраты (не-коты) под ней

Прямая делит плоскость на две половины. Над ней z>0, значит yˆ>0.5 — зона «кот». Под ней z<0, yˆ<0.5 — зона «не-кот». Эта черта и называется границей решения (decision boundary) (z=0).

Теперь главное: граница зависит только от весов (w). Точки данных на неё не влияют никак — прямая проходит там, куда её поставили w и b. Обучение (градиентный спуск из «Бинарной классификации») — это и есть процесс, при котором веса (w) постепенно двигаются, и прямая вместе с ними переползает с места на место, пока не разделит классы наилучшим образом.

Проверим прямой ход на четырёх точках. Считаем z=2x1+x2−3, затем yˆ=σ(z):

x1x2zyˆрешение при пороге 0.5
0.81.6+0.20.55кот
1.20.4−0.20.45не кот
0.32.6+0.20.55кот
1.31.0+0.60.65кот

Каждая строка пересчитывается в столбик: для первой точки z=2⋅0.8+1⋅1.6−3=1.6+1.6−3=0.2, и yˆ=σ(0.2)=0.55 (значение — из таблицы сигмоиды (σ) или на калькуляторе: e−0.2≈0.819, значит σ(0.2)=1/1.819≈0.55). Остальные строки — по тому же шаблону.

Обрати внимание на третью и четвёртую строки: обе точки в зоне «кот», но уверенности разные — 0.55 против 0.65. Чем дальше точка от границы, тем больше |z| и тем увереннее модель. Точка, лежащая на самой границе, дала бы ровно yˆ=0.5: модель честно признаётся, что не знает.

И ещё одно следствие, которое сейчас спрячем в карман: граница у логистической регрессии — всегда прямая (точнее, гиперплоскость в пространстве признаков: при 12288 признаках это плоскость в 12288-мерном пространстве, но механика та же). Если классы в реальности разделяются кривой линией, логистическая регрессия прямой этого не выхватит — и именно поэтому следующим шагом после векторизации к делу подключаются полноценные нейросети.

Если можешь пересказать: порог 0.5 отвечает z=0, а z=0 — прямая; над ней «кот», под ней «не-кот»; веса (w) двигают прямую, — листай дальше.

Вывод dz = a − y: обещанная выкладка

В «Бинарной классификации» мы взяли на веру и проверили числом формулу, в которую сворачивается вся обратная цепочка логистической регрессии:

dz=a−y

Здесь a — предсказание модели (a) (a=σ(z), то же число, что yˆ), y — правильный ответ (y), а dz — производная функции ошибки по z («насколько ошибка отзовётся на взвешенной сумме»). Теперь выведем её по цепному правилу.

Шаг 0: что во что входит. Цепочка прямого хода: z→a→L. Здесь a=σ(z) и L(a,y) — кросс-энтропия (простыми словами: штраф за ошибку одного предсказания, который почти равен нулю, если модель уверенно права, и резко растёт, если она уверенно ошиблась; полный разбор формулы с числами — в «Функции стоимости»). Производную считаем от конца к началу: сначала «как L зависит от a», потом «как a зависит от z», и перемножаем.

Шаг 1: производная кросс-энтропии по a. Кросс-энтропия склеивает два случая одной формулой L=−[ylog⁡a+(1−y)log⁡(1−a)]. Производную берём по каждому случаю отдельно.

При y=1 второе слагаемое исчезает: L=−log⁡a, и производная −log⁡a — это −1/a:

∂L∂a=−1a

При y=0 исчезает первое: L=−log⁡(1−a). Производная от −log⁡(1−a) по правилу цепочки равна +11−a (внутренняя функция 1−a даёт множитель −1, минус перед логарифмом переворачивает знак):

∂L∂a=11−a

Шаг 2: производная сигмоиды (σ). У сигмоиды (σ) красивая производная — она выражается через саму сигмоиду:

dadz=a(1−a)

Вывод по определению: σ(z)=(1+e−z)−1, дифференцируем как степень:

dσdz=−(1+e−z)−2⋅(−e−z)=e−z(1+e−z)2

Теперь раскладываем на множители:

e−z(1+e−z)2=11+e−z⏟σ(z)⋅e−z1+e−z⏟1−σ(z)=σ(z)(1−σ(z))

Второй множитель проверяется в одну строку: 1+e−z−11+e−z=1−11+e−z. Проверим числом: при z=1.38 имеем a=0.799, формула даёт 0.799⋅0.201=0.1606; численная производная (посчитать σ при z=1.380001 и z=1.379999, взять разницу) даёт 0.1606. Совпало.

Шаг 3: перемножаем по цепочке. Общий случай:

∂L∂z=∂L∂a⋅dadz

Случай y=1:

∂L∂z=−1a⋅a(1−a)=−(1−a)=a−1

Случай y=0:

∂L∂z=11−a⋅a(1−a)=a

Шаг 4: один взгляд на оба случая. При y=1 ответ a−1, при y=0 ответ a. Но a−1 — это в точности a−y при y=1, а a — это a−y при y=0. Оба случая записываются одной формулой:

dz=a−y

Вот и вся магия: короткая формула — не совпадение, а следствие того, что кросс-энтропия согласована с сигмоидой (σ). Множители 1/a и 1/(1−a) из производной ошибки точно гасят лишние куски a(1−a) из производной сигмоиды (σ) — эта согласованность не случайна: кросс-энтропию для сигмоиды выбирали именно из этого требования. Если взять другую ошибку (например, квадрат разницы), красивого схлопывания не выйдет — производная останется громоздкой.

Финальная проверка на числах из «Бинарной классификации»: z=1.38, a=0.799, y=1. Формула: dz=0.799−1=−0.201. Численная производная L по z даёт −0.201. Совпало — как и в прошлый раз, только теперь мы знаем, откуда это берётся.

Если можешь пересказать: производная ошибки по a минус-один-на-a (при y=1), производная сигмоиды (σ) — a(1−a); перемножение гасит дроби и оставляет a−y, — листай дальше.

Спуск доводит до конца: 10 шагов на числах

В «Бинарной классификации» мы сделали один шаг градиентного спуска и остановились. Продолжим тот же пример до десяти шагов — и посмотрим, к чему сходится процесс. Напомню условия: один обучающий пример x=[0.5,0.3,0.9] с ответом y=1, начальные веса (w) w=[1.2,−0.4,2.0], b=−0.9, скорость обучения (α) α=0.1. На каждом шаге: считаем z, затем a=σ(z), затем ошибку L=−log⁡a, сигнал dz=a−1 (тот самый вывод прошлого раздела), и сдвигаем веса: w:=w−αxdz, b:=b−αdz.

Первые шаги в числах (проверяются в столбик, как и все предыдущие):

шагzyˆL=−log⁡yˆ
0+1.3800.79900.2244
1+1.4230.80580.2159
2+1.4650.81230.2079
3+1.5050.81840.2004
5+1.5820.82950.1869
10+1.7550.85260.1595

Для краткости показаны первые шаги, пятый и последний десятый; шаги 4 и 6–9 считаются по тому же шаблону.

Разберём, что произошло. Уверенность модели в правильном ответе (y) выросла с 0.7990 до 0.8526, ошибка упала с 0.2244 до 0.1595 — почти на 30%. Заметь: спуск не «дожимает» yˆ до единицы — он двигается в её сторону маленькими шагами, и каждый следующий шаг даёт всё меньший выигрыш. Это нормальное поведение спуска: у дна чаши наклон пологий, и эффективность шагов падает.

Градиентный спуск на одном примере: слева ошибка L убывает с 0.224 до 0.159, справа уверенность ŷ растёт с 0.799 до 0.853

Заглянем внутрь одного шага — шага 1 (все значения из таблицы):

  1. Прямой ход: z=1.423, a=0.8058, L=−log⁡(0.8058)=0.2159.
  2. Сигнал ошибки: dz=a−y=0.8058−1=−0.1942 — модель недобрала уверенности, сигнал отрицательный, веса (w) должны подрасти.
  3. Градиенты: dw=x⋅dz=[0.5⋅(−0.1942),0.3⋅(−0.1942),0.9⋅(−0.1942)]=[−0.0971,−0.0583,−0.1748], и db=−0.1942.
  4. Шаг при α=0.1: w:=[1.21,−0.394,2.018]−0.1⋅[−0.0971,−0.0583,−0.1748]=[1.2197,−0.3882,2.0355], b:=−0.880−0.1⋅(−0.1942)=−0.8606.

Сверь с таблицей: после этого шага z=+1.465 — строка «шаг 2». Машина делает ровно это, миллионы раз, по всем примерам набора: прямой ход, сигнал ошибки, поправка весов (w).

И ещё деталь, ради которой стоило считать десять шагов: куда не дошёл спуск. Уверенность 0.8526 — не 1.0, и дальше она будет расти всё медленнее, асимптотически. На одном примере спуск в принципе может дожать уверенность сколь угодно близко к единице (веса (w) растут, z уходит в бесконечность) — но на настоящем наборе из многих примеров с противоречивыми ответами это невозможно: веса (w) вынуждены компромиссом обслуживать все примеры сразу. Именно этот компромисс и измеряет функция стоимости J из «Функции стоимости».

Если можешь пересказать: шаг спуска — прямой ход, dz=a−y, поправка против градиента; за 10 шагов ошибка упала почти на 30%, уверенность растёт асимптотически, — листай дальше.

Что дальше

Три пробела закрыты. Имя «регрессия» честно: внутри модели живёт линейная регрессия z=wTx+b, сигмоида (σ) лишь сжимает её результат в вероятность. Геометрия предсказания — прямая: граница решения проходит там, где z=0, над ней зона «кот», под ней — «не-кот», и обучение двигает эту прямую весами (w). И главная формула обратного хода dz=a−y теперь не трюк, а вывод: производная ошибки, помноженная на производную сигмоиды, схлопывается в одно вычитание — потому что кросс-энтропия согласована с сигмоидой.

Всё, что мы сделали для логистической регрессии, — прямая репетиция нейросети: предсказание слоем, ошибка, backprop, спуск. Но прежде чем разворачивать этот конвейер в матричный, векторизованный код без единого цикла по примерам, стоит закрепить сам механизм производных и обратного хода на более общем инструменте — вычислительном графе. Это тема следующего разбора.

Если можешь пересказать: регрессия внутри, прямая снаружи, dz — одно вычитание из согласованности ошибки и сигмоиды (σ), — тема усвоена.