Прошло 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

Комментарии (5)


  1. 0xC0CAC01A
    15.09.2024 16:26
    +4

    Ошибка выжившего


  1. pes_loxmaty
    15.09.2024 16:26
    +6

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

    А если отбросить все матчи где она не угадала, то получиться 100% точность?


  1. leremin
    15.09.2024 16:26

    В следующей версии предлагаю добавить в нейросеть количество и состав матных слов от тренера перед игрой. Точнее будет.


  1. Hve2024
    15.09.2024 16:26

    там можно было тупо все ничьи поставить без всякой нейросети, и не париться, потому что это это не обычный чемпионат и количество ничьих обычно зашкаливает. средний коф 3.20 не меньше, может быть и больше, а в плейофф там вообше ничьих много было, одна ничья в трех матчах закрывает 3 матча в плюсе (там подряд 2-3 ничьи было вроде), а вот в регулярных чемпионатах такое не прокатит, играю лет 20 лет. закономерностей очень много в разных чемпионатах, раньше проще было, сейчас уже чуть ли не чемпионат Антарктиды по футболу принимают, Зимбабве это вообще сейчас топ считается с Танзанией)))

    вот бы на регулярке потестить было бы интересно

    Ps посчитал 18 ничьих из 51 матча, вот и плюс, 80 процентов примерно


  1. randomsimplenumber
    15.09.2024 16:26
    +1

    -- а скажите что то по ML-шному?

    -- Был проанализирован датасет

    Было бы интересно подробностей. Что в датасете было, и как его анализировали. А то это как рисование совы, только без кружочков.