Регрессия и распределение шума
В задачах регрессии обычно предполагают, что есть какая-то неизвестная нам «
настоящая» зависимость таргета от входа, а
наблюдаемые таргеты получаются из «
настоящих» добавлением нормального шума с нулевым матожиданием и постоянной дисперсией. Это предположение ведет к квадратичной функции потерь (L2).
Но часто это предположение ломается: дисперсия шума может быть
непостоянной, а само распределение — не нормальным. Например, так распределены деньги, которые пользователи приносят сервису за какой-то период.
Если у вас есть задача регрессии, вы можете построить гистограмму ошибок и проверить, похожа ли она на нормальное распределение.
Интуитивно хочется к таким криво распределенным таргетам сначала применить какое-то преобразование (скажем, логарифм), после которого они станут относительно нормальными, решить задачу регрессии в преобразованной шкале, а потом уже предсказания перевести в исходную шкалу.
Когда-то в Яндексе Миша Парахин всем советовал в таких ситуациях чуть более принципиальный подход: в качестве этого преобразования использовать
CDF (функцию распределения) исходного распределения таргетов (оцененную по датасету) и затем обратную CDF нормального распределения. Тогда преобразованные таргеты как раз будут нормально распределены (правда, тут некоторая подмена понятия — вообще говоря, нам нужно нормальное распределение шума/ошибок, а не самих таргетов).
Но у этих подходов есть проблема — они не
mean-proper.
Mean-proper функции ошибок — это у которых минимум достигается, когда предсказание равно матожиданию таргета. Например, L2 (MSE) или Binary Cross-Entropy (в случае бинарных таргетов) — mean-proper. А вот L1 (MAE), MAPE, MSE логарифмов — нет. Попросту говоря, при использовании таких лоссов предсказания будут смещенными. Я когда-то уже
писал про это для логарифмов.Это свойство (mean-proper) часто довольно важно. Например, хотелось бы, чтобы сумма наших предсказаний доходов по какому-то сегменту пользователей примерно попадала в настоящие суммарные доходы.
Поэтому я к этим трюкам с преобразованием таргета всегда относился скептически — не хочется терять калиброванность из-за того, что шум как-то не так распределен. И вообще, казалось бы, как бы ни был распределен шум, практика нас обычно учит: что вы хотите улучшить на test set — то и оптимизируйте на train set. Хотите MSE — используйте MSE. Просто разные лоссы ведут к разным компромиссам, когда не получается точно описать данные. Так ведь?
Оказалось — нет. За последние несколько дней я провёл небольшой эксперимент на искусственных данных. Пусть у нас одномерный случай,
x распределен равномерно на [0, 1], «настоящая» зависимость выглядит как
z = exp(a*x + b), а наблюдаемые таргеты сэмплируются не из нормального, а из экспоненциального распределения с матожиданием
z(x). Обучаем модель
y_pred = exp(a*x + b), т.е. просто подбираем параметры
a и
b по датасету, используя либо обычный L2 loss, либо специальный экспоненциальный лосс
log(y_pred) + y / y_pred — это negative log-likelihood экспоненциального распределения (он тоже mean-proper!).
И оказалось, что экспоненциальный лосс даёт лучшее качество, чем L2, даже по MSE! Особенно, когда обучающих данных немного (когда много — L2 догоняет по качеству).
Конечно, в реальных случаях у нас данных сильно больше, чем тут. Но и зависимости у нас сложнее, и фичей сильно больше, и особенно для спарс-фичей — разреженность данных может быть ещё сильнее.
Эксперимент показал, что лосс, адаптированный к настоящему распределению шума, ведёт именно к
лучшей генерализации — а не просто к другому компромиссу.
Иллюстрация (cherry-pick) — ниже. Типичная чувствительность L2 к выбросам.
P.S. Эксперимент выглядит очень простым. Но пока я его делал, я напоролся на несколько удивительных подводных камней. Оказалось, что использование
1) линейной зависимости
z = a*x + b (без
exp)
2) оптимизаторов Adam и (S)GD
3)
mean(x) ± 2 * std(x) / sqrt(N) в качестве доверительного интервала среднего
— всё это делает эксперимент очень нестабильным. Угадайте, почему 😉