Как при помощи машинного обучения и чата GPT 4.0 удалось предсказать чемпиона Евро 2024 и обыграть букмекера

от автора

Прошло 2 месяца, с окончания чемпионата Европы по футболу, а значит самое время подвести итоги.

Краткий дискурс в начало.
Перед стартом ЧЕ, мне стало интересно проверить точность машинного обучения при прогнозе на столь непрогнозируемую сферу как футбол, а заодно узнать можно ли обыграть букмекера, написав пару строчек кода.

Был проанализирован датасет из 3000 релевантных матчей, не проанализировано все остальное (рейтинг, форма и т. п.).

Условия с «букмекером»: 51 матч сыгран турнире, на каждый совершена условная ставка в размере 100 долларов на основании прогноза машины + 2 раза по 100 долларов мы поставили на чемпиона — до начала турнира и после окончания групповой стадии. Оба раза триумфатором была выбрана Испания.

Виртуальный банк составил 5 300 долларов, в конце посмотрим как он изменился

Итак, с помощью чата GPT 4.0 я перебрал несколько вариантов базового алгоритма Random forest на питоне и на R. Результаты оказались выше на R, поэтому его и принял за основу. Код с прогнозом описан в прошлых статьях, здесь я подвожу итоги.

library(dplyr)  # Результаты и коэффициенты для 36 матчей results <- c("+", "-", "+", "+", "+", "+", "-", "+", "-", "+", "+", "+", "-", "+", "-", "-", "+", "+", "-", "-", "-", "-", "+", "-", "-", "+", "+", "-", "-", "-", "-", "-", "-", "-", "-", "-", "+", "+", "+", "+", "+", "+", "+", "+", "-", "+", "+", "+", "+") odds <- c(1.30, 4.05, 1.93, 1.38, 1.52, 3.60, 4.40, 4.80, 1.50, 1.55, 1.62, 1.50, 1.46, 1.27, 4.55, 5.62, 3.48, 2.20, 3.35, 4.15, 2.50, 2.00, 1.58, 3.25, 1.17, 3.10, 1.40, 3.10, 1.67, 1.30, 1.20, 1.80, 2.50, 3.80, 1.30, 2.20, 1.73, 3.75, 1.17, 1.07, 1.40, 1.16, 1.18, 2.80, 1.72, 1.60, 3.50, 1.25, 1.85, 2.00, 1.90)  # Деление матчей на этапы first_tour <- 1:12 second_tour <- 13:24 third_tour <- 25:36  # Функция для расчета точности и прибыли calculate_tour_stats <- function(matches, results, odds) {   # Точность   correct_preds <- sum(results[matches] == "+")   total_preds <- length(matches)   accuracy <- correct_preds / total_preds      # Прибыль   correct_odds <- odds[matches][results[matches] == "+"]   total_profit <- sum(correct_odds * 100) - total_preds * 100      return(list(accuracy = accuracy, total_profit = total_profit)) }  # Оценка каждого этапа first_tour_eval <- calculate_tour_stats(first_tour, results, odds) second_tour_eval <- calculate_tour_stats(second_tour, results, odds) third_tour_eval <- calculate_tour_stats(third_tour, results, odds)  # Вывод результатов cat("First Tour - Accuracy:", first_tour_eval$accuracy * 100, "%\n") cat("First Tour - Profit:", first_tour_eval$total_profit, "units\n\n")  cat("Second Tour - Accuracy:", second_tour_eval$accuracy * 100, "%\n") cat("Second Tour - Profit:", second_tour_eval$total_profit, "units\n\n")  cat("Third Tour - Accuracy:", third_tour_eval$accuracy * 100, "%\n") cat("Third Tour - Profit:", third_tour_eval$total_profit, "units\n\n") 

Первый тур прошёл неплохо. Профит обеспечен двумя крупными коэффициентами (Slovenia vs Denmark -> Prediction: Draw 3.60 Romania vs Ukraine -> Prediction: Home Win 4.80) и высоким процентом прохода.

First Tour — Accuracy: 75 %

First Tour — Profit: 720 units

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

Second Tour — Accuracy: 33.33333 %

Second Tour — Profit: -347 units

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

Third Tour — Accuracy: 16.66667 %

Third Tour — Profit: -750 units

Проводя аналитику, я всегда стараюсь дробить результаты на более мелкие. Например, заказчик просит предоставить аналитику по месяцам и у нас выходит средний результат 1.02. При этом посмотрев статистику мы видим повторяющиеся: 1.05 первую неделю, 1.07 вторую, 1.01 третью и 0.9 последнюю. В этом примере, можно обратить внимание заказчика на неравномерное распределение рекламного бюджета и тому подобное. Ровно также важно наблюдать за результатами модели в приближении, вполне возможно, что в моменте она учится не тому или есть внешние факторы мешающие хорошему прогнозу.

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

Идём дальше.

# Результаты и коэффициенты для матчей плейофф (37-51) results <- c("-", "-", "+", "+", "+", "+", "+", "+", "+", "+", "-", "+", "+", "+", "+") odds <- c(1.73, 3.75, 1.17, 1.07, 1.40, 1.16, 1.18, 2.80, 1.72, 1.60, 3.50, 1.25, 1.85, 2.00, 1.90)  # Функция для расчета точности и прибыли с проверкой, есть ли верные прогнозы calculate_tour_stats <- function(matches, results, odds) {     # Проверка на наличие матчей     if (length(matches) == 0) {         return(list(accuracy = NA, total_profit = NA))     }          # Точность     correct_preds <- sum(results[matches] == "+")     total_preds <- length(matches)     accuracy <- ifelse(total_preds > 0, correct_preds / total_preds, NA)          # Проверяем, есть ли хоть один верный прогноз     correct_odds <- odds[matches][results[matches] == "+"]          # Если нет верных прогнозов, устанавливаем прибыль в -100 * количество матчей     if (length(correct_odds) == 0) {         total_profit <- -total_preds * 100     } else {         total_profit <- sum(correct_odds * 100) - total_preds * 100     }          return(list(accuracy = accuracy, total_profit = total_profit)) }  # Оценка всех 15 матчей (37-51) matches <- 1:15 playoff_eval <- calculate_tour_stats(matches, results, odds)  # Вывод результатов if (!is.na(playoff_eval$accuracy)) {     cat("Playoff - Accuracy:", playoff_eval$accuracy * 100, "%\n") } else {     cat("Playoff - Accuracy: NA\n") }  if (!is.na(playoff_eval$total_profit)) {     cat("Playoff - Profit:", playoff_eval$total_profit, "units\n\n") } else {     cat("Playoff - Profit: NA units\n\n") } 

1/8 прошла весьма неплохо, 75% удачных исходов. Но с учётом того, что теперь мы берём проход, коэффициенты резко снизился, так игра идёт на 2 результата с ярко выраженными фаворитами.

1/4 так же 75% процентов.

Ну дальше полуфинал и финал, где все предсказания сбылись.

Playoff — Accuracy: 80 %

Playoff — Profit: 410 units

Итак точность прогноза в плей-офф составила 80 %, прематчем машина оценивала свою точность в 72.43 %. И снова мы видим реалистичную оценку своих возможностей от модели.

На основании скромной выборки в 39 матчей (я не считаю 3-й тур), можно сделать вывод о том что модель правильно оценивает вероятность удачного предсказания (естественно для полноценного подтверждения гипотезы, нужна выбора хотя бы из 500 матчей).

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

Но за счет верного предсказания чемпиона с коэффициентом 9.00 и 5.50, наш виртуальный банк стал — 6,583$.


В 2026 году проверим точность наших прогнозов уже на Чемпионате мира по футболу.

Все матчи

+ 1. Germany vs Scotland -> Prediction: Home Win 1.30

— 2. Hungary vs Switzerland -> Prediction: Home Win 4.05

+ 3. Spain vs Croatia -> Prediction: Home Win 1.93

+ 4. Italy vs Albania -> Prediction: Home Win 1.38

+ 5. Poland vs Netherlands -> Prediction: Away Win 1.52

+ 6. Slovenia vs Denmark -> Prediction: Draw 3.60

— 7. Serbia vs England -> Prediction: Draw 4.40

+ 8. Romania vs Ukraine -> Prediction: Home Win 4.80

— 9. Belgium vs Slovakia -> Prediction: Home Win 1.50

+ 10. Austria vs France -> Prediction: Away Win 1.55

+ 11. Turkey vs Georgia -> Prediction: Home Win 1.62

+ 12. Portugal vs Czech Republic -> Prediction: Home Win 1.50

— 13. Croatia vs Albania -> Prediction: Home Win 1.46

+ 14. Germany vs Hungary -> Prediction: Home Win 1.27

— 15. Scotland vs Switzerland -> Prediction: Home Win 4.55

— 16. Slovenia vs Serbia -> Prediction: Home Win 5.62

+ 17. Denmark vs England -> Prediction: Draw 3.48

+ 18. Spain vs Italy -> Prediction: Home Win 2.20

— 19. Slovakia vs Ukraine -> Prediction: Home Win 3.35

— 20. Poland vs Austria -> Prediction: Home Win 4.15

— 21. Netherlands vs France -> Prediction: Away Win 2.50

-22. Georgia vs Czech Republic -> Prediction: Away Win 2.00

+23. Turkey vs Portugal -> Prediction: Away Win 1.58

-24. Belgium vs Romania -> Prediction: Draw 3.25

-25. Switzerland vs Germany -> Prediction: Away Win 1.17

-26. Scotland vs Hungary -> Prediction: Home Win 3.10

+27. Albania vs Spain -> Prediction: Away Win 1.40

+28. Croatia vs Italy -> Prediction: Draw 3.10

-29. Netherlands vs Austria -> Prediction: Home Win 1.67

-30. France vs Poland -> Prediction: Home Win 1.30

-31. England vs Slovenia -> Prediction: Home Win 1.20

-32. Denmark vs Serbia -> Prediction: Home Win 1.80

-33. Slovakia vs Romania -> Prediction: Away Win 2.50

-34. Ukraine vs Belgium -> Prediction: Home Win 3.80

-35. Georgia vs Portugal -> Prediction: Away Win 1.30

-36. Czech Republic vs Turkey -> Prediction: Home Win 2.20

-37. «Switzerland vs Italy -> Prediction: Away Win» 1.73

-38. «Germany vs Denmark -> Prediction: Away Win» 3.75

+39. «England vs Slovakia -> Prediction: Home Win» 1.17

+40. «Spain vs Georgia -> Prediction: Home Win» 1.07

+41. «France vs Belgium -> Prediction: Home Win» 1.40

+42. «Portugal vs Slovenia -> Prediction: Home Win» 1.16

+43.»Romania vs Netherlands -> Prediction: Away Win» 1.18

+44. «Austria vs Turkey -> Prediction: Away Win» 2.80

+45. «Spain vs Germany -> Prediction: Home Win» 1.72

+46. «Portugal vs France -> Prediction: Away Win» 1.60

-47. «Netherlands vs Turkey -> Prediction: Away Win» 3.5

+48. «England vs Switzerland -> Prediction: Home Win» 1.25

+49. «Spain vs France -> Prediction: Home Win» 1.85

+50. «Netherlands vs England -> Prediction: Away Win» 2.00

+51. «Spain vs England -> Prediction: Home Win» 1.90


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


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *