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

Чемпионат мира по футболу FIFA 2022 уже начался, и мы можем многое понять из данных об этом соревновании.

Такие вещи, как команда мечты на ЧМ-2022, лучший состав из 26 человек для каждой национальной сборной и их идеальный стартовый состав, можно получить с помощью Python.

Но мы будем делать не только это! Мы также добавим некоторые визуализации данных, чтобы сделать этот анализ более понятным, и даже график футбольного поля с идеальным составом с использованием Python.

Table of Contents
1. Dataset Overview
2. Adjusting the Dataset FIFA 22 to the World Cup 2022
3. The Metric To Use for This Analysis
4. Dream Team World Cup 2022
5. The Players with The Highest Rating on each National Team
6. The Best 26-Man Squad for each National Team
7. Best Starting XI and Formation
 - Spain: Best Starting XI (4–2–3–1)
 - Portugal: Best Starting XI (4–2–3–1)
 - England: Best Starting XI (4–4–2)
 - Brazil: Best Starting XI (4–3–3)
 - France: Best Starting XI (4–2–3–1)
 - Argentina: Best Starting XI (4–3–3)
 - Germany: Best Starting XI (4–2–3–1)

Обзор набора данных

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

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
sns.set_style('darkgrid')

df = pd.read_csv('players_22.csv', low_memory=False)

Этот набор данных содержит более 100 столбцов, но для этого анализа мы будем использовать только некоторые из них.

df = df[['short_name', 'age', 'nationality_name', 'overall', 'potential',
         'club_name', 'value_eur', 'wage_eur', 'player_positions']]

Следует иметь в виду, что столбец player_positions имеет несколько позиций, поэтому для этого анализа мы должны выбрать только одну. Кроме того, мы должны удалить данные NaN.

# selecting only one position
df['player_positions'] = df['player_positions'].str.split(',', expand=True)[0]

# dropping nan
df.dropna(inplace=True)

Вот как выглядит фрейм данных df на данный момент.

Адаптация набора данных FIFA 22 к ЧМ-2022

Теперь мы собираемся адаптировать набор данных FIFA 22 к чемпионату мира 2022 года. Это означает, что мы будем рассматривать только те страны, которые прошли квалификацию для участия в соревнованиях, и только тех игроков, которые были вызваны в свои национальные сборные.

# dropping injured players
players_missing_worldcup = ['K. Benzema', 'S. Mané', 'S. Agüero', 'Sergio Ramos', 'P. Pogba',
                            'M. Reus', 'Diogo Jota', 'A. Harit', 'N. Kanté', 'G. Lo Celso', 'Piqué']

drop_index = df[df['short_name'].isin(players_missing_worldcup)].index
df.drop(drop_index, axis=0, inplace=True)

# filtering only national teams in the world cup
teams_worldcup = [
    'Qatar', 'Brazil', 'Belgium', 'France', 'Argentina', 'England', 'Spain', 'Portugal',
    'Mexico', 'Netherlands', 'Denmark', 'Germany', 'Uruguay', 'Switzerland', 'United States', 'Croatia',
    'Senegal', 'Iran', 'Japan', 'Morocco', 'Serbia', 'Poland', 'South Korea', 'Tunisia',
    'Cameroon', 'Canada', 'Ecuador', 'Saudi Arabia', 'Ghana', 'Wales', 'Costa Rica', 'Australia'
]

df = df[df['nationality_name'].isin(teams_worldcup)]

Метрика для использования в этом анализе

Для этого анализа мы будем использовать рейтинги ФИФА для каждого игрока. Рейтинг представлен столбцом overall.

Давайте отсортируем фрейм данных по overall (если несколько игроков имеют одинаковый рейтинг, мы также отсортируем по столбцам potential и value_eur)

df.sort_values(by=['overall', 'potential', 'value_eur'], ascending=False, inplace=True)

Вот как теперь выглядит датафрейм.

Теперь давайте посмотрим, как рейтинги (то есть общие) распределяются между всеми игроками ЧМ-2022.

import numpy as np
fig, ax = plt.subplots(figsize=(12, 5), tight_layout=True)

sns.histplot(df, x='overall', binwidth=1)

bins = np.arange(df['overall'].min(), df['overall'].max(), 1)
plt.xticks(bins)
plt.show()

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

Чемпионат мира по команде мечты 2022

Простой способ получить команду мечты — убрать все дубликаты в столбце player_positions (число df отсортировано по общему количеству, поэтому «недубликатами» будут игроки с наивысшим рейтингом).

df.drop_duplicates('player_positions')

Если мы выберем только столбцы short_name, overall, club_name и player_positions, мы получим фрейм данных ниже, который представляет нашу команду мечты.

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

Вот моя команда мечты.

Игроки с наивысшим рейтингом в каждой национальной сборной

Теперь давайте создадим фрейм данных df_best_players, который показывает лучшего игрока каждой национальной сборной. Мы извлечем первые 3 буквы из столбца nationality_name, чтобы узнать, откуда пришел каждый игрок.

df_best_players = df.copy()
df_best_players = df_best_players.drop_duplicates('nationality_name').reset_index(drop=True)
country_short =  df_best_players['nationality_name'].str.extract('(^\w{3})', expand=False).str.upper()
df_best_players['name_nationality'] = df_best_players['short_name'] +' (' + country_short + ')'

Давайте сделаем гистограмму для визуализации кадра данных df_best_players.

fig, ax = plt.subplots(figsize=(10, 6), tight_layout=True)

sns.barplot(df_best_players, x='overall', y='name_nationality',
            palette=sns.color_palette('pastel'), width=0.5)
plt.show()

Лучший состав из 26 человек для каждой национальной сборной

Давайте создадим функцию, которая возвращает лучший состав для каждой национальной сборной. Для этого мы выберем по 2 лучших игрока на каждую позицию в каждой национальной сборной. Когда у нас будет лучший отряд, мы отсортируем его по player_positions, overall и potential.

def best_squad(nationality):
    df_best_squad = df.copy()
    df_best_squad = df_best_squad.groupby(['nationality_name', 'player_positions']).head(2)
    df_best_squad = df_best_squad[df_best_squad['nationality_name']==nationality].sort_values(['player_positions', 'overall', 'potential'], ascending=False)
    return df_best_squad

Давайте посмотрим, какой лучший состав для Бразилии

best_squad('Brazil')

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

Теперь давайте посмотрим, каков средний рейтинг у состава каждой национальной сборной. Затем мы отсортируем его по убыванию по average_overall.

average_overall = [best_squad(team)['overall'].mean() for team in teams_worldcup]

df_average_overall = pd.DataFrame({'Teams': teams_worldcup, 'AVG_Overall': average_overall})
df_average_overall = df_average_overall.dropna()
df_average_overall = df_average_overall.sort_values('AVG_Overall', ascending=False)
df_average_overall

Вот 10 национальных команд с самым высоким средним результатом.

Давайте визуализируем это с помощью гистограммы.

fig, ax = plt.subplots(figsize=(12, 5), tight_layout=True)

sns.barplot(df_average_overall[:10], x='Teams', y='AVG_Overall',
            palette=sns.color_palette('pastel'))
plt.show()

Лучший стартовый состав и расстановка

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

Вот все формы, которые я придумал (вы можете добавить больше, если хотите)

dict_formation = {
    '4-3-3': ['GK', 'RB', 'CB', 'CB', 'LB', 'CDM', 'CM', 'CAM', 'RW', 'ST', 'LW'],
    '4-4-2': ['GK', 'RB', 'CB', 'CB', 'LB', 'RM', 'CM', 'CM', 'LM', 'ST', 'ST'],
    '4-2-3-1': ['GK', 'RB', 'CB', 'CB', 'LB', 'CDM', 'CDM', 'CAM', 'CAM', 'CAM', 'ST'],
}

Теперь мы создаем функцию best_lineup, которая возвращает лучший стартовый XI на основе желаемой формации.

def best_lineup(nationality, lineup):
    lineup_count = [lineup.count(i) for i in lineup]

    df_lineup = pd.DataFrame({'position': lineup, 'count': lineup_count})
    positions_non_repeated = df_lineup[df_lineup['count'] <= 1]['position'].values
    positions_repeated = df_lineup[df_lineup['count'] > 1]['position'].values

    df_squad = best_squad(nationality)

    df_lineup = pd.concat([
        df_squad[df_squad['player_positions'].isin(positions_non_repeated)].drop_duplicates('player_positions', keep='first'),
        df_squad[df_squad['player_positions'].isin(positions_repeated)]]
    )
    return df_lineup[['short_name', 'overall', 'club_name', 'player_positions']]

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

for index, row in df_average_overall[:7].iterrows():
    max_average = None
    for key, values in dict_formation.items():
        average = best_lineup(row['Teams'], values)['overall'].mean()
        if max_average is None or average>max_average:
            max_average = average
            formation = key
    print(row['Teams'], formation, max_average)

Большой! Теперь у нас есть лучшая схема для каждой национальной сборной.

Spain 4-2-3-1 85.1
Portugal 4-2-3-1 84.9
England 4-4-2 84.45454545454545
Brazil 4-3-3 84.81818181818181
France 4-2-3-1 83.9
Argentina 4-3-3 83.54545454545455
Germany 4-2-3-1 84.1

Давайте выясним, какой лучший стартовый состав для Испании, Португалии, Англии, Бразилии, Франции, Аргентины и Германии.

1. Испания: Лучший стартовый XI (4–2–3–1)

best_lineup('Spain', dict_formation['4-2-3-1'])

2. Португалия: Лучший стартовый XI (4–2–3–1)

best_lineup('Portugal', dict_formation['4-2-3-1'])

3. Англия: Лучший стартовый XI (4–4–2)

best_lineup('England', dict_formation['4-4-2'])

4. Бразилия: лучший стартовый состав (4–3–3)

best_lineup('Brazil', dict_formation['4-3-3'])

5. Франция: Лучший стартовый XI (4–2–3–1)

best_lineup('France', dict_formation['4-2-3-1'])

6. Аргентина: Лучший стартовый состав (4–3–3)

best_lineup('Argentina', dict_formation['4-3-3'])

7. Германия: Лучший стартовый XI (4–2–3–1)

best_lineup('Germany', dict_formation['4-2-3-1'])

Вот и все! Вы можете найти полный код на моем GitHub.

Изучаете науку о данных с помощью Python? Получите мою БЕСПЛАТНУЮ памятку по Python для Data Science, присоединившись к моему списку рассылки, в котором более 20 000 человек.

Если вам нравится читать такие истории и вы хотите поддержать меня как писателя, подумайте о том, чтобы зарегистрироваться и стать участником Medium. Это 5 долларов в месяц, что дает вам неограниченный доступ к тысячам руководств по Python и статьям по науке о данных. Если вы зарегистрируетесь по моей ссылке, я получу небольшую комиссию без каких-либо дополнительных затрат для вас.