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

Дело в том, что в оригинальной статье использовались оценки максимального правдоподобия, чтобы найти значения скрытых параметров, которые обеспечивают наилучшее правдоподобие данных. MLE немного скучен, и я подумал, что было бы забавно использовать Pyro — вероятностную среду программирования Python для реализации этой статьи.

Пока я буду публиковать фрагменты кода по мере продвижения, полный код будет доступен в конце.

Прежде всего, нам нужно описать, как Махер подошел к моделированию и что моделировали в первую очередь. Идея у него была такая: когда две команды встречаются в матче, они надеются забить какое-то количество голов. Очевидно, что счет в футболе представлен парой неотрицательных чисел. Количество забитых голов в каждом матче можно описать как случайную величину Пуассона, среднее значение которой определяется некоторыми скрытыми переменными.

Махер использовал идею о том, что каждую команду можно охарактеризовать двумя из этих скрытых переменных: силой атаки команды A и слабостью защиты противоположной команды B. Тогда идея состоит в том, что количество голов, забитых первой командой, будет распределено согласно ~ Пуассону. (А*В). Это означает, что у нас есть пара параметров для каждой команды.

Есть еще один параметр, отражающий домашнее преимущество команды. Считается (и, видимо, есть статистические данные), что каждая команда, играющая дома, имеет так называемое домашнее преимущество, то есть просто лучше играет дома в среднем в долгосрочной перспективе. Интересно, что это явление кажется универсальным для всех команд.

В исходной статье для поиска этих параметров используется MLE, вот скриншот с результатами:

Это все хорошо и весело, однако получение таких параметров как бы означает, что производительность команды в некоторой степени стабильна и фиксирована, а не является случайной величиной сама по себе.

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

Pyro поможет найти распределение этих параметров.

Во-первых, мы импортируем вещи.

Затем мы читаем CSV-файлы с историей матчей. Здесь нет ничего особенного, мы концентрируемся только на английской премьер-лиге. Одна вещь, которую мы делаем, — это создание большего количества столбцов, чтобы ограничить цели 4. Причина, по которой нам это нужно, станет очевидной позже. Наш кадр данных загрузчика выглядит примерно так:

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

Наконец, последний шаг подготовки данных — создание тензоров факела для нашей модели:

И, наконец, модель, пожалуйста, прочитайте встроенные комментарии, чтобы лучше понять, что происходит.

Рендер модели выглядит так:

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

Этого можно достичь за счет минимизации так называемого ELBO — нижней границы доказательств, подробнее здесь https://en.wikipedia.org/wiki/Evidence_lower_bound

Так или иначе, в Pyro для этого нужно 4 вещи.

  1. Направляющая функция — функция с четко определенными распределениями, которая будет использоваться для аппроксимации истинного апостериорного распределения. Мы будем использовать внутренние возможности Pyro для создания автоматических направляющих, которые по умолчанию используют некоррелированные нормальные распределения для неизвестных значений параметров.
  2. Оптимизатор, для которого оптимизатор Adam отлично подойдет — он используется для фактической минимизации метрики ELBO — это четко определенная задача минимизации.
  3. Trace_ELBO — это частная реализация идеи минимизации ELBO, подробнее можно прочитать здесь, ссылки тоже есть.
  4. Наконец, нам понадобятся объекты стохастического вариационного вывода, которые свяжут их все вместе с моделью.

Вот и мы

Наконец, мы можем запустить цикл оптимизации:

Вот как выглядит наша минимизация ELBO:

Хорошо, у нас есть некоторые результаты, но для чего они на самом деле хороши, подходят ли они? Как мы проверяем?

Что ж, одна проверка, которую мы можем сделать, — это извлечь параметры атаки/защиты из апостериорных распределений и сравнить их в разных командах, а также использовать наши футбольные знания, чтобы увидеть, имеют ли относительные распределения какой-либо смысл. Мы можем рисовать образцы, используя оптимизированные значения из направляющей функции, давайте нарисуем здесь 800 образцов:

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

Хорошо, а как насчет параметра домашнего преимущества? Вот его апостериорное распределение:

Хорошо, для чего еще это хорошо? Что ж, давайте смоделируем несколько матчей между «Ливерпулем» и «Уотфордом». Мы можем сделать это, запустив следующий код:

Будет ли что-то случайное, если мы дадим Уотфорду домашнее преимущество?

Наконец, можем ли мы сделать что-то более тонкое, чем создать несколько графиков и сказать, что они имеют смысл? Что мы можем сделать, так это: для домашних голов давайте смоделируем количество голов, которое предсказывает эта модель, и затем с помощью критерия хи-квадрат сравним это распределение с фактически наблюдаемым количеством голов. Нулевая гипотеза для хи-квадрата состоит в том, что два частотных распределения одинаковы. Следовательно, если значение p будет выше 1 или уровня значимости 5%, мы не сможем отвергнуть нулевую гипотезу и можем сделать вывод, что недостаточно доказательств, чтобы рассматривать предсказания модели как нечто, существенно отличающееся от того, что мы наблюдаем.

Вот тут-то и вступает в игру ограничение голов на 4. Разложим вещи по 5 ведрам: 0,1,2,≥3 голов.

Существует несколько способов имитации количества целей модели. Я решил пойти по этому пути: получить параметры атаки, защиты и домашнего преимущества, усреднить их по командам и внутри команд, а затем использовать эти средние значения в качестве входных данных для одномерного распределения Пуассона, примерно так:

После объединения исходного и предсказанного значений получаем следующее:

Нет, мы можем запустить тест хи-квадрат:

Чуть менее красивой выглядит картина по голам на выезде, хотя нулевую гипотезу мы все же не отвергаем:

Это в значительной степени завершает историю. В своей статье Махер также использовал двумерную модель Пуассона, но об этом в другой раз.