Как стать автором
Обновить

Xg предсказывает результаты матчей?

Уровень сложностиПростой
Время на прочтение6 мин
Количество просмотров2.2K

Для начала определим для кого эта статья? Моя цель заинтересовать не только обыкновенных зрителей, но и тех, кто уже занимается футбольной аналитикой. В статье я постараюсь показать интересные исследования об Xg.

Многие из тех, кто смотрит футбол и читает новости когда-нибудь видел метрику «xg». Что она вообще означает? Простыми словами Xg это количество ожидаемых голов. Т.е. каждый нанесённый удар по воротам имеет вероятность конвертироваться в забитый мяч, но с каждой позиции эта вероятность разная (если углубляться, то станет очевидным, что xg зависит от нескольких параметров, а не от одной позиции). К примеру, самая высокая вероятность забить мяч при исполнении пенальти. Чаще всего с пенальти дают 0.79 xg. Необходимо учитывать, что единой формулы расчёта xg нет, каждый провайдер рассчитывает её по-своему. Так например, для написания этой статьи я использовал данные с сайта https://understat.com/, но, если мы посмотрим другие источники, цифры будут отличаться.

Моя задача узнать, насколько точно Xg предсказывает количество голов в матче. Исследование будем проводить для АПЛ сезона 2022/2023. В данном исследовании мы ограничимся простыми методами анализа. Я составил таблицу из 380 матчей АПЛ. Пример таблицы с первыми 10 матчами АПЛ.

Table_EPL <- read.csv("F:\\EPL.csv")# Загружаем наш csv файл

Order – отвечает в таблице за количество матчей от 1 до 380

Week – в каком туре был сыгран матч, в Англии туры называют неделями. Предварительно для удобства все матчи объединены по турам, вне зависимости от даты, например матч 28 тура Брайтон – МЮ был сыгран 4 мая, хотя 28 тур игрался в середине марта.

Team1 – команда хозяин

Xg1 – показатель xg домашней команды

Goal1 – сколько голов забила домашняя команда

Goal2 – сколько голов забила гостевая команда

Xg2 – показатель xg гостевой команды

Team2 – команда гость

Изначальная таблица построена, далее будем считать разницу между забитыми мячами и xg у каждой из команд (diff1 и diff2), а потом напишем «yes» если разница меньше или равна 0.5, и, если разница строго больше 0.5 пишем «no» (Res1 и Res2).

Table_EPL$diff1 <- (Table_EPL$Xg1 - Table_EPL$Goal1)# Считаем разность Xg и забитых мячей для команд хозяев
Table_EPL$diff2 <- (Table_EPL$Xg2 - Table_EPL$Goal2)# Считаем разность Xg и забитых мячей для команд гостей
Table_EPL$Res1 <- ifelse(abs(Table_EPL$diff1) > 0.5, 'no', 'yes')# Условие "успешности" прдесказанных забитых голов для команд хозяев
Table_EPL$Res2 <- ifelse(abs(Table_EPL$diff2) > 0.5, 'no', 'yes')# Условие "успешности" прдесказанных забитых голов для команд гостей

Получится данная таблица:

Далее проведём два анализа строгий и нестрогий. В строгом анализе будем выводить «yes» если в Res1 и Res2 указано «yes», в нестрогом анализе если хотя бы в одном из столбцов имеется значение «yes».

Проведём строгий анализ

Table_EPL$success <- ifelse(Table_EPL$Res1 == 'yes' & Table_EPL$Res2 == 'yes', 'yes', 'no')# Условие "успешного" предсказания результата матча
Всего успешно предсказанных матчей получается 65, неуспешных соответственно 315.
Всего успешно предсказанных матчей получается 65, неуспешных соответственно 315.
length(which(Table_EPL$success == 'no' ))# Подсчёт "неуспешных" результатов

Теперь рассмотрим нестрогий анализ

Table_EPL$success <- ifelse(Table_EPL$Res1 == 'yes' | Table_EPL$Res2 == 'yes', 'yes', 'no')# Условие "успешного" предсказания результата матча

Получится таблица:

Всего успешно предсказанных матчей получается 241, неуспешных соответственно 139.
Всего успешно предсказанных матчей получается 241, неуспешных соответственно 139.
length(which(Table_EPL$success == 'no' ))# Подсчёт "неуспешных" результатов

Суммарные значения

sum(Table_EPL$Xg1,Table_EPL$Xg2)# Суммарный Xg
sum(Table_EPL$Goal1,Table_EPL$Goal2)# Суммарное количество голов

Суммарный xg равен 1136.54, мячей забито 1084, разница равна 52.54

Столь незначительное отклонение от забитых мячей говорит, что Xg может не быть точным в каждом конкретном матче, но на дистанции сезона, данная метрика покажет более чем хорошие результаты. Незначительное оно т.к. я рассматриваю ошибку предсказания в матче больше 0,5. В нашем случае разница значительно меньше 190(380 матчей * 0,5).

Далее приведу статистику средних значений.

Весь чемпионат:

summary(c(Table_EPL$Xg1,Table_EPL$Xg2))# Вычисляем средний Xg

Средний Xg – 1,48

summary(c(Table_EPL$Goal1,Table_EPL$Goal2))# Вычисляем среднее количество голов

Среднее кол-во голов – 1,43

Для команд хозяев:

summary(Table_EPL$Xg1)# Вычисляем средний Xg

Средний Xg – 1,67

summary(Table_EPL$Goal1)# Вычисляем среднее количество голов

Среднее кол-во голов – 1,63

Для команд гостей:

summary(Table_EPL$Xg2)# Вычисляем средний Xg

Средний Xg – 1,3

summary(Table_EPL$Goal2)# Вычисляем среднее количество голов

Среднее кол-во голов – 1,2

Ну и в конце проведём некую оценку точности показателей Xg. Я здесь имею ввиду, что чем больше забито мячей, тем большую неточность показывает Xg. Пример матч Ливерпуль 9:0 Борнмут, Xg в этом матче Ливерпуль 4,86 Борнмут 0,18.

Попробуем оценить в какой момент Xg не даёт удовлетворительную точность. Замечу, что здесь поменяем способ оценки и будем рассчитывать не интервал ± 0,5 xg, а значение xg большее или равное минимально допустимой границе для количества забитых мячей.

Для домашних игр:

length(which(Table_EPL$Goal1 == '4'))# Количество матчей с 4 голами
length(which(Table_EPL$Goal1 == '4' & Table_EPL$Xg1 >= '3.5'))# Количество матчей с 4 голами и Xg более 3.5

Матчей с 4 забитыми мячами – 28, xg ≥ 3,5 – 4 матча, точность ~ 14,3%

length(which(Table_EPL$Goal1 == '3'))# Количество матчей с 3 голами
length(which(Table_EPL$Goal1 == '3' & Table_EPL$Xg1 >= '2.5'))# Количество матчей с 3 голами и Xg более 2.5

Матчей с 3 забитыми мячами – 43, xg ≥ 2,5 – 19 матчей, точность ~ 44,2%

length(which(Table_EPL$Goal1 == '2'))# Количество матчей с 2 голами
length(which(Table_EPL$Goal1 == '2' & Table_EPL$Xg1 >= '1.5'))# Количество матчей с 2 голами и Xg более 1.5

Матчей с 2 забитыми мячами – 90, xg ≥ 1,5 – 53 матча, точность ~ 58,9% 

length(which(Table_EPL$Goal1 == '1'))# Количество матчей с 1 голом
length(which(Table_EPL$Goal1 == '1' & Table_EPL$Xg1 >= '0.5'))# Количество матчей с 1 голом и Xg более 0.5

Матчей с 1 забитым мячом – 124, xg ≥ 0,5 – 112 матчей, точность ~ 90,3% 

Построим простой график для иллюстрации

library(ggplot2)# Подключаем ggplot2 для построения графика
plot(Table_XG$week, Table_XG$Goal1, type =  "o", pch = 16,# Ось Х, Ось У, Тип линии графика, Тип точки на графике
     main = 'Xg in match',# Название графика
     xlab = 'week',# Подпись оси Х
     ylab = 'xg and goal',# Подпись оси У
     col = 'green3',# Цвет линии
     lwd = 2)# Толщина линии
xlines = seq(min(Table_XG$week), max(Table_XG$week), 1)# Создаём последовательность с указанием минимального и максимального значения
ylines = seq(min(Table_XG$Goal1), max(Table_XG$Goal1), 1)# Создаём последовательность с указанием минимального и максимального значения
abline(h = ylines, v = xlines, col = "lightgray")# Рисуем сетку по нашим последовательностям
lines(Table_XG$week, Table_XG$Xg1, type = "o", pch = 19, col = 'red', lwd = 2)# Добавляем вторую линию на график, аналогично первой
legend("topleft",# Создаём легенду и указываем её положение                                    
       legend = c("Goals", "Xg"),# Что будет указано в легенде
       col = c("green3", "red"),# указываем цвета в легенде
       lty = 7,# Тип линии в легенде
       pch = 19)# Тип точки в легенде

Для гостевых игр:

length(which(Table_EPL$Goal2 == '4'))# Количество матчей с 4 голами
length(which(Table_EPL$Goal2 == '4' & Table_EPL$Xg2 >= '3.5'))# Количество матчей с 4 голами и Xg более 3.5

Матчей с 4 забитыми мячами – 15, xg ≥ 3,5 – 2 матча, точность ~ 13,3% 

length(which(Table_EPL$Goal2 == '3'))# Количество матчей с 3 голами
length(which(Table_EPL$Goal2 == '3' & Table_EPL$Xg2 >= '2.5'))# Количество матчей с 3 голами и Xg более 2.5

Матчей с 3 забитыми мячами – 35, xg ≥ 2,5 – 7 матчей, точность ~ 20% 

length(which(Table_EPL$Goal2 == '2'))# Количество матчей с 2 голами
length(which(Table_EPL$Goal2 == '2' & Table_EPL$Xg2 >= '1.5'))# Количество матчей с 2 голами и Xg более 1.5

Матчей с 2 забитыми мячами – 76, xg ≥ 1,5 – 44 матча, точность ~ 57,9% 

length(which(Table_EPL$Goal2 == '1'))# Количество матчей с 1 голом
length(which(Table_EPL$Goal2 == '1' & Table_EPL$Xg2 >= '0.5'))# Количество матчей с 1 голом и Xg более 0.5

Матчей с 1 забитым мячом – 125, xg ≥ 0,5 – 112 матчей, точность ~ 89,6%

Построим простой график для иллюстрации

library(ggplot2)# Подключаем ggplot2 для построения графика
plot(Table_XG$week, Table_XG$Goal2, type =  "o", pch = 16,# Ось Х, Ось У, Тип линии графика, Тип точки на графике
     main = 'Xg in match',# Название графика
     xlab = 'week',# Подпись оси Х
     ylab = 'xg and goal',# Подпись оси У
     col = 'green3',# Цвет линии
     lwd = 2)# Толщина линии
xlines = seq(min(Table_XG$week), max(Table_XG$week), 1)# Создаём последовательность с указанием минимального и максимального значения
ylines = seq(min(Table_XG$Goal2), max(Table_XG$Goal2), 1)# Создаём последовательность с указанием минимального и максимального значения
abline(h = ylines, v = xlines, col = "lightgray")# Рисуем сетку по нашим последовательностям
lines(Table_XG$week, Table_XG$Xg2, type = "o", pch = 19, col = 'red', lwd = 2)# Добавляем вторую линию на график, аналогично первой
legend("topleft",# Создаём легенду и указываем её положение                                    
       legend = c("Goals", "Xg"),# Что будет указано в легенде
       col = c("green3", "red"),# указываем цвета в легенде
       lty = 7,# Тип линии в легенде
       pch = 19)# Тип точки в легенде

Выводы

Исходя из проведённого анализа можно сделать вывод, что xg показывает высокую точность предсказания результатов матчей на дистанции, а не в одном отдельном взятом матче. Это можно понять увидев, что при строгом анализе предсказано ~ 17,1% матчей, а при нестрогом ~ 63,4% матчей, что конечно хорошо, но как по мне недостаточно, учитывая, что мы считали матч успешным, если хотя бы у одной из команд предсказано значение. Также у Xg есть такой недостаток, как потеря точности при забитых мячах больше 2. В итоге можно сказать, что xg действительно хорошая и нужная метрика, однако она не является единственной главной.

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

Теги:
Хабы:
Рейтинг0
Комментарии6

Публикации

Истории

Работа

Data Scientist
78 вакансий

Ближайшие события

Конференция «IT IS CONF 2024»
Дата20 июня
Время09:00 – 19:00
Место
Екатеринбург
Summer Merge
Дата28 – 30 июня
Время11:00
Место
Ульяновская область