Зачем она нужна
Модель предсказывает цену квартиры, время доставки, спрос на товар. Первый вопрос заказчика: «На сколько она ошибается?» Ответ «в среднем на 4 минуты» или «на 120 тысяч» — это и есть MAE (mean absolute error), средняя абсолютная ошибка. Её понимает любой человек без статистического образования, потому что она измеряется в тех же единицах, что и сама величина.
Где она встречается:
- метрика качества регрессии — прогноз спроса, времени в пути, цен, нагрузки на серверы; в отчётах её ставят рядом с RMSE;
- функция потерь —
L1Lossв PyTorch; её берут, когда в данных есть выбросы или нужен прогноз медианы, а не среднего; - компьютерное зрение — L1 по пикселям в pix2pix и в задачах сверхразрешения (EDSR), L1 по координатам рамок в детекторе DETR;
- градиентный бустинг —
loss="absolute_error"в scikit-learn,objective="l1"в LightGBM: значения в листьях — медианы остатков; - робастная статистика — регрессия наименьших модулей (least absolute deviations, LAD), квантильная регрессия, медиана как оценка «типичного» значения.
MAE — среднее расстояние от прогноза до правды: $\frac1n\sum|y_i-\hat y_i|$. Каждая ошибка входит линейно: промах на 2 весит как четыре промаха по $0{,}5$. Поэтому MAE устойчива к выбросам, а лучшая константа для неё — медиана. Цена за это — излом в нуле: производная есть везде, кроме точки, где ошибка равна нулю, и её модуль не уменьшается у минимума.
Интуиция: средняя длина промаха
Нарисуем правду $y_i$ точками, прогнозы $\hat y_i$ — синими маркерами, а ошибку — вертикальным отрезком между ними. MAE — это средняя длина оранжевых отрезков. Направление не важно: недолёт и перелёт на одно и то же расстояние стоят одинаково.
Ниже — сквозной пример шпаргалки: $y=(3;\,5;\,8)$, $\hat y=(2{,}5;\,5;\,10)$. Тяните синие маркеры. На нижнем графике каждая ошибка $e_i=y_i-\hat y_i$ стоит на «галочке» $|e|$; MAE — средняя высота этих точек (бирюзовая линия).
Самая большая ошибка, $2$, даёт $80\%$ суммы модулей ($2$ из $2{,}5$). В MSE та же ошибка дала бы $94\%$ суммы квадратов ($4$ из $4{,}25$). MAE «демократичнее»: она не позволяет одному большому промаху заслонить остальные.
Формула по косточкам
Разберём формулу на четыре действия и посмотрим, что делает каждое.
- $y_i$
- истинное значение для объекта $i$ (цена, время, спрос);
- $\hat y_i$
- прогноз модели для того же объекта;
- $e_i=y_i-\hat y_i$
- ошибка (остаток, residual): положительная — модель недооценила, отрицательная — переоценила;
- $|e_i|$
- модуль убирает знак, чтобы недолёт и перелёт не гасили друг друга; $|e|=\sqrt{e^2}$ — расстояние на числовой прямой;
- $\frac1n\sum$
- усреднение делает метрику независимой от размера выборки: MAE на 100 и на 10 000 объектах можно сравнивать.
Почему нельзя обойтись без модуля? Средняя ошибка без него, $\frac1n\sum e_i$, на нашем примере равна $(0{,}5+0-2)/3=-0{,}5$, и её можно сделать нулевой при сколь угодно плохой модели: ошибки $+100$ и $-100$ в среднем дают ноль. Эта величина называется смещением (bias) — полезная, но другая метрика.
| $i$ | $y_i$ | $\hat y_i$ | $e_i$ | $|e_i|$ | $e_i^2$ |
|---|---|---|---|---|---|
| 1 | 3 | 2,5 | 0,5 | 0,5 | 0,25 |
| 2 | 5 | 5 | 0 | 0 | 0 |
| 3 | 8 | 10 | −2 | 2 | 4 |
| Сумма | 2,5 | 4,25 | |||
| Среднее | 0,833 | 1,417 |
Столбец $e_i^2$ добавлен для сравнения с MSE. В векторной записи MAE — это норма $L_1$ вектора ошибок, делённая на $n$:
Отсюда второе имя функции потерь — L1-потеря (L1 loss). Расстояние $\|y-\hat y\|_1$ называют манхэттенским: так ходит такси по сетке кварталов — сумма смещений по каждой оси.
Свойства и лучшая константа
- Неотрицательность: $\mathrm{MAE}\ge0$, и $\mathrm{MAE}=0$ только если все прогнозы точные.
- Единицы — те же, что у $y$. Масштаб переносится напрямую: если перевести рубли в тысячи рублей, MAE уменьшится ровно в 1000 раз.
- Линейный вклад ошибок: удвоение одной ошибки удваивает её вклад, а не учетверяет, как в MSE.
- Выпуклость: модуль выпуклый, сумма выпуклых функций выпукла, поэтому у MAE нет «ложных» локальных минимумов — ни по прогнозам, ни по параметрам линейной модели. Но выпуклость нестрогая: минимум может быть не единственным.
- Кусочная линейность: как функция прогнозов MAE состоит из линейных кусков, склеенных по изломам там, где какая-то ошибка равна нулю. В изломах производной нет.
- Связь с RMSE: $\mathrm{MAE}\le\mathrm{RMSE}\le\sqrt n\,\mathrm{MAE}$. В примере: $0{,}833\le1{,}190\le1{,}443$. Чем больше отношение RMSE/MAE, тем «тяжелее хвосты» ошибок.
Лучшая константа — медиана
Пусть модель совсем простая: для всех объектов она отвечает одним и тем же числом $c$. Какое $c$ лучшее по MAE? Функция $\mathrm{MAE}(c)=\frac1n\sum|y_i-c|$ — сумма «галочек» с вершинами в точках данных. Её наклон в любой точке между данными равен
Пока слева от $c$ меньше половины точек, наклон отрицательный, и $c$ выгодно двигать вправо; когда слева больше половины — наклон положительный. Минимум там, где точки делятся пополам, то есть в медиане.
Доказательство: минимум MAE(c) достигается ровно на медианах
Упорядочим данные: $y_{(1)}\le\dots\le y_{(n)}$. Функция $f(c)=\sum|y_i-c|$ выпукла и кусочно линейна. В точке $c$, не совпадающей с данными, её производная равна $L(c)-R(c)$, где $L$ и $R$ — число точек слева и справа. В точке данных $c=y_{(k)}$ (пусть она встречается один раз) субдифференциал — отрезок $[L-R-1;\;L-R+1]$.
Для выпуклой функции $c^*$ — точка минимума тогда и только тогда, когда $0\in\partial f(c^*)$. При нечётном $n=2m+1$ это выполняется только в $c^*=y_{(m+1)}$: там $L=R=m$, и $0\in[-1;\,1]$. Левее медианы $L-R\le-1$ и производная отрицательна, правее — положительна. Значит, минимум единственный.
При чётном $n=2m$ для любого $c$ строго между $y_{(m)}$ и $y_{(m+1)}$ имеем $L=R=m$: производная равна нулю, функция там постоянна, и по непрерывности минимумы — весь отрезок $[y_{(m)};\,y_{(m+1)}]$ вместе с концами. Обычная договорённость «медиана $=(y_{(m)}+y_{(m+1)})/2$» — лишь один из равноправных ответов.
Медиана почти не реагирует на крайние значения: если $16$ заменить на $1600$, медиана останется $5$, а среднее улетит к $323{,}8$. Модель, обученная на MAE, ведёт себя так же: она предсказывает условную медиану $y$ при данных признаках, а не условное среднее.
Производная: знак ошибки и субградиент
Производная модуля — это знак: $|e|'=\operatorname{sign}(e)$ при $e\ne0$. В нуле у «галочки» излом, и обычной производной нет. Выпуклый анализ предлагает замену — субградиент.
Вывод: производная MAE по прогнозам и по параметрам
Запишем $|e|=\sqrt{e^2}$ и продифференцируем при $e\ne0$:
Ошибка зависит от прогноза так: $e_i=y_i-\hat y_i$, поэтому $\partial e_i/\partial\hat y_i=-1$. По цепному правилу:
Если прогноз даёт линейная модель $\hat y_i=wx_i+b$, то $\partial\hat y_i/\partial w=x_i$, $\partial\hat y_i/\partial b=1$, и
В градиент входит только знак каждой ошибки, а не её размер. Объект с ошибкой $0{,}1$ и объект с ошибкой $100$ тянут параметры с одинаковой силой $1/n$.
Субградиент выпуклой функции $f$ в точке $x$ — любое число $g$, для которого прямая $f(x)+g\,(z-x)$ нигде не поднимается выше графика: $f(z)\ge f(x)+g\,(z-x)$ для всех $z$. Для $|e|$ в нуле это все $g$ с $|g|\le1$: любую прямую через начало координат с наклоном от $-1$ до $1$ можно «подложить» под галочку. Множество субградиентов называется субдифференциалом.
Фреймворки не хранят множество субградиентов: PyTorch, TensorFlow и NumPy считают $\operatorname{sign}(0)=0$. Это законный выбор — $0\in[-1;\,1]$. Вторая производная модуля равна нулю везде, кроме излома, поэтому методы, которым нужен гессиан (метод Ньютона, листья XGBoost по формуле $-G/H$), с MAE напрямую не работают: в бустинге значения листьев для MAE пересчитывают как медианы остатков.
Устойчивость к выбросам
Выброс (outlier) — объект с аномальным $y$: опечатка, сбой датчика, редкое событие. Для потери важно, с какой силой такой объект тянет модель. У MSE сила пропорциональна ошибке ($2e/n$), у MAE она ограничена: $1/n$, как бы далеко ни лежала точка.
Обратите внимание на поведение синей прямой: пока выброс ниже неё, его можно тащить вниз сколько угодно — прямая не сдвинется вообще. Знак его ошибки не меняется, а MAE реагирует только на знаки. Прямая MSE, наоборот, ползёт за выбросом без ограничений.
В робастной статистике устойчивость измеряют долей испорченных данных, которая может увести оценку сколь угодно далеко. У среднего она нулевая (точнее, $1/n$): одной точки достаточно. У медианы — $50\%$: пока испорчено меньше половины выборки, медиана остаётся в пределах «чистых» данных. Регрессия по MAE устойчива к выбросам по $y$, но не к точкам с аномальным $x$ (высоким рычагом, leverage) — такая точка всё ещё может развернуть прямую.
MAE в пространстве параметров: многогранник
Пусть модель — прямая $\hat y=wx+b$, данные — пять точек с $x=(-2;\,-1;\,0;\,1;\,2)$ и $y=(1{,}3;\,2;\,3{,}1;\,4{,}5;\,7)$. Каждой паре $(w;\,b)$ соответствует своя прямая и своя MAE. Получаем поверхность над плоскостью параметров.
Каждое слагаемое $|y_i-wx_i-b|$ — это «двускатная крыша» с коньком вдоль прямой $b=y_i-wx_i$, где $i$-я ошибка равна нулю. Сумма пяти крыш — многогранник: плоские грани, острые рёбра, вершины. Хотя бы один минимум всегда лежит в вершине, где пересекаются рёбра, то есть оптимальную прямую можно выбрать проходящей как минимум через две точки данных.
Две поверхности дают разные ответы: прямая MAE проходит через точки $x=-1$ и $x=1$ и почти не замечает «оттопыренную» последнюю точку $y=7$; прямая MSE наклонена круче, чтобы уменьшить её квадрат. Каждая лучше по своей мере: у прямой MSE $\mathrm{MAE}=0{,}456>0{,}39$, у прямой MAE $\mathrm{MSE}=0{,}378>0{,}229$.
Почему оптимум проходит через две точки
Задачу $\min_{w,b}\sum|y_i-wx_i-b|$ можно записать как линейную программу: введём $u_i\ge0$, $v_i\ge0$ с $y_i-wx_i-b=u_i-v_i$ и будем минимизировать $\sum(u_i+v_i)$. Если у линейной программы есть оптимум, а у допустимого множества есть вершины (здесь — если не все $x_i$ равны), то одна из оптимальных точек — вершина. В вершине в равенство обращаются столько независимых ограничений, сколько переменных, — $2n+2$. Равенств $y_i-wx_i-b=u_i-v_i$ всего $n$, значит, не меньше $n+2$ переменных $u_i,v_i$ равны нулю. Объект даёт два нуля, только если $u_i=v_i=0$, то есть его ошибка нулевая; иначе — не больше одного. Поэтому хотя бы у двух объектов ошибка равна нулю: прямая проходит через две точки.
Отсюда же — возможная неединственность: если грань многогранника горизонтальна, минимумом будет целое ребро или грань, как плоское дно $\mathrm{MAE}(c)$ при чётном $n$. Для пяти точек нашего примера минимум единственный: следующая по качеству вершина даёт $0{,}427$.
Регрессия по модулям старше метода наименьших квадратов. В 1757 году Руджер Бошкович, обрабатывая измерения длины градуса меридиана, предложил подбирать прямую так, чтобы сумма модулей отклонений была минимальной (при дополнительном условии, что сумма самих отклонений равна нулю); позже метод разобрал Лаплас. МНК Лежандр опубликовал лишь в 1805 году, но квадраты победили надолго: их минимум находится решением линейной системы, а задачу с модулями стали массово решать лишь после появления линейного программирования в середине XX века.
MAE в обучении: субградиентный спуск
Градиентный спуск делает шаг против градиента: $\theta\leftarrow\theta-\eta\,g$. С MAE возникает особенность: у минимума градиент не уменьшается. Он скачет между векторами, составленными из $\pm1/n$, и с постоянным шагом $\eta$ параметры всё время перепрыгивают через дно.
Для выпуклых функций с ограниченным субградиентом (у MAE он ограничен) теория даёт точный рецепт: при шаге $\eta_t\propto1/\sqrt t$ лучшее найденное значение сходится к минимуму со скоростью $O(\ln t/\sqrt t)$ — почти как $1/\sqrt t$. С постоянным шагом гарантирован лишь выход в окрестность оптимума: превышение $\mathrm{MAE}-\mathrm{MAE}^*$ остаётся порядка $\eta$. Поэтому на практике MAE обучают с расписанием шага (learning rate schedule) — оно нужно и SGD, и Adam, у которого шаг у дна тоже не уменьшается сам, — или заменяют потерю на гладкую функцию Хьюбера.
У MSE градиент пропорционален ошибке, поэтому шаги сами укорачиваются по мере приближения к минимуму — постоянного (не слишком большого) $\eta$ хватает для точной сходимости. У MAE «тормозов» нет: о близости к оптимуму говорит только то, что знаки ошибок начинают делиться поровну.
Обобщение: квантили и вероятностный смысл
Медиана — это квантиль уровня $0{,}5$. Если наклонить «галочку», сделав правую ветвь круче левой, минимум сдвинется к другому квантилю. Получается пинбол-потеря (pinball loss), или квантильная потеря:
При $\tau=0{,}9$ недооценка ($e>0$) штрафуется в девять раз сильнее переоценки, и оптимальная константа — $90\%$-й квантиль. Так строят прогнозные интервалы: модель для $\tau=0{,}1$ и модель для $\tau=0{,}9$ дают коридор, в который должно попадать около $80\%$ наблюдений.
Для оптимальной прямой доля точек ниже неё не больше $\tau$, а доля точек ниже или на ней — не меньше $\tau$: $53/60\le0{,}9\le55/60$. Это прямое следствие условия $0\in\partial$ — того же, что дало медиану.
MAE как метод максимального правдоподобия
Пусть $y_i=\hat y_i+\varepsilon_i$, где шум $\varepsilon$ имеет распределение Лапласа с плотностью $p(\varepsilon)=\frac{1}{2s}e^{-|\varepsilon|/s}$. Тогда отрицательный логарифм правдоподобия
При фиксированном $s$ максимизировать правдоподобие — то же, что минимизировать MAE, а оценка масштаба шума — сама MAE: $\hat s=\mathrm{MAE}$. Выбирая MAE, мы неявно предполагаем шум с «тяжёлыми» (по сравнению с гауссовским) хвостами. Для MSE та же логика приводит к нормальному шуму — см. MSE.
В коде
MAE считается в одну строку. Интереснее — субградиент и обучение. В NumPy:
pythonimport numpy as np
y = np.array([3.0, 5.0, 8.0])
y_hat = np.array([2.5, 5.0, 10.0])
def mae(y, y_hat):
return np.mean(np.abs(y - y_hat))
def mae_grad(y, y_hat):
# субградиент по прогнозам: sign(ŷ − y) / n, в нуле берём 0
return np.sign(y_hat - y) / y.size
print(mae(y, y_hat)) # 0.8333333333333334
print(mae_grad(y, y_hat)) # [-0.33333333 0. 0.33333333]
# лучшая константа по MAE — медиана, а не среднее
data = np.array([2.0, 3.0, 5.0, 9.0, 16.0])
print(np.median(data), mae(data, np.median(data))) # 5.0 4.0
print(data.mean(), mae(data, data.mean())) # 7.0 4.4
В PyTorch потеря называется L1Loss. Обратите внимание на градиент: у второго объекта ошибка ровно ноль, и фреймворк берёт субградиент $0$. Вторая часть листинга обучает прямую рисунков 5–6 с убывающим шагом:
pythonimport torch
import torch.nn as nn
y = torch.tensor([3.0, 5.0, 8.0])
y_hat = torch.tensor([2.5, 5.0, 10.0], requires_grad=True)
loss = nn.L1Loss()(y_hat, y) # то же, что (y_hat - y).abs().mean()
loss.backward()
print(loss.item()) # 0.8333333134651184
print(y_hat.grad) # tensor([-0.3333, 0.0000, 0.3333])
# линейная модель по MAE: шаг убывает как 1/√t
x = torch.tensor([-2.0, -1.0, 0.0, 1.0, 2.0])
t = torch.tensor([1.3, 2.0, 3.1, 4.5, 7.0])
w = torch.zeros(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)
opt = torch.optim.SGD([w, b], lr=0.5)
sched = torch.optim.lr_scheduler.LambdaLR(opt, lambda k: 1 / (k + 1) ** 0.5)
for step in range(3000):
opt.zero_grad()
nn.functional.l1_loss(w * x + b, t).backward()
opt.step(); sched.step()
print(round(w.item(), 2), round(b.item(), 2)) # 1.25 3.25 — прямая через 2 точки
В scikit-learn есть метрика, точная линейная регрессия по MAE (через линейную программу) и бустинг с MAE:
pythonimport numpy as np
from sklearn.metrics import mean_absolute_error
from sklearn.linear_model import QuantileRegressor
from sklearn.ensemble import HistGradientBoostingRegressor
print(mean_absolute_error([3, 5, 8], [2.5, 5, 10])) # 0.8333333333333334
# линейная регрессия по MAE — это квантильная регрессия с τ = 0,5
X = np.array([[-2.0], [-1.0], [0.0], [1.0], [2.0]])
y = np.array([1.3, 2.0, 3.1, 4.5, 7.0])
lad = QuantileRegressor(quantile=0.5, alpha=0.0).fit(X, y) # alpha=0 — без L1-штрафа (по умолчанию 1.0)
print(lad.coef_, lad.intercept_) # [1.25] 3.25
# бустинг на MAE: значения в листьях — медианы остатков
gbr = HistGradientBoostingRegressor(loss="absolute_error")
Если нужна MAE как метрика — считайте её как есть. Если как потеря для градиентного спуска — уменьшайте шаг по расписанию или берите Хьюбера с малым $\delta$: та же устойчивость к выбросам, но гладкий минимум.
Частые ошибки
- Забыть модуль:
np.mean(y - y_hat)— это смещение, а не MAE. Ошибки разных знаков гасят друг друга, и плохая модель может получить ноль. - Сравнивать MAE разных задач. MAE $=5$ для цен в тысячах и для температуры в градусах — несравнимые числа. Для сравнения между масштабами есть MAPE или MAE, делённая на MAE простой базовой модели.
- Учить на MSE, а отчитываться MAE (или наоборот). MSE ведёт модель к условному среднему, MAE — к медиане. На скошенных данных (цены, доходы, время ожидания) это разные числа, и модель, лучшая по одной метрике, обычно уступает по другой.
- Постоянный шаг с MAE-потерей. Параметры будут дрожать у минимума с амплитудой порядка $\eta$. Нужно расписание шага или сглаженная потеря.
- Ждать единственного решения. Минимум MAE может быть целым отрезком (чётное число точек) или ребром многогранника. Разные решатели вернут разные, но одинаково хорошие ответы.
- Считать MAE «типичной ошибкой» без оглядки на хвост. MAE $=1$ может скрывать редкие промахи на 50. Смотрите на распределение ошибок, квантили и RMSE рядом с MAE.
Связи с другими формулами
- MSE: квадрат вместо модуля — гладкость и среднее вместо медианы, но чувствительность к выбросам.
- RMSE: $\mathrm{RMSE}\ge\mathrm{MAE}$. Для нормальных ошибок $\mathrm{RMSE}/\mathrm{MAE}=\sqrt{\pi/2}\approx1{,}253$, для лапласовских $\sqrt2\approx1{,}414$; в сквозном примере $1{,}428$.
- Функция Хьюбера: квадрат около нуля и модуль вдали — гладкий минимум и устойчивость к выбросам одновременно.
- MAPE: та же MAE, но от относительных ошибок $|e_i|/|y_i|$.
- SGD и Adam: оптимизаторы, которым с MAE нужен убывающий шаг.
Итоги
1) $\mathrm{MAE}=\frac1n\sum|y_i-\hat y_i|$ — средняя длина промаха в единицах $y$; в сквозном примере $0{,}833$. 2) Ошибки входят линейно, поэтому MAE устойчива к выбросам, а лучшая константа — медиана (при чётном $n$ — любая точка между двумя центральными значениями). 3) Производная — $-\operatorname{sign}(e_i)/n$; в нуле субдифференциал $[-1;\,1]$, на практике берут $0$. 4) Поверхность MAE по параметрам — многогранник; среди оптимальных прямых всегда есть проходящая через две точки данных. 5) Градиент не убывает у минимума: учите с убывающим шагом или берите Хьюбера. 6) Наклонная «галочка» — пинбол-потеря — даёт квантили; MAE соответствует шуму Лапласа.