Рубрики
Без рубрики

Использование вероятности и статистики для прогнозирования спортивных результатов

Эта статья является английским переводом моей статьи, которая была написана на бразильском португальском и PO … Tagged с Python, статистикой, DataScience, Football.

Эта статья представляет собой английский перевод моей статьи, которая была написана на бразильском португальском языке и размещена здесь на моем профиле dev.to.

Начальные соображения

В этой статье мы будем использовать математические понятия, такие как Ожидаемое значение и Распределение вероятностей , если вы не знаете много об этих понятиях, вы все равно можете понять все, что делается в статье, но если вы хотите узнать больше о содержании, я указываю Хан Академия Веб -сайт, особенно модули на Распределение вероятностей и Среднее – ожидаемое значение , они короткие и очень объяснительные видео о концепциях.

Введение в проект

В этом проекте мы будем использовать вероятность и статистику для прогнозирования результатов футбольных матчей. Для этого мы будем использовать Python и это Numpy Библиотека, наряду с понятиями вероятности и статистики.

Мы выполним следующий процесс, мы прочитаем файл, содержащий все результаты матчей AFC Ajax в голландской футбольной лиге (Eredivisie) в течение сезона 18/19, и мы на каждом раунде предсказываем счет следующего матча Команда, этот прогноз будет состоять из ожидаемой стоимости (EV) голов, забитых клубом, и EV of Coals Cond.

Что произойдет, если мы догадываемся от случайных значений?

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

Мы рассмотрим, что Ajax может набрать от 0 (минимальное количество голов, забитых в соответствии с нашими данными) до 8 (максимальное число, записанное Ajax в соответствии с целями в наших данных), то есть в общей сложности 9 возможных результатов и Разрешить от 0 (зарегистрированное минимум) до 6 (зарегистрированных максимальных) целей, в общей сложности 7 возможностей. У нас есть вероятность получить право на получение прогнозирования оценки матча состоит в том, чтобы набрать правильное количество забитых голов и правильное количество прочитанных голов, поэтому, если мы выберем случайные значения в определенном интервале, у нас будет:

Голландская лига имеет в общей сложности 34 матча, мы не будем делать прогнозы для первого раунда, поскольку у нас нет предыдущих данных, которые помогут нам рассчитать прогноз. Таким образом, учитывая, что у нас есть 33 матча, чтобы попытаться получить хотя бы один правый балл, мы умножаем 33 на вероятность правого балла, что дает нам значение около 0,5238 правого балла. Это означает, что без математических инструментов, используя случайные значения, мы должны получить правильный балл менее одного соответствия 33 проанализированных. Для количества голов, забитых на матче, мы имеем ожидаемое значение 3,6667 (33 * 1/9) Правильные результаты, а для голов пропустили 4,7143 (33 * 1/7).

Итак, давайте попробуем улучшить эти значения (которые очень low) с использованием математики и программирования.

Реализация проекта

Чтобы создать наш проект, во -первых, мы создадим наш файл результатов, этот файл будет иметь определенный формат и будет написан как:

goalsscored,goalsconceded

Например, если Аякс забил 4 гола и уступил 2 в матче, который мы будем иметь в файле:

4,2

Этот файл будет назван resultAdos.txt , и он доступен в Репозиторий проекта Анкет

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

import numpy as np

Тогда мы откроем наш файл результатов.

# Opening the file with our scores
fileResults = open("resultados.txt", "r")

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

В конце итерации мы закроем файл ( resultAdos.txt ), который был открыт в начале нашего кода.

# Declaring our score list
matchesScores = []

# The for loop will work with every line of the file in each iteration
for lineofFile in fileResults:
    """
   The next line of code will add the contents of a file line,
   inside the braquets we have a list comprehension which
   does the exact same work as the following code:
   list = []
    for x in l.split(","):
        list.append(int(x))
    results.append(list)
    """
    matchesScores.append([int(x) for x in lineofFile.split(",")])

# The we will close our file
fileResults.close()

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

# We Will declare two lists, one containing the goals scored and one with the goals conceded
goals_scored = []
goals_conceded = []

# We will declare the number of time we got the goals scored, goals conceded and both of them right
right_round = 0
right_goals_scored = 0
right_goals_conceded = 0

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

Для этого мы получим частоту каждого количества голов, то есть сколько раз команда забила 0 голов, 1 гол, 2 гола и так далее. Мы сделаем то же самое с пропущенными целями. С частотой каждого количества целей у нас будут данные для расчета нашего ожидаемого значения.

Например, мы можем иметь частоту, подобную той, что показано на графике ниже ( Это не фактическая частота данных ).

Пример того, как может выглядеть частота

Чтобы определить голы, забитые и признанные, мы кодируем:

"""
We will go through our list of scores per round
and calculate the expected value of goals scored
and conceded for each round,
we will predict with these values and
then we will check if these values correspond
to the result that happened in the match.
"""
for round in range(len(matchesScores)):
    goals_scored.append(matchesScores[round][0])
    goals_conceded.append(matchesScores[round][1])

    # Now we will get the frequency of the number of goals scored so far
    num_goals, freq_num_goals = np.unique(goals_scored, return_counts=True)
    # For organizational reasons, we will transform our values into a dictionary 'goals': frequency
    dic_goals_scored = dict(zip(num_goals, freq_num_goals))

    # We wil do the same with the goals conceded
    num_goals, freq_num_goals = np.unique(goals_conceded, return_counts=True)
    # For organizational reasons, we will transform our values into a dictionary 'goals': frequency
    dic_goals_conceded = dict(zip(num_goals, freq_num_goals))

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

    expected_scored=0
    for goal in dic_goals_scored.keys():
        expected_scored += goal*(dic_goals_scored[goal]/len(goals_scored))

    expected_conceded=0 
    for goal in dic_goals_conceded:
        expected_conceded += goal*(dic_goals_conceded[goal]/len(goals_conceded))

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

    # After calculating our prediction we will print it and compare to the real result

    # The next line will round our values to the closest integer
    expected_scored = int(np.around(expected_scored))
    expected_conceded = int(np.around(expected_conceded))

    """
    If we are in the last round we have no future round
    to predict so we will stop our iteration
    """
    if (round+1 == len(matchesScores)):
        break
    """
    Now we will print our expected value for the next round
     as lists start at number 0 we have to add
     1 to the round value to get the round currently being read,
     that is, we have to add 2 to the number of the `round`
     to get the value of the NEXT round.
    """
    print(f'At the {round+2} round we predicted a result of Ajax  {expected_scored} x {expected_conceded} opponent')
    print(f'At the {round+2} we got a result of Ajax  {matchesScores[round+1][0]} x {matchesScores[round+1][1]} opponent')

    # We will check the results
    if(expected_scored==matchesScores[round+1][0] and expected_conceded==matchesScores[round+1][1]):
        right_round += 1
    if(expected_scored==matchesScores[round+1][0]):
        right_goals_scored += 1
    if(expected_conceded==matchesScores[round+1][1]):
        right_goals_conceded += 1

После выполнения цикла мы проверим наше количество правильных догадок.

# We Will print the results
print("We got {0:1d} of the matches results right, this is, {1:2.2f}%".format(right_round, (right_round/33)*100))

print("We got {0:1d} of the goals scored in a match right, this is, {1:2.2f}%".format(right_goals_scored, (right_goals_scored/33)*100))

print("We got {0:1d} of the goals conceded in a match right, this is, {1:2.2f}%".format(right_goals_conceded, (right_goals_conceded/33)*100))

Вывод нашей программы будет выглядеть так

> At the 2 round we predicted a result of Ajax  1 x 1 opponent
> At the 2 we got a result of Ajax  1 x 0 opponent
...
> At the 34 round we predicted a result of Ajax  3 x 1 opponent
> At the 34 we got a result of Ajax  4 x 1 opponent
> We got 4 of the matches results right, this is, 12.12%
> We got 7 of the goals scored in a match right, this is, 21.21%
> We got 15 of the goals conceded in a match right, this is, 45.45%

Обратите внимание, что мы получили 4 результата прямо из полного матча, в 8 раз больше, чем использование случайных значений, 7 прогнозов забитых голов, в 2 раза больше и 15 прогнозов пропустимых целей, в 3 раза больше.

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

Программа, разработанная в этой статье, доступна в моем Gitlab Repository Анкет Я надеюсь, что я помог вам каким -либо образом, если у вас есть какие -либо проблемы или вопросы, не стесняйтесь оставить комментарий к этому сообщению или вышли мне электронное письмо ;).

Оригинал: “https://dev.to/lisandramelo/using-probability-and-statistics-to-predict-sportive-results-f57”