«В своем последнем сообщении в блоге я показал, как можно использовать шансы для измерения сложности футбольного матча. Затем я взял эту трудность и исследовал, насколько она предсказуема для исхода матча (не очень предсказуема) и голов/бросков, сделанных в матче (более предсказуема).

Теперь я применяю тот же процесс к соревнованиям Fantasy Premier League. Эта мера сложности дает нам хорошее представление о том, как должна быть сформирована наша воображаемая команда, вам следует отдавать предпочтение игрокам, у которых предстоят более легкие матчи, поскольку эти матчи, скорее всего, приведут к большему количеству голов. Точно так же избегайте защитников в этих сложных матчах, так как они с большей вероятностью уступят и потеряют очки с сухим счетом!

Нравятся такие посты? Тогда вам стоит подписаться на мою рассылку. Это краткий ежемесячный обзор всего, что мне показалось интересным в последнее время, а также всех постов, которые я написал. Так что подписывайтесь и будьте в курсе!

https://buttondown.email/dm13450

Премьер-лига Fantasy (сокращенно FPL)

Вся причина и / или вдохновение для этого анализа исходит из желания быть лучше в Fantasy Premier League. Для тех, кто не знает, это онлайн-игра, в которой вы создаете команду из 11 игроков высшей лиги. Есть бюджет и некоторые правила отбора, но вкратце речь идет о выборе хороших игроков. Затем каждую неделю игроки набирают очки, и ваш общий счет равен сумме очков всех ваших игроков. Я использую подход манибол при выборе команды FPL и пытаюсь построить модели, которые помогут выбрать мою команду. Мы надеемся, что это докажет превосходство подхода, основанного на цифрах, по сравнению с правильными методами футбольного человека при выборе людей со страстью. Пока я 12-й (из 16), поэтому аналитика не приносит никакой пользы.

Существует целое сообщество людей, использующих подход, основанный на статистике, и люди даже написали свои магистерские диссертации на такие темы! Так что мой вклад в это сообщество — лучший метод оценки сложности приспособления. Вы можете прочитать мою предыдущую запись в блоге о том, как построить эту меру сложности, но в этой статье я посмотрю, сможем ли мы построить модель, которая включает эту сложность приспособления в предсказанные игроками очки для каждого слабого. Модель ожидаемых точек должна быть краткой.

Это будет простая модель, которая просто связывает сложность матча с общим количеством очков, набранных каждым игроком. Я предполагаю, что баллы распределяются по методу Пуассона и используют как xgboost для чисто прогнозирующей производительности, так и GAM, чтобы попытаться понять взаимосвязь между сложностью и общим количеством набранных баллов.

Я скачал данные с https://github.com/vaastav/Fantasy-Premier-League, которые показывают, сколько очков каждый игрок набирал каждую неделю в течение последних нескольких сезонов. Я присоединяю его к данным о коэффициентах с сайта football-data.co.uk, и это дает нам полный набор данных.

Я делаю обычное разделение 70/30 случайным образом. Я не беспокоюсь о том, чтобы использовать будущие игры для предсказания предыдущих, меня больше беспокоит понимание базовой структуры того, как начисляются очки.

require(caret)

fplModelData <- read_csv("data/player_clean_data.csv") %>% 
  drop_na(Difficulty, position) %>% 
  mutate(position = factor(position, 
                           levels = c("GK", "DEF", "MID", "FWD")),
         total_points =if_else(total_points < 0, 0, total_points)) 

trainIndexes <- createDataPartition(fplModelData$total_points, p = 0.7, list=F)

fplModelData[trainIndexes, ] -> trainData
fplModelData[-trainIndexes, ] -> testData

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

gamModel <- gam(total_points ~ s(Difficulty, by=position) + (value + position)^2, 
                  data=trainData, 
                  family="poisson",
                  method="REML")

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

ggplot(pltFrame, aes(x=Difficulty, 
                     y=exp(Fit), 
                     ymin=exp(Fit - 1.96*SE), 
                     ymax = exp(Fit + 1.96*SE), 
                     colour=as.factor(Position),
                     fill=as.factor(Position))) + 
  geom_line() + 
  geom_ribbon(alpha=0.5) + 
  facet_wrap(~Position, scales="free_y") + 
  theme(legend.position = "none", legend.title = element_blank()) + 
  ylab("Expected Points Effect") +
  scale_color_brewer(palette = "Dark2") + 
  scale_fill_brewer(palette="Dark2")

Здесь следует отметить пару интересных вещей.

  • Вратари на самом деле набирают больше очков в сложных матчах.

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

  • Защитники и полузащитники имеют линейный прирост очков примерно на 1 балл от сложных матчей к легким.

Что интересно, так это относительная ровность форвардов плюс небольшое снижение в матчах со сложностью от 0,25 до 0,5 перед быстрым увеличением в очень легких матчах.

XGBoosting

Теперь мы знаем, что существует связь между сложностью и ожидаемыми баллами, что, если мы просто отбросим интерпретируемость на ветер и построим максимально предсказательную модель? Для этого я буду использовать древовидную модель, реализованную с помощью библиотеки xgboost. Я включу все те же переменные, что и выше, и вплоть до взаимодействий второго порядка. Посмотрим, сможем ли мы улучшить GAM.

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

library(doParallel)
cl <- makePSOCKcluster(3)
registerDoParallel(cl)

trControl <- trainControl(method="adaptive_cv",
                           number = 5, repeats = 5,
                           adaptive = list(min = 5, alpha = 0.05, 
                                           method = "gls", complete = TRUE),
                             search = "random", 
                          verboseIter = TRUE)

xgbModel <- train(total_points ~ (position + value + Difficulty)^2, 
                    data = trainData, 
                    method = "xgbTree", 
                    trControl = trControl,
                    verbose=TRUE)
					
stopCluster(cl)

После завершения настройки модели мы можем оценить ее на нашем тестовом наборе.

Модель XGBoost имеет R² 16%, тогда как GAM имеет R² всего 12%, поэтому при переходе на эту модель типа «черный ящик» приличное увеличение.

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

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

Вывод

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

Первоначально опубликовано на https://dm13450.github.io 12 октября 2021 г.