Введение

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

Но что, если команда не может подписать своего основного целевого игрока? Каковы их альтернативные варианты, похожие на их основную цель? Именно в свете этого я создал простую систему рекомендаций по игрокам, которая предлагает 10 лучших игроков, наиболее похожих на данного входного игрока, используя Анализ основных компонентов (АПК) и Самоорганизующаяся карта (SOM)с использованием косинусного расстояния и расстояния Брея-Кертиса.

Давайте посмотрим, как это можно построить.

Сбор данных

Данные, используемые для создания этой системы рекомендаций, получены из fbref. Однако данные были получены с использованием библиотеки worldfootballR, которая извлекает данные с веб-сайта fbref. Данные, которые я использовал, состоят из статистики игроков за сезон 2022–2023 годов от игроков, принадлежащих к 5 лучшим лигам Европы, Лиге Примейра и Эредивизи. Статистика игроков включала их стандартную статистику, броски, пасы, защитные действия, типы пасов, создание голов и бросков, владение мячом и прочие характеристики. Все это можно увидеть на веб-сайте fbref.

Библиотека worldfootballR, как указано в названии, относится только к R, а код R для получения данных о пяти лучших лигах Европы, Liga Primeira и Eredivisie — в моем репозитории GitHub (ссылка в конце статьи). Однако давайте рассмотрим функции в этой библиотеке, которые используются для получения данных.

Для пяти лучших европейских лиг используется функция ‘fb_big5_advanced_season_stats’. Его описание и использование показаны на картинке ниже.

Для Liga Primeira и Eredivisie мы используем 3 функции. Первый — 'fb_league_urls', и мы используем его для получения URL-адреса веб-страницы лиги в определенном сезоне из fbref. Его использование и описание приведены ниже.

После этого нам нужно получить URL-адреса веб-страниц каждой команды, которая принимала участие в этом конкретном сезоне в этой конкретной лиге. Для этого используется функция ‘fb_teams_urls’, описание и использование которой приведены ниже.

И, наконец, чтобы получить статистику игроков каждой команды в этой лиге в данном сезоне, мы используем функцию ‘fb_team_player_stats’. Его описание и использование следующие.

Код для получения статистики можно найти в моем репозитории GitHub в виде файлов R-Markdown. Однако, чтобы дать вам представление о том, что происходит — мы собираем статистику для каждой категории и для каждого игрока в фреймы данных, затем выполняем внутренние соединения, чтобы получить один фрейм данных со статистикой всех необходимых категорий, и, наконец, мы удаляем этих игроков. которые являются вратарями, поскольку нас интересуют только аутфилдеры. Затем мы сохраняем окончательный фрейм данных в файл .CSV, который мы можем использовать позже.

Теперь давайте перейдем к предварительной обработке данных.

Предварительная обработка данных

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

Второй важный шаг больше связан с спецификой Liga Primeira и Eredivisie. Здесь нам нужно переименовать столбцы, чтобы они соответствовали именам столбцов фрейма данных, содержащего 5 лучших лиг Европы. Кроме того, кадры данных Liga Primeira и Eredivisie не содержат названий лиг для всех наблюдений. Это должно быть исправлено.

Наконец, перед моделированием нам нужно убедиться, что статистика каждого игрока, кроме «Сыгранных матчей» и «Сыгранных матчей», преобразована в их статистическую форму «За 90». Вот формула.

Код Python для этого предоставляется в репозитории GitHub. Следует отметить, что если у игрока нет значения определенной характеристики, мы приписываем это отсутствующее значение 0.

Прежде чем мы продолжим, вот краткое описание переменных в наборе данных.



Анализ главных компонентов (PCA)

На данный момент окончательный набор данных содержит около 103 измерений, на которых мы хотим основывать систему рекомендаций. А так как система работает по принципу контентной фильтрации, то важно найти точки, или в данном случае игроков, которые находятся близко друг к другу. Однако количество измерений очень велико для вычисления окрестности точки. Следовательно, нам необходимо выполнить уменьшение размерности, что достигается с помощью анализа основных компонентов (сокращенно PCA).

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

Кратко объясним работу PCA

  1. Ковариационная матрица набора данных рассчитывается
  2. Находятся собственные векторы и соответствующие им собственные значения. Собственные векторы сортируются в порядке убывания их соответствующих собственных значений.
  3. Мы берем только k собственных векторов, которые объясняют требуемую величину дисперсии данных. В нашем случае мы выбираем собственные векторы, которые объясняют 95% дисперсии данных.
  4. Выполните матричное умножение с k собственными векторами, чтобы получить новый набор данных с k функциями.

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

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

Самоорганизующаяся карта (SOM)

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

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

Цель SOM состоит из трех частей:

а) Входное наблюдение присваивается нейрону, наиболее похожему на его использование по определенной метрике расстояния. (Соревнование)

б) Найдите значения веса нейрона, чтобы соседние нейроны имели одинаковые значения. (Сотрудничество)

в) Каждая единица становится центром кластера, где кластер содержит определенный набор наблюдений. (обновление веса)

Давайте посмотрим на шаги, связанные с SOM.

  1. Сначала мы случайным образом инициализируем веса в соединениях. Помните, что соединение — это весовой вектор, представляющий нейрон.
  2. Далее этап конкурса. Для каждого входного наблюдения мы находим нейрон, который наиболее похож на входное наблюдение, используя определенную метрику расстояния. В случае с этим проектом я использую комбинацию косинусного расстояния и расстояния Брея-Кертиса. Помните, что этот шаг, скорее всего, приведет к тому, что конкретный нейрон будет похож более чем на одно наблюдение. Этот наиболее похожий нейрон также называется Best Matching Unit (BMU).
  3. Теперь мы подходим к шагу сотрудничества. Здесь мы должны понимать, что у каждого нейрона есть окрестности нейронов, идентифицируемых определенной функцией. Вы можете визуализировать это как круг с центром в BMU и радиусом, расходящимся от центра, что приводит к кругу, и любые нейроны в этом круге находятся по соседству с BMU. Как говорит слово «сотрудничество», цель состоит в том, чтобы попытаться сделать каждый соседний нейрон похожим на входной вектор. Здесь вступает в игру этап обновления веса. Следует отметить, что в течение нескольких итераций размер окрестности становится меньше. Кроме того, этап обновления веса включает использование скорости обучения, которая также уменьшается по мере увеличения количества итераций.
  4. Шаг 4 — повторить шаги 2 и 3 для определенного количества итераций.

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

Некоторыми важными гиперпараметрами в SOM являются количество нейронов, параметр, контролирующий размер BMU, и скорость обучения.

В этом проекте я использовал библиотеку ‘minisom’. Ссылка здесь содержит подробную информацию о библиотеке. Еще один момент, на который следует обратить внимание в случае с этим проектом, — это размер сетки, который я выбрал. Я выбрал сетку размером 2x3, которая представляет собой плоскость из 6 нейронов, расположенных в 2 ряда и 3 столбца. В результате получилось 6 кластеров разумных размеров. Более того, я заметил, что даже если я увеличил размер сетки, топографическая ошибка и ошибка квантования были небольшими и не сильно изменились.

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

Рекомендации

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

  1. Подготовьте матрицу расстояний для каждого кластера, полученного из SOM. Метрика расстояния представляет собой сумму косинусного расстояния и расстояния Брея-Кертиса.
  2. Для данного входного игрока определите кластер игрока и, следовательно, матрицу расстояний. Теперь, когда у нас есть матрица расстояний, мы просто ищем 10 ближайших наблюдений (то есть игроков) для входного игрока, используя расстояния в матрице расстояний, рассчитанные для кластера наблюдений, к которому принадлежит данный входной игрок.
  3. Как только мы получим 10 ближайших игроков для данного входного игрока, мы можем визуализировать их с помощью диаграммы радара. Я построил радарный график, используя несколько функций из исходного набора данных, чтобы создать график, который содержит 2 радара — один для входного игрока, а другой — для рекомендуемого игрока. В результате получается 10 радиолокационных графиков, каждый из которых содержит 2 радара. Для этого я использовал библиотеки mplsoccer’и matplotlib’. Ссылка здесь ссылается на документацию от ‘mplsoccer’, в которой объясняется, как построить радарную диаграмму.

Вот пример одной из рекомендаций для Луки Модрича, звездного полузащитника «Реала».

Код

Код R, необходимый для очистки данных, и код Python, необходимый для очистки данных, предварительной обработки данных и самой модели, находятся в следующем репозитории GitHub.

URL: https://github.com/sameerprasadkoppolu/Soccer-Player-Recommendation-System

Наконец, я надеюсь, вам понравилось ваше чтение. Я призываю вас попробовать это для себя и получить удовольствие от этого! Возможно, это поможет вам в режиме менеджера в FIFA.