Вероятность выигрыша (WP) - это вероятность выигрыша (да) - с учетом определенного контекста (или предшествующего знания, говоря языком статистики). Этот контекст решает все. Например, игроки, делающие ставки, обычно имеют некоторое представление о вероятности выигрыша в предстоящей игре, основываясь на своих предварительных знаниях о сильных и слабых сторонах двух команд в целом и контексте конкретной игры. Это домашняя игра? У игроков выходной день или прощальная неделя? Звездный игрок травмирован?
Вероятность выигрыша в игре - как следует из названия - дополнительно моделирует контекст факторов, влияющих на каждый момент во время хода игры. Это может быть полезно не только для ставок на спорт, но и для болельщиков, которые хотят более активно взаимодействовать со своими командами. Хотя WP можно смоделировать для любого вида спорта, в этом посте я собираюсь сосредоточиться на баскетболе, в частности, на студенческом баскетболе мужского дивизиона I, для которого у меня есть соответствующая база данных игр, которую я начал собирать в этом сезоне. Вот пример того, как выглядит набор данных:
Каждая строка здесь представляет собой момент времени во время игры NCAA, когда произошло событие, изменившее счет или время на часах - попытка броска с игры, отскок, передача и т. Д. Соответствующими функциями для модели, описанной здесь, будут лидерство (домашний рейтинг - оценка посетителя), чистый рейтинг, который представляет собой просто разницу в рейтингах кенпом между двумя командами (дома - посетитель), и время Осталось в игре секунды. Целевая переменная - та, которую мы пытаемся предсказать с помощью нашей модели - это, конечно, результат победа, независимо от того, выиграла ли (1) или проиграла (0) команда хозяев в игре в соответствии с нормативными требованиями. Обратите внимание, что для текущей модели я просто выбрал игры, которые не закончились ничьей - я займусь ничьей… в конечном итоге. Это был просто выбор, который я пока сделал, чтобы упростить и заставить все работать быстро. Еще одно упрощение заключалось в том, чтобы исключить контекст владения мячом - какая команда владеет мячом, что, очевидно, важно знать очень поздно в игре, когда время идет к концу.
Предыдущие модели вероятности победы в баскетболе (и других видах спорта, насколько я могу судить) в основном полагались на ту или иную форму локальной логистической регрессии (здесь и здесь). Я на самом деле пробовал провести чистую логистическую регрессию, и, конечно же, это вообще не сработало. Когда я прочитал, что люди раньше шли по маршруту местной логистической регрессии, часть меня подумала: ну, нет никакого удовольствия делать именно то, что делали раньше! Когда я начал думать об этом, я подумал, может ли нейронная сеть определить тот же тип местности и нелинейности, которые необходимы для моделирования вероятности выигрыша. Как оказалось, я думаю, что ответ на этот вопрос - по крайней мере до некоторой степени однозначный да.
Чтобы помочь мне в этом путешествии, я во многом полагался на одну из цифр из сообщения в блоге Майка Бойя (пожалуйста, прочтите его и подпишитесь на него @ inpredict в Twitter), который показывает вероятность победы (для игр НБА) для команды. опережает на 3 очка, что является либо 5-очковым фаворитом, либо проигравшим в зависимости от времени в течение игры. Сплошные линии представляют собой модель, а точки представляют собой вероятности выигрыша с разделением на интервалы для фактических результатов игры.
Моя цель состояла в том, чтобы построить модель, которая могла бы воспроизвести что-то подобное. Однако перед этим давайте посмотрим, насколько похожи данные NCAA.
Из рисунка видно - если прищуриться - что приблизительные вероятности выигрыша на самом деле не слишком отличаются от данных Майка. Следует отметить, что время на моих графиках идет «вспять» - 0 - это зуммер в конце игры. Хорошо, теперь перейдем к моей модели.
Следует упомянуть, что я пробовал несколько разных вещей, в том числе своего рода «экспоненциальную трансформацию» времени, которая выглядела так:
Как оказалось, мне просто нужно было следовать мантре глубокого обучения, которая заключается в том, чтобы позволить нейронной сети изучить необходимые функции. Поэтому я отказался от преобразования времени и просто сделал свою нейронную сеть на один уровень глубже, и это, похоже, помогло.
В TensorFlow 2.0 простая модель AF на самом деле такова:
model = tf.keras.models.Sequential([ tf.keras.layers.Dense(12, activation='relu', input_shape=[3,]), tf.keras.layers.Dense(12, activation='relu'), tf.keras.layers.Dense(1, activation='sigmoid') ]) model.compile(optimizer=tf.keras.optimizers.RMSprop(1e-3), loss='binary_crossentropy', metrics=['accuracy', 'AUC']) model.summary() model.fit(df[['lead','net','time']].to_numpy(), df['win'].to_numpy(), verbose=1, shuffle=True, epochs=50, batch_size=512)
Вот и все, только входной слой, 2 скрытых слоя по 12 нейронов в каждом и выходной слой с сигмовидной активацией. И это в основном работает, как вы можете видеть здесь, для команды с преимуществом в 3 очка, которая является либо фаворитом на 5 очков, либо собакой с точки зрения чистого рейтинга:
times = list(range(0,2400,30)) winp_favorite = [model.predict_proba(x=[[3,5,time]])[0][0] for time in times] winp_underdog = [model.predict_proba(x=[[3,-5,time]])[0][0] for time in times] plt.plot(times, winp_favorite, 'b-') plt.plot(times, winp_underdog, 'r-') plt.title('NCAA Win Probability') plt.xlabel('Time elapsed (s)') plt.savefig('ncaa_win_prob.png')
Кстати, если у вас есть только 1 скрытый слой, вы можете получить такие кривые, которые выглядят шатко:
Наконец, чтобы показать вам, как эти функции работают индивидуально, здесь представлены вероятности победы для команды с чистым рейтингом +5 и оставшимися 30 секундами на часах с отрывом от 1 до 5 очков:
model.predict_proba(x=[[1, 5, 30], [2, 5, 30], [3, 5, 30], [4, 5, 30], [5, 5, 30]]) > array([[0.7975986 ], [0.8999447 ], [0.95134 ], [0.978909 ], [0.99045944]], dtype=float32)
Как и ожидалось, вероятность победы резко возрастает с несколькими дополнительными очками, так как команде, которая его отстает, становится очень сложно получить несколько владений за такое короткое время. Наконец, мы видим, что вероятность победы команды с отрывом в 4 очка за 30 секунд до конца практически не зависит от чистого рейтинга (как показал Люк Бенц):
# varying net rating from -5 to +5 model.predict_proba(x=[[4, -5, 30], [4, 0, 30], [4, 5, 30]]) > array([[0.94858927], [0.97111243], [0.978909 ]], dtype=float32)
Я рад, что это вообще работает, хотя, думаю, в этом нет ничего удивительного. Но я хотел поделиться этим с надеждой, что другие люди также могут пойти по этому пути и добавить больше функций, улучшенные архитектуры и т. Д. Как я сказал ранее, следующим очевидным шагом будет добавление владения мячом в качестве дополнительной функции. Удачи!