Модуль 1. Что значит «работает»¶
После этого модуля вы сможете
- Разобрать утверждение из статьи на три части: что измерено, на чём, по сравнению с чем.
- Объяснить, почему одно число без разброса — не результат.
- Посчитать среднее, дисперсию, стандартную ошибку и доверительный интервал и сказать, что каждое из них означает.
- Построить бутстрэп-интервал и IQM руками, без библиотек.
- Проверить опубликованное заявление и получить свой ответ на вопрос «правда ли».
Время: около недели. Пререквизиты: Python, проверьте себя.
Ноутбук: notebooks/01-claim-baseline-noise.ipynb
Зачем это первым¶
Обычный курс начинается так: берём данные, обучаем модель, получаем точность 0.93. Это выглядит как результат. Это не результат.
Вот фраза из статьи:
Наш метод достигает точности 0.93 на этом наборе данных, превосходя предыдущий результат 0.91.
Прежде чем поверить, надо спросить четыре вещи.
Точность чего. «Точность» — семейство величин, а не величина.
На чём. Та ли это выборка, на которой мерили 0.91.
Сколько раз запускали и какой был разброс. Если со вторым зерном ГПСЧ метод даёт 0.90, то 0.93 было удачей, а не улучшением.
С чем сравнивают. Предыдущий метод настраивали так же тщательно, как свой, — или взяли из статьи трёхлетней давности с настройками по умолчанию.
Ни один из четырёх вопросов не требует знания машинного обучения. Все четыре требуют привычки и немного арифметики.
Модуль стоит первым не потому, что он простой, а потому, что без него следующие двадцать шесть бессмысленны. Модель, про которую вы не умеете сказать, работает ли она, не отличается от модели, которая не работает.
Три части утверждения¶
Любое утверждение о результате раскладывается на три части. Не две — три.
Величина. Что измеряли. «Точность» — это доля верных ответов, F1, AUC или точность на редком классе. В обучении с подкреплением «награда» — сумма за эпизод, средняя за шаг, дисконтированная или нет. Половина несравнимых сравнений в литературе — это сравнение разных величин под одним словом.
Условия. На каких данных, в какой постановке, с каким бюджетом. Модель на десять эпох и модель на сто — разные условия. Метод с двадцатью настроенными гиперпараметрами и метод из коробки — тоже.
База сравнения. С чем именно «лучше». Самая важная часть и самая часто испорченная.
Разберём
На задаче управления запасами с нестационарным спросом обученная политика даёт прибыль 274.0 против 240.7 у лучшей фиксированной политики base-stock. Числа — межквартильное среднее по пяти зёрнам с 95-процентным бутстрэп-интервалом [247.3, 280.4].
Величина: прибыль за эпизод, сведённая межквартильным средним. Условия: нестационарный спрос, пять зёрен. База: лучшая фиксированная base-stock — не наивная, а найденная перебором лучшая в своём классе.
Теперь чего здесь нет: у базы не указан интервал. Это не обман, база детерминирована. Но из текста это не следует, и хороший читатель споткнётся. Вы споткнулись?
База сравнения¶
«Наш метод даёт 0.93» — пустое утверждение. Значение имеет разница с тем, что было бы без метода.
Три уровня базы, от бесполезной к честной.
Тривиальная. Что даст константный ответ. Если 95 % писем не спам, классификатор «всё не спам» даёт точность 0.95. Метод с точностью 0.93 хуже, чем ничего, а в статье это будет написано как «достигает 0.93». Проверка занимает минуту и отсеивает удивительно много.
Простая. Что даст самый скучный разумный метод: логистическая регрессия, бустинг из коробки, скользящее среднее для временного ряда, формула из учебника для задачи запасов. В таблицах ML-статей эта строка отсутствует чаще, чем присутствует.
Настроенная. Тот же скучный метод, которому дали столько же попыток настройки, сколько своему. Вот это честное сравнение. Встречается редко, потому что регулярно показывает, что улучшения нет.
Асимметрия усилий
Самый частый способ получить улучшение, которого нет, — не подделка данных. Это разная тщательность. Свой метод настраивают неделю, базовый берут из чужого репозитория с настройками по умолчанию. Формально всё честно: числа настоящие, код открыт. Содержательно сравнивают не методы, а количество вложенного труда.
Читая статью, ищите фразу о том, как настраивали базу. Её отсутствие — сигнал.
Шум¶
Теперь главное. Запустите обучение дважды, поменяв только зерно генератора случайных чисел. Числа будут разные. Разные не в шестом знаке: в обучении с подкреплением разброс между зёрнами регулярно больше, чем разница между методами.
Откуда случайность: инициализация весов, порядок перемешивания данных, разбиение на обучение и тест, dropout, сама среда.
Отсюда следует неприятное:
Число из одного запуска — не свойство метода. Это одно наблюдение случайной величины.
Сравнить два таких числа — то же самое, что бросить кубик дважды и по 5 против 3 заключить, что первый кубик лучше.
Что считать вместо¶
Запустить \(n\) раз с разными зёрнами и работать с распределением результатов.
Пусть \(x_1, \dots, x_n\) — результаты \(n\) запусков.
Среднее — центр:
Выборочная дисперсия — насколько результаты разбросаны вокруг центра:
Почему \(n-1\), а не \(n\)
Потому что \(\bar{x}\) посчитано по этим же данным. Отклонения от собственного среднего систематически меньше отклонений от истинного, и деление на \(n-1\) ровно это компенсирует: оценка получается несмещённой. Проверяется численно за восемь строк — это первое задание в ноутбуке.
Стандартное отклонение \(s = \sqrt{s^2}\) — разброс в тех же единицах, что и величина.
Стандартная ошибка среднего — насколько точно мы знаем центр:
Это разные вещи, и их путают постоянно. \(s\) — насколько разбросаны запуски. \(\mathrm{SE}\) — насколько разбросано было бы среднее, если повторить весь эксперимент из \(n\) запусков заново. Смотрите на \(\sqrt{n}\): чтобы уточнить среднее вдвое, нужно вчетверо больше запусков. Из-за этого в статьях так часто стоит \(n = 3\).
Доверительный интервал примерно 95 %:
Читается так: если повторять весь эксперимент много раз, примерно в 95 % случаев построенный интервал накроет истинное значение. Он не означает «истинное значение лежит здесь с вероятностью 0.95». Истинное значение не случайно — случаен интервал.
Правило перекрытия¶
Практическое правило: интервалы двух методов перекрываются — разница не показана.
Не «методы одинаковы». Не показана. Разница может быть, но данных мало.
Правило грубое и консервативное. Оно отсекает большинство случаев, где улучшение объявлено на шуме, и это первый фильтр при чтении статьи.
Когда среднее врёт¶
У среднего неприятное свойство: один выброс тянет его целиком. В обучении с подкреплением это происходит постоянно — часть запусков расходится, часть попадает в удачный режим.
Пять запусков: 10, 11, 9, 10, 60. Среднее — 20. Такого результата не показал ни один
запуск.
Отсюда две устойчивые сводки.
Медиана — значение посередине упорядоченного списка. Устойчива, но выбрасывает почти всю информацию: при \(n = 5\) она опирается на одно наблюдение.
Межквартильное среднее (IQM) — отбросить худшую и лучшую четверть, усреднить середину. Устойчивее среднего, информативнее медианы. Стандарт в современных работах по RL, и именно его вы видели в примере выше.
Формула страшнее, чем есть: отсортировать, отрезать по четверти с краёв, усреднить остаток. Три строки на NumPy.
Бутстрэп¶
Для IQM простой формулы стандартной ошибки нет. Она и не нужна.
Бутстрэп: много раз извлечь из наших \(n\) результатов выборку размера \(n\) с возвращением, посчитать статистику на каждой, взять 2.5-й и 97.5-й процентили полученного распределения.
Работает это потому, что наша выборка — лучшее приближение к тому, откуда пришли данные. Пересэмплируя из неё, мы имитируем повторение эксперимента.
def bootstrap_ci(values, statistic, n_resamples=10_000, seed=0):
"""95% доверительный интервал для любой статистики.
Пересэмплирование с возвращением имитирует повторение эксперимента:
выборка — наше лучшее приближение к тому, откуда пришли данные.
"""
rng = np.random.default_rng(seed)
values = np.asarray(values)
draws = rng.choice(values, size=(n_resamples, len(values)), replace=True)
stats = np.array([statistic(row) for row in draws])
return np.percentile(stats, [2.5, 97.5])
Одиннадцать строк. Работает для среднего, медианы, IQM, доли — для чего угодно. Самый полезный кусок кода в курсе.
Честное ограничение
Бутстрэп не создаёт информацию. При \(n = 3\) он даст интервал, и этот интервал будет бессодержательным, потому что три числа мало говорят о распределении. Пять зёрен и широкие интервалы в статье — это не недостаток, а честность. Недостаток — три зерна и интервалов нет вовсе.
Практика¶
Часть 1. Ноутбук¶
Откройте notebooks/01-claim-baseline-noise.ipynb.
Он проходит путь целиком на симулированном эксперименте, где истинный ответ известен заранее. На настоящих данных истину не видно, и понять, где оценка врёт, невозможно. Здесь — видно.
Что внутри:
- Численная проверка, зачем \(n-1\) в дисперсии.
- Два «метода» с известной истинной разницей. Сколько зёрен нужно, чтобы её увидеть.
- Как часто при \(n = 3\) худший метод объявляется лучшим. Считаем, а не гадаем.
- Среднее против IQM на распределении с выбросами.
- Бутстрэп-интервалы, написанные с нуля.
Пройдите его дважды, как описано в правилах учёбы: первый раз целиком, второй — ломая.
Часть 2. Настоящее заявление¶
Теория без применения не откладывается. Берём опубликованное утверждение и проверяем сами.
В библиотеке decisionrl заявлено: на задаче
управления запасами с нестационарным спросом обученная политика даёт 274.0 прибыли против
240.7 у лучшей фиксированной base-stock. Числа получены скриптом
examples/verify_applied_claims.py
из того же репозитория. Это редкий и правильный случай: заявление приложено вместе со
способом его проверить.
pip install "decisionrl[gym]"
git clone https://github.com/DrobyshevDev/decisionrl
cd decisionrl
python examples/verify_applied_claims.py
Прогон требует терпения, а не видеокарты. Пока считает, ответьте письменно:
- Какая величина сравнивается и на скольких зёрнах.
- Что такое «лучшая фиксированная base-stock» и почему это более сильная база, чем просто base-stock.
- Перекрываются ли интервалы обученной политики и базы.
- У базы интервал не указан. Обоснованно ли это здесь? В каком случае было бы нет?
Посчиталось — сравните с опубликованным. Расхождение — нормальный результат, а не провал. Другая версия PyTorch, другое железо, другие зёрна. Вопрос не «совпало ли», а «попадает ли ваше число в опубликованный интервал, и если нет, то на сколько мимо».
Ровно эту работу вы будете делать в модуле 26 с настоящей статьёй. Здесь тренировка на задаче, где код заведомо запускается.
Шесть способов ошибиться¶
Не обманом. Все шесть регулярно случаются с добросовестными людьми, включая вас в ближайшие полгода.
1. Выбор зерна. Запустили пять раз, показали лучший. Формально число настоящее. Защита: набор зёрен фиксируется до эксперимента, показываются все.
2. Асимметрия настройки. Свой метод настраивали неделю, базовый — из коробки. Защита: одинаковый бюджет настройки, и написать, какой.
3. Подглядывание в тест. Смотрели на тестовую метрику, меняли модель, снова смотрели. Через двадцать итераций тест перестал быть тестом: вы настроились на него через себя. Защита: решения принимаются по валидационной выборке, тест открывается один раз.
4. Утечка. Признак, которого в момент предсказания не существует. Нормализация, посчитанная по всем данным до разбиения. Дубликаты, попавшие и в обучение, и в тест. Защита: про каждый признак спросить — был бы он известен в момент, когда предсказание реально нужно?
5. Остановка по результату. Смотрели на метрику по ходу и остановились, когда стало хорошо. Это выбор зерна во времени. Защита: критерий остановки фиксируется заранее.
6. Множественные сравнения. Проверили двадцать вариантов, один дал улучшение с \(p < 0.05\). При двадцати проверках один ложный результат ожидается по построению. Защита: поправка на множественность или честное «мы проверили двадцать».
Как этим пользоваться
Это не список для чтения чужих статей, а чек-лист для собственной работы. Ваш метод показал улучшение — пройдите по шести пунктам, прежде чем радоваться. Примерно в половине случаев радоваться будет нечему, и лучше узнать это самому.
Задание¶
Возьмите любую задачу с числовым результатом: из ноутбука, из decisionrl, из своего проекта.
- Сформулируйте утверждение письменно, разложив на три части: величина, условия, база.
- Выберите базу и обоснуйте, почему она честная. Тривиальную посчитайте обязательно.
- Запустите не меньше десяти зёрен. Зёрна выберите до запуска и запишите.
- Посчитайте среднее, IQM и бутстрэп-интервалы для обоих.
- Напишите вывод одним предложением — таким, которое вы готовы защищать.
- Отдельным абзацем: какой из шести способов ошибиться наиболее вероятен именно здесь и что вы сделали, чтобы его исключить.
Шестой пункт самый важный. Он же единственный, который нельзя списать.
Проверка себя¶
Ответьте вслух, не подглядывая. Не получается — это адрес того, что перечитать.
- Чем стандартное отклонение отличается от стандартной ошибки среднего? Что произойдёт с каждым, если увеличить число запусков вчетверо?
- Почему в формуле дисперсии \(n-1\)?
- Что означает 95-процентный доверительный интервал? Сформулируйте так, чтобы не сказать «истинное значение лежит здесь с вероятностью 0.95».
- Интервалы двух методов перекрываются. Что можно утверждать? Чего нельзя?
- Зачем нужен IQM, если есть среднее и медиана?
- Объясните бутстрэп человеку, знающему только среднее арифметическое.
- Метод даёт точность 0.95. Какой первый вопрос вы зададите?
- Почему сравнение настроенного метода с ненастроенной базой — не обман, но и не результат?
Дальше¶
В модуле 2 появится язык, на котором всё это описывается точно: случайная величина, распределение, оценка параметра. Вопрос «сколько зёрен нужно» получит ответ формулой, а не перебором.
А привычку заводите сейчас и не бросайте до конца курса:
Увидели число — спросите, с чем сравнивают и сколько раз запускали.
Это две трети критического чтения статей. Оставшаяся треть — предмет части VII.
Принцип
Зелёный пайплайн на одной машине — не доказательство. Каждое число, которое вы публикуете, измерено на том прогоне, который вы описываете.