Соревнование замерло 16 августа, а таблица поехала дальше. Разбираю, что из этого настоящее

от автора

Я полез в данные соревнования Pokemon TCG AI Battle посмотреть, кто там выигрывает, и залип на другом. На публичной таблице 6806 команд. Самая поздняя отправка решения датирована 16 августа, 23:58:53. После этой секунды не отправил никто

1668 команд из 6806, почти четверть поля, сделали финальную отправку именно в этот день: 824 из них после шести вечера, 350 в последний час. Похоже, немалая часть узнала про срок в тот же день, когда он истекал

Дальше начинается то, ради чего я это пишу. Организатор продолжает каждое утро выкладывать свежий дамп сыгранных партий. То есть уже неделю соревнование крутится с замороженным полем: агенты не учатся и никто их не трогает. Меняется только жеребьёвка и кости.

Такое окно выпадает редко. И оно хорошо показало, где у меня настоящий эффект, а где я сам себе придумал. Покажу и то, и другое, потому что придуманного набралось больше.

Что действительно выросло

Средний счёт лучшего агента за день: 1248.30 в семь дней до заморозки, 1304.69 в семь после. Плюс 56.4 очка при разбросе около 20, тест Уэлча даёт t ровно 5.0. Это настоящее движение, а не шум.

Ни одной новой строчки кода в поле за эту неделю не появилось

Рекорда тут, впрочем, нет, и картинка это показывает честнее моего заголовка. 29 июня верх стоял на 1411.13, весь июль сползал вниз при полностью живом поле, и текущие 1335.04 это возврат к уровню начала июля. Так что «верх растёт» надо читать как «верх отскочил», а не как «поставил рекорд».

Ничего загадочного тут нет. Дневной средний счёт агента говорит не столько про агента, сколько про то, кого ему подсунули в соперники и с какими картами. Обычно это намертво перемешано с тем, что участники правят ботов. Здесь не перемешано.

Что я принял за находку, а оно ей не оказалось

Медиана поля за ту же неделю формально прибавила 23.3, с 1039.14 до 1062.41. Я хотел поставить это рядом с ростом верха, как второе подтверждение.

Не выйдет. Внутри этой недели медиана сходила с 1133.22 семнадцатого августа на 963.27 восемнадцатого и вернулась на 1082.73 двадцатого. Разброс до заморозки был 13.5 очка, после стал 59.7, и тест на семи днях против семи ничего не показывает: p около 0.32. Сдвига медианы я не померил и делать вид, что померил, не буду.

Хуже вышло со вторым сюжетом, который мне нравился больше всех.

Расстояние между верхом и серединой 16 июня было 396.87. К 28 июля оно упало до 92.15. Поле догоняет лидера: кто‑то придумал, остальные повторили. Я уже написал было, что после заморозки разрыв пошёл обратно, потому что копировать стало нечем

Разрыв развернулся 28 июля, за 19 дней до заморозки, при полностью живом поле, и вырос со 92.15 до 238.71 к 16 августа. Это плюс 159 процентов, и все они случились, пока копировать было можно. То, что добавилось после заморозки, статистически неотличимо от шума: 209.16 против 242.28, p около 0.14.

Так что копирование тут ни при чём, а что именно случилось 28 июля, я не знаю. Если у кого‑то есть версия, мне интересно.

Число, которое читают неправильно, включая меня

В индексе есть колонка с числом эпизодов за день. Она падает: 7819 в первый полный день, 4655 в последний. Минус 40.5 процента.

Первая мысль очевидная: народ разошёлся, играют меньше.

Мысль неверная. Я посмотрел на объём дампа: каждый день это 20 гигабайт. Не «около двадцати». 68 дней из 69 укладываются в 0.26 процента от ровно 20 ГиБ, единственное исключение это неполный первый день, последний дамп весит 19.999 ГиБ

Значит число эпизодов не измеряет ничего, что делали участники. Это двадцать гигабайт, поделённые на размер одной партии. Партии за два месяца выросли с 2.746 МБ до 4.613, на 68 процентов, потому что агенты стали играть длиннее. Меньше влезает.

И вот тут я чуть не подложил себе свинью. У меня был готов эффектный аргумент: ранговая корреляция между числом эпизодов и мегабайтами на эпизод равна минус единице, не минус девяти десятым, а ровно минус единице.

Аргумент пустой. Мегабайты на эпизод я сам и получаю делением объёма дампа на число эпизодов, то есть коррелирую x с c/x. Корреляция около минус единицы там гарантирована арифметикой до того, как я открыл файл. На 68 полных днях получается минус 0.9998, и ровно минус единица не выходит только потому, что делимое не идеально постоянное. А если прогнать очевидный однострочник по всем 69 строкам, вместе с неполным первым днём, получится минус 0.914. То самое число, над которым я собирался посмеяться.

Работает тут не корреляция. Работает то, что делимое каждый день одно и то же.

Если строите что‑то поверх этого индекса: нормируйте по байтам, не по эпизодам.

Две медианы, обе правильные, и разные линейки

Последняя ловушка там же.

Медиана публичной таблицы: 615.6. Лучший результат 1317.8, худший минус 474.2. Медиана, которую сообщает дневной дамп за тот же день: 1086.06. Разница 470 очков, и обе цифры честные: дамп собирается из партий, которые в этот день реально игрались, а играет активный верх поля

Но честным надо быть до конца. Это ещё и две разные линейки, а не только две разные популяции. Лучший результат во всей таблице 1317.8, а дневной верх дампа 23 августа 1335.04, то есть выше всей таблицы. За 69 дней дневной верх оказывался выше лучшего результата таблицы четырнадцать раз. У одной популяции одна и та же величина так себя вести не может.

Поэтому фраза «на уровне медианы дампа стоят 32 команды из 6806» это грубая привязка, а не точный процентиль. Я её оставляю, но с этой оговоркой.

Что я забрал себе

Дедлайн на баннере соревнования и дедлайн приёма решений это разные даты. Вторую я нашёл только в самой таблице, посмотрев на максимум по колонке с датой последней отправки.

Замороженное поле это бесплатный замер шума, и другого такого окна в этом соревновании не будет.

Счётчик эпизодов это байтовая квота. Прежде чем строить вывод на метрике, посмотрите, не окажется ли она константой, поделённой на что‑то другое.

И главное, что я вынес из этой недели уже про себя: из четырёх сюжетов, которые я собирался написать, проверку пережил один. Остальные три были красивее.

Данные тут открытые: индекс эпизодов выкладывает сам Kaggle, таблицу отдаёт API любому. Ноутбук со всем кодом лежит рядом, все цифры в нём пересчитываются заново при каждом запуске.

Если какое‑то число здесь расходится с картинкой, права картинка, а ошибся я. Напишите в комментариях, поправлю.

ссылка на оригинал статьи https://habr.com/ru/articles/1074532/