Когда несколько агентов действительно лучше одного длинного промпта?
Финальный проект не обязан быть самой сложной моделью курса. Он обязан провести
одну проверяемую мысль через данные, baseline, протокол, ошибки и публичную защиту
так, чтобы другой человек мог воспроизвести вывод — и, если тот неверен, опровергнуть
его вашими же средствами.
Вопрос раньше технологии
«Сделать ИИ для городского транспорта» не проверяется. «Можно ли по открытым
почасовым данным велопроката предсказать спрос на следующий час точнее, чем среднее
по этому часу и типу дня?» уже задаёт объект, горизонт и соперника. Второй вопрос
можно проиграть — и именно поэтому его стоит задавать.
Сильный вопрос содержит наблюдаемую единицу, признаки, доступные к моменту решения,
target, горизонт, baseline, критерий успеха, границы применимости и предполагаемого
пользователя результата. Если хотя бы один пункт отсутствует, спор о результате
превращается в спор о вкусах.
Перед выбором темы найдите одно реальное решение, которое изменится. Если прогноз не
меняет ничьё действие, вам нужна не предсказательная модель, а исследовательская
визуализация — и это честный, а не запасной жанр.
Весь этот урок мы будем проверять один вопрос на реальных данных — на почасовом
велопрокате из курса (урок 49 и урок 50 уже опирались на
него). Не потому, что тема лучшая, а потому, что каждое утверждение здесь можно
пересчитать за минуту на своей машине и увидеть, где протокол ломается.
Паспорт задачи до первой строки кода
До кода заполняются двенадцать строк: вопрос и гипотеза; происхождение данных,
лицензия, дата и объём; единица наблюдения; target и момент его доступности; split;
baseline; основная и защитные метрики; риски утечки; группы и режимы для анализа
ошибок; вычислительный бюджет; формат интерактива; условие остановки.
Паспорт — это не бюрократия, а фиксация степеней свободы. Всё, что не записано до
эксперимента, потом незаметно подстроится под желаемый результат: сдвинется период,
поменяется метрика, «уточнится» порог.
Наш контракт на весь урок: данные — UCI Bike Sharing, почасовой файл hour.csv,
17 379 строк с 1 января 2011 по 31 декабря 2012 года; единица наблюдения — один час
проката; target — cnt, число поездок за час (среднее 189,5, медиана 142, максимум
977); метрика — средняя абсолютная ошибка
MAE=n1i=1∑nyi−yi;
протокол — разбиение по времени; baseline — среднее по часу и типу дня; условие
остановки — один прогон по тесту после фиксации всего перечисленного.
Скошенность видна сразу и определяет выбор метрики. Минимум E∣y−c∣
достигается на медиане, минимум E(y−c)2 — на среднем:
argcminE∣y−c∣=med(y),argcminE(y−c)2=Ey.
Именно поэтому константный baseline мы строим по медиане обучающей части: она равна
124 поездкам в час и на тесте даёт MAE=161,1.
Разбиение — это гипотеза о будущем
Разбиение выборки — не техническая деталь, а утверждение о том, как модель будет
использоваться. Если система работает по схеме «сегодня учим, завтра предсказываем»,
проверка обязана иметь ту же форму: обучение на прошлом, оценка на будущем.
train={t≤T1},val={T1<t≤T2},test={t>T2}.
У нас T1= 30 июня 2012 года, T2= 30 сентября 2012 года: 13 003 часа обучения,
2 208 часов валидации, 2 168 часов теста (92 календарных дня). Никакая настройка не
имеет права заглядывать за T2.
Теперь эксперимент. Обучим один и тот же градиентный бустинг двумя способами: по
временному разбиению и по случайному перемешиванию тех же строк (обучение и валидация
того же размера, только выбраны случайно). Октябрь–декабрь в обоих случаях отложен и
не участвует в обучении ни в одной конфигурации.
Случайное перемешивание почасового ряда даёт отчётную ошибку 23,1 поездки в час,
тогда как на честно отложенном октябре–декабре та же модель ошибается на 42,3 — в
1,83 раза больше. Временное разбиение отчитывается о 40,4 и получает 45,5: разрыв
всего 1,13. Модель, признаки и гиперпараметры одинаковы; различается только протокол.
Причина проста: соседние часы одного дня почти одинаковы. При перемешивании час 14:00
попадает в обучение, а 15:00 того же дня — в проверку, и модель фактически
подсматривает ответ. Это утечка через структуру данных, а не через код.
Лаборатория протокола
Меняйте протокол — смотрите, во что превращается отчёт
График шире экрана — листайте по горизонтали →
Загружается живая иллюстрация…
Переключатели меняют только протокол: разбиение (по времени или случайное) и набор
признаков (честные или с утечкой). Золотая полоса — ошибка, о которой вы отчитались;
синяя — ошибка на отложенном будущем. Ползунок сокращает обучающую выборку.
Проверьте три вещи. Первая: при случайном разбиении разрыв держится около 1,8 раза и
не исчезает с ростом данных — плохой протокол не лечится объёмом. Вторая: с «утечными»
признаками обе полосы падают примерно до трёх поездок в час, и разрыв исчезает, то
есть разбиение вообще не видит эту болезнь. Третья: честная конфигурация даёт худшие
числа и единственно осмысленный вывод.
Утечка, которую не ловит никакое разбиение
В файле есть колонки casual и registered — число случайных и зарегистрированных
клиентов за час. Их сумма тождественно равна target:
casuali+registeredi=cntiдлявсех17379строк.
Модель с этими признаками показывает MAE=3,45 и R2=0,9966
против честных 45,5 и 0,878. Формально всё безупречно: разбиение по времени, тест
нетронут, воспроизводимость идеальна. Содержательно — бессмыслица: в момент прогноза
эти числа ещё не существуют.
Рис. 90.2. Утечка признака не ловится никаким разбиением
Слева: сумма casual и registered совпадает с target во всех 17 379 строках — это
тождество, а не признак. Справа: ошибка падает с 45,5 до 3,45 поездки в час, около 2%
среднего спроса. Правильная реакция на такое улучшение — не радость, а вопрос «когда
этот столбец становится известен?».
Общее правило записывается одной формулой. Пусть a(j) — момент, когда признак j
становится доступным, а t — момент прогноза. Допустимы только признаки с
a(j)≤t,приэтом target измеряетсявt+h,h>0.
Проверка этого условия — отдельный тест в коде проекта, а не устная договорённость.
Лестница baseline
Baseline не украшение отчёта. Он обнаруживает утечку, если подозрительно силён;
показывает добавочную ценность модели; остаётся запасным методом при отказе сложной
системы. Строить его надо лестницей — от совсем глупого к разумному:
Рис. 90.3. Лестница baseline: сколько добавляет каждая ступень
Константа по медиане обучения — 161,1 поездки в час. Среднее по часу суток и типу дня
— 88,5: почти половину ошибки объясняет один суточный профиль. «Тот же час неделю
назад» — 70,6 (доступно для 98,2% тестовых часов). Градиентный бустинг на честных
признаках — 45,5. Каждая ступень стоит одной строки кода и одной строки в отчёте.
Полезно смотреть не на абсолютные значения, а на долю снятой ошибки. Относительно
константы модель снимает
1−161,145,5=0,72,
а относительно осмысленного часового baseline — уже только
1−88,545,5=0,49.
Обе цифры верны; в отчёте обязана стоять вторая, потому что часовой профиль знает и
дежурный механик проката.
Насколько мы уверены в выигрыше
Разность средних ошибок сама является случайной величиной. Модель обыгрывает часовой
baseline на
Δ=MAEb1−MAEмодель=88,5−45,5=43,0
поездки в час. Но 2 168 тестовых часов — не 2 168 независимых наблюдений: часы одного
дня связаны погодой и событиями. Поэтому ресэмплируем целые дни, а не часы: из 92
тестовых дней выбираем 92 дня с возвращением, в каждой реплике считаем разность на
одном и том же наборе дней для обеих моделей и берём эмпирические квантили,
Две тысячи реплик с фиксированным зерном дают интервал, который не содержит нуля:
выигрыш есть, и он не меньше примерно 36 поездок в час. Об этом — урок 46
о доверительных интервалах; здесь важно лишь, что интервал считается парно.
Средняя метрика — плохой отчёт
Число 45,5 — среднее по очень разным режимам. Разложим тестовую ошибку по группам:
если Gk — доля часов группы k, то
MAE=k∑Gk⋅MAEk,
и содержательный разговор идёт про слагаемые, а не про сумму.
Ночью (0–5 часов) модель ошибается на 11,9 поездки при среднем спросе 28; утром (6–11)
— на 53,8 при спросе 254; днём (12–17) — на 67,4 при спросе 359; вечером (18–23) — на
48,5 при спросе 233. Относительная ошибка ночью 11,9/28≈0,43, а днём
67,4/359≈0,19: в абсолютных числах ночь «лучшая», в относительных — худшая.
Рис. 90.4. Средняя ошибка 45,5 — это среднее по очень разным часам
Слева: ошибка по часам суток повторяет форму спроса — модель ошибается там, где
людно. Золотая линия — 20% среднего спроса того же часа: почти всюду ошибка ниже неё,
кроме утреннего и вечернего пика. Справа: в редкой погодной категории «дождь или
снег» (160 часов из 2 168) ошибка 72,0 против 42,7 в ясную погоду.
Разрез по типу дня, наоборот, ничего не показывает: 45,6 в рабочие дни против 45,4 в
выходные. Это тоже результат — он говорит, что признак «рабочий день» модель уже
усвоила, и искать улучшение надо не здесь.
Метрика продолжается в интерфейс
Пользователю проката не нужна MAE. Ему нужно решить, объявлять ли тревогу «час будет
пиковым» и подгонять ли машину с велосипедами. Превратим прогноз в решение: тревога,
если y>τ, а пиковым считается час с y>500 (таких 10,8% в тесте).
Рис. 90.5. Метрика продолжается в интерфейс: цена порога
При пороге 300 модель ловит 97,4% пиковых часов, но три из пяти тревог ложные (542
тревоги за квартал). При 400 — точность 0,723 и полнота 0,923 (300 тревог). При 500 —
0,938 и 0,643. При 600 ложных тревог нет вовсе, но найдено лишь 28,1% пиков. Пунктир
— доля пиковых часов 0,108: она задаёт уровень, ниже которого точность бессмысленна.
Выбор порога — не статистика, а экономика. Если ложная тревога стоит cfp,
а пропуск — cfn, минимизируется ожидаемая цена
C(τ)=cfp⋅FP(τ)+cfn⋅FN(τ),
и при cfp=1, cfn=4 выигрывает порог 400: 83 ложные тревоги
против 18 пропусков дают 83+4⋅18=155, тогда как порог 500 даёт
10+4⋅84=346. Интерактив, который показывает пользователю только «точность 94%»,
скрывает от него именно это решение.
Интерактив обязан отвечать на один вопрос, иметь начальное состояние с готовым
выводом, подписывать единицы и источник данных, показывать неопределённость, не
прятать сброс, работать с клавиатуры и иметь текстовое описание на случай, когда
скрипты не выполнились. Это продолжение визуального аргумента, а не награда после
текста.
Сколько ещё данных
Прежде чем просить у города новый выгруз, посмотрите на кривую обучения: как падает
ошибка при росте обучающей выборки. Часто предполагают степенной закон
(урок 79):
MAE(n)≈αn−β+ε∞,
где ε∞ — неустранимая часть, связанная с шумом и недостающими
признаками.
Рис. 90.6. Кривая обучения: где кончается польза новых данных
1 300 часов обучения — ошибка 59,9; 2 600 — 48,9; 5 201 — 45,5; 7 801 — 43,7; 10 402 —
44,1; 13 003 — 45,5. После примерно восьми тысяч часов кривая выходит на плато:
удвоение данных не улучшает прогноз, а колебания в пределах пары поездок в час — шум
обучения. Значит, следующий шаг проекта — не «больше строк», а новые признаки или
другой горизонт.
Оркестр ролей
Даже один человек последовательно играет роли: предметник проверяет смысл; хранитель
данных отвечает за происхождение и split; моделист строит baseline и кандидатов;
скептик ищет утечку и контрпримеры; дизайнер делает интерактив; рецензент
воспроизводимости запускает всё с нуля; рассказчик собирает аргумент.
Роли разделяют критерии, а не создают длинную церемонию. Идея проверяющего из
урока про агентов полезна и здесь: проверка обязана иметь внешнее
свидетельство — файл, лог, контрольную сумму, — а не мнение автора о собственной
работе.
Красная команда и условие остановки
Перед защитой другой человек пытается: нарушить формат входа; найти почти-дубликат,
пересекающий split; изменить зерно; удалить сильнейший признак; сдвинуть период или
регион; подобрать состязательный пример; проверить край ползунка; отключить сеть;
воспроизвести окружение с нуля.
Не все найденные проблемы надо чинить. Часть честно фиксируется как ограничение.
Условие остановки защищает от бесконечной подгонки по валидации: например, «три
конфигурации подряд без улучшения валидационной MAE больше чем на одну поездку в час
— стоп».
Отрицательный результат — тоже проект
Предположим, ваша последовательная модель не превзошла часовой baseline. Не меняйте
вопрос задним числом. Проверьте, одинаковы ли признаки и бюджет настройки, достаточна
ли ширина интервалов и где именно методы расходятся: возможно, сложная модель
выигрывает только в дождь или только на праздниках.
Вывод «на этих данных и при этом протоколе добавочная сложность не дала измеримого
выигрыша: интервал для разности накрывает ноль» полезен, ограничен и воспроизводим.
Плохой вывод звучит как «нейросети не работают» — он выходит далеко за пределы
эксперимента:
Гурий Иванович Марчук (1925–2013) занимался ровно тем, о чём этот урок: как сделать
вычислительную модель проверяемой. В «Методах вычислительной математики» (1977) и в
работах по математическому моделированию окружающей среды он развил метод сопряжённых
уравнений: если нас интересует не всё решение, а один функционал J — скажем,
средняя концентрация примеси над районом, — то чувствительность J к возмущению
входных данных δφ вычисляется через решение сопряжённой задачи
φ∗:
δJ=⟨φ∗,δφ⟩.
Практический смысл прямой: ещё до расчётов видно, какие входные данные вообще влияют
на ответ, а какие можно измерять грубо. Это и есть анализ чувствительности — старший
брат абляции, которую вы проводите руками, выбрасывая признаки по одному.
В «Математических моделях в иммунологии» (1980) Марчук довёл ту же дисциплину до
медицины: модель заболевания записывалась системой уравнений, её параметры
идентифицировались по клиническим наблюдениям, а затем предсказания сверялись с
независимыми данными. Модель, параметры и проверка были одним связанным объектом —
именно так устроен и хороший школьный капстон.
Рубрика защиты
Проект оценивается по 100 баллам: постановка и предметный смысл — 12; данные,
лицензия, происхождение — 12; split и защита от утечки — 12; baseline и абляция — 12;
модель и объяснение — 10; метрики и неопределённость — 12; анализ ошибок и ограничения
— 12; интерактив и визуальный аргумент — 10; воспроизводимость — 8:
12+12+12+12+10+12+12+10+8=100.
Сложность модели отдельно не награждается. Проект из линейной регрессии
(урок 49) с базисными признаками (урок 50), честным
протоколом и внятным анализом ошибок получает максимум; проект с трансформером и
случайным разбиением — не получает.
Структура двенадцатиминутной защиты: вопрос и решение — 1 минута; данные и split — 2;
baseline и модель — 2; главный рисунок — 2; интерактивный эксперимент — 2; ошибки и
ограничения — 2; вывод — 1. Полные таблицы остаются в приложении.
На вопрос «почему вам верить?» ответ состоит из происхождения данных, отложенного
блока, лестницы baseline, интервала неопределённости и воспроизведения — а не из
уверенного тона.
Что переносится дальше
Курс образует сеть, а не список. Данные и их происхождение (урок 03),
переобучение и честная валидация (урок 32), разложение ошибки
(урок 33), интервалы (урок 46), регрессия и базисы
(урок 49, урок 50), масштабирование (урок 79),
агенты и проверяющие (урок 89) — всё это инструменты одного метода:
сформулировать проверяемое утверждение и попытаться его опровергнуть.
Финальный проект — первый случай, когда вы делаете это целиком сами, включая ту
часть, которую никто не проверит за вас: выбор протокола до того, как стали известны
результаты.