Игорь Градов
Игорь Градов
6 мин
ai

39 забытых парковок год занижали ошибку на 16%: как метрики искусственного интеллекта приукрашивают модель

Московские разработчики, прогнозирующие загруженность городских парковок, обнаружили, что забытый в коде список из 39 идентификаторов парковок целый год искажал метрики искусственного интеллекта, делая модель на бумаге точнее, чем она была на самом деле.

Почему это важно

Захардкоженный список, снимок данных годичной давности, за год разъехался с реальностью настолько, что 30 живых парковок исключались из обучения без причины, а 30 мёртвых попадали в него беспрепятственно. Публикуемая ошибка модели оказалась занижена на 16%.

Историю раскопала команда, которая прогнозирует загруженность московских парковок на сутки вперёд. В обучающем скрипте лежал фиксированный перечень из 39 «аномальных» парковок: год назад они передавали одно и то же значение сутками, и их убрали из обучающих данных (данных, на которых модель учится находить закономерности). Когда разработчики пересчитали, какие парковки молчат сейчас, число совпало: снова 39. Но пересечение двух списков составило всего девять позиций.

Как список разъехался с реальностью за год?

Часть парковок из старого перечня за год «ожила»: датчики починили или площадку наконец подключили к системе. Одновременно город добавил новые парковки, которых не было в реестре на момент составления списка. Занятость по ним не передаётся, но в обучение они попадали без фильтрации.

Разработчики создали в базе данных специальное представление parking_feed_health с двумя полями:

  • feed_silent: парковка не отдавала данных о свободных местах 30 дней.
  • last_free_at: дата, когда данные поступали в последний раз.

Сравнение показало симметричную картину: 30 парковок с живым потоком данных выбрасывались из обучения зря, а 30 молчащих парковок в обучение попадали. Среди «молчащих, но не исключённых» половина имела семизначные идентификаторы, их просто не существовало, когда список составляли.

Почему «тихие» парковки приукрашивают метрики искусственного интеллекта?

Здесь начинается самое интересное. У молчащих парковок показатель occupancy_rate за сентябрь принимал ровно одно значение: 100. Не «почти всегда 100», а буквально одно уникальное число на 31 122 строк.

Команда переписала бэктест (контрольный прогон модели на исторических данных). Старый брал первые 60 парковок по номеру, не проверяя, живой ли поток, и делал один срез за последние сутки. Новый замер охватил все московские парковки, шесть срезов с шагом в сутки, и разделил результаты по живости потока.

Ключевые цифры:

  • Живые парковки: MAE (средняя абсолютная ошибка, насколько прогноз в среднем промахивается) составила 8,80.
  • Все парковки вместе: MAE снизилась до 7,36.
  • Разница: 39 константных рядов «улучшили» публикуемую ошибку на 16%. Если считать в обратную сторону, честный замер хуже приукрашенного на 20%.

При этом на молчащих парковках простейший метод «оставить как сейчас» давал MAE ровно 0,00, потому что ряд константный и предсказывать нечего. Нейросеть GRU (рекуррентная сеть, тип модели, хорошо работающий с последовательностями) на тех же парковках выдавала 1,18: она слегка дёргалась вокруг константы и портила идеальный ответ. Но поскольку 1,18 сильно меньше 8,80 на настоящих парковках, эти бесполезные результаты тянули общее среднее вниз. Самый бесполезный кусок работы выглядел самым успешным.

Почему R² растёт на пустых данных?

С показателем R² (коэффициент детерминации, насколько хорошо модель объясняет разброс данных; единица означает идеальное совпадение) механика ещё коварнее.

R² считается как единица минус отношение ошибки модели к общему разбросу данных. Молчащие парковки сидят на значении 100, далеко от общего среднего, и сильно раздувают знаменатель. А к числителю добавляют почти ноль, потому что ошибка там мизерная. Знаменатель растёт, числитель нет, R² растёт.

Насколько это ломает интуицию: метод «оставить как сейчас» на живых парковках давал R² = минус 0,223 (то есть хуже, чем просто взять среднее). Добавление 39 константных рядов превращало тот же самый метод в R² = плюс 0,107. Код не менялся ни на строчку, а из «хуже среднего» результат стал «лучше среднего».

Модель всё же работает, завышено было описание пользы

На живых парковках GRU показала MAE 8,80 и R² 0,814. Ближайшая осмысленная база, «повторить значение ровно неделю назад», дала 10,19 и 0,659. Простейшая персистенция (прогноз «останется как сейчас») на горизонте в сутки развалилась: MAE 25,09 и отрицательный R².

Модель действительно обыгрывает обе базы. Польза реальная, завышено было число, которым эту пользу описывали. Деградация по горизонту ожидаемая: на первый час MAE составляет 4,53, на 6 и более часов вперёд поднимается до 9 и выше. Любопытно, что на горизонте 12 и более часов точность чуть выше, чем на 6 и более: вероятно, сильная суточная сезонность помогает, и «завтра в это же время» попадает в ту же фазу суток, что и конец входного окна.

Нейросеть слегка дёргается вокруг константы и портит идеальный ответ. И при этом её присутствие в выборке улучшает итоговую цифру, потому что 1,18 сильно меньше, чем 8,80 на настоящих парковках, и тянет среднее вниз. Самый бесполезный кусок работы выглядит в этом замере самым успешным. : Автор исследования, команда прогноза загруженности московских парковок

Что с этим делать прямо сейчас, по ролям?

Автору на Дзене. Если вы используете любые автоматизации для контента, метрики искусственного интеллекта, включая внутренние дашборды Дзена, стоит проверять, не попадают ли в выборку «мёртвые» объекты, которые искусственно улучшают показатели. Пост с нулевыми просмотрами, стоящий в выборке, может так же тянуть среднее в нужную сторону.

Маркетологу. Любой отчёт по предиктивной аналитике (прогнозирование спроса, загрузки, конверсий) нуждается в вопросе: «Какие объекты в выборке неактивны и что происходит с метрикой без них?» Разница в 16 и более процентов между честной и приукрашенной цифрой может стоить бюджета.

Разработчику и предпринимателю. Захардкоженный (жёстко прописанный в коде) список, это снимок одного дня. Решение из этой истории: заменить статический перечень на SQL-запрос, который при каждом запуске обучения берёт актуальное состояние из базы. Команда именно так и поступила, убрала фиксированный список и заменила его запросом к таблице parking_feed_health.

Мнение редакции dzen.guru

Эта история ценна не технической находкой, а тем, как устроен самообман в продакшене. Никто не подтасовывал цифры намеренно: список писали для дела, просто забыли, что данные живые, а код нет. По моим наблюдениям, в российских проектах с ИИ такое встречается повсеместно, от рекомендательных систем до чат-ботов: фильтры, написанные под состояние данных на момент запуска, за полгода превращаются в источник ложного комфорта. Лучшая страховка, не список, а запрос, который обновляется автоматически. И обязательный замер метрик искусственного интеллекта отдельно по «живым» и «мёртвым» объектам: если разница между ними переворачивает картину, вы измеряете не качество модели, а долю мусора в выборке.

Забытый фильтр в коде не делает модель хуже. Он делает хуже ваше понимание того, насколько модель хороша. Разница между MAE 7,36 и 8,80 выглядит косметической, пока не осознаёшь, что за ней стоит 20% завышенной уверенности. Следующий шаг для любого проекта с прогнозированием: прямо сейчас открыть код обучения, найти все захардкоженные списки исключений и заменить каждый на запрос к актуальному состоянию данных.

Поделиться:TelegramVK
Игорь Градов
Игорь Градов

Основатель dzen.guru. Эксперт по монетизации и продвижению на Дзен. Автор курса «Старт на Дзен 2026».

Комментарии

Читайте также

Meta Muse снижает настороженность милотой: зачем компании ваша привязанность к маскоту
ai

Meta Muse снижает настороженность милотой: зачем компании ваша привязанность к маскоту

make the medicine go down? So I signed up and let Muse connect to my email. That's how it "gets to know you" — which is a cute way to say a large language…

8 мин
Microsoft Copilot объединил чат, код и ИИ-агентов: компания метит в «новый Office»
ai

Microsoft Copilot объединил чат, код и ИИ-агентов: компания метит в «новый Office»

Microsoft второго июня объединила чат, написание кода и автономных ИИ-агентов в одном приложении Copilot, которое компания называет «суперприложением» и…

6 мин
Meta запустила создание игры с помощью нейросети: из промпта в ленту Facebook за минуты
ai

Meta запустила создание игры с помощью нейросети: из промпта в ленту Facebook за минуты

Meta выпустила два инструмента для создания игр через промпты (текстовые команды для нейросети) прямо на телефоне и в браузере, а готовые игры можно будет…

6 мин