Un modelo de aprendizaje automático en Python que utiliza la biblioteca Scikit-learn para predecir los resultados de los partidos de fútbol en la Premier League rusa (RPL).
Entrada
Me inspiró para escribir este artículo el artículo
Aprendizaje automático: predicción del vencimiento del EPL 2018 . Nuestro modelo de aprendizaje automático se entrenará en las estadísticas de partidos de la Premier League rusa (RPL) a partir de la temporada 2015/2016 para predecir los resultados de los próximos juegos. Datos tomados del sitio web de estadísticas de fútbol wyscout.com.
El código y los datos están disponibles en
github .
Datos
Conectamos las bibliotecas necesarias:
import pandas as pd import numpy as np import collections
Los datos del partido están en
github .
data = pd.read_csv("RPL.csv", encoding = 'cp1251', delimiter=';') data.head()

¿Qué significa xG y PPDA?xG (objetivos esperados) es un modelo de objetivos esperados. Se basa en el indicador de tiros a puerta, en base al cual podemos estimar cuántos goles realmente tuvo que marcar el equipo si tomamos en cuenta todos los tiros que aplicó.
Obtenga más información sobre xG.PPDA (Pases permitidos por acción defensiva) es un indicador de estadísticas de fútbol que te permite determinar la intensidad de la presión en un partido. Cuanto menor sea el valor de PPDA, mayor será la intensidad del juego en defensa.
Aprenda más sobre PPDAPPDA = número de pases realizados por el equipo atacante / número de acciones en defensa
Vamos a predecir los resultados de los partidos para la segunda parte de la temporada 2018/2019 (es decir, los partidos jugados en 2019). La lista de equipos que juegan esta temporada (sin incluir Arsenal, Orenburg, Dynamo, Krylia Sovetov y Yenisei, porque no tienen estadísticas de temporadas pasadas o hay pocas estadísticas sobre ellas):
RPL_2018_2019 = pd.read_csv('Team Name 2018 2019.csv', encoding = 'cp1251') teamList = RPL_2018_2019['Team Name'].tolist() teamList

Eliminamos partidos con equipos que no participan en la temporada 2018/2019:
deleteTeam = [x for x in pd.unique(data['']) if x not in teamList] for name in deleteTeam: data = data[data[''] != name] data = data[data[''] != name] data = data.reset_index(drop=True)
Función que devuelve las estadísticas del equipo para una temporada:
def GetSeasonTeamStat(team, season): goalScored = 0
Ejemplo de uso de funciones:
GetSeasonTeamStat("", 2018)

Por conveniencia, podemos agregar el código:
returnNames = ["", "", "", "\n ", " ", "\n ", "\nxG ( )", "PPDA ( )", "\n", " ", "\n", " ", "\n", " ", "\n ( )"] for i, n in zip(returnNames, GetSeasonTeamStat("", 2018)): print(i, n)

¿Por qué nuestras estadísticas son diferentes de las estadísticas reales?Estadísticas reales de Spartak en la temporada 2017/2018:

Las estadísticas son diferentes porque Tomamos en cuenta los partidos de equipos que no juegan en el RPL en la temporada 2018/2019. Es decir, no tenemos en cuenta los partidos de Spartak - SKA, Spartak - Tosno, etc.
Función que devolverá estadísticas de todos los equipos para la temporada:
def GetSeasonAllTeamStat(season): annual = collections.defaultdict(list) for team in teamList: team_vector = GetSeasonTeamStat(team, season) annual[team] = team_vector return annual
Entrenamiento modelo
Escribiremos una función que devolverá datos de entrenamiento. Ella crea un diccionario con vectores de equipo para todas las estaciones. Para cada juego, la función calcula la diferencia entre los vectores de los equipos para una determinada temporada y la escribe en xTrain. La función establece yTrain en 1 si el equipo local gana, y 0 en caso contrario.
def GetTrainingData(seasons): totalNumGames = 0 for season in seasons: annual = data[data[''] == season] totalNumGames += len(annual.index) numFeatures = len(GetSeasonTeamStat('', 2016))
Aprendemos datos de entrenamiento para todas las estaciones desde 2015/2016 hasta 2018/2019.
years = range(2016,2019) xTrain, yTrain = GetTrainingData(years)
Para predecir la probabilidad de ganar, utilizaremos el algoritmo de aprendizaje automático LinearRegression de la biblioteca Scikit-Learn.
from sklearn.linear_model import LinearRegression model = LinearRegression() model.fit(xTrain, yTrain)
Escribiremos una función que devolverá pronósticos. Devolverá un valor entre 0 y 1, donde 0 es la pérdida y 1 es la ganancia.
def createGamePrediction(team1_vector, team2_vector): diff = [[a - b for a, b in zip(team1_vector, team2_vector)]] predictions = model.predict(diff) return predictions
Resultados
Por ejemplo, veamos las predicciones del algoritmo para el partido Zenit - Spartak
team1_name = "" team2_name = "" team1_vector = GetSeasonTeamStat(team1_name, 2019) team2_vector = GetSeasonTeamStat(team2_name, 2019) print (', ' + team1_name + ':', createGamePrediction(team1_vector, team2_vector)) print (', ' + team2_name + ':', createGamePrediction(team2_vector, team1_vector))

Resulta que en el partido Zenit - Spartak, la probabilidad de victoria para Zenit es del 47% (17/03/2019 Spartak 1-1 Zenit).
Propongo hacer un pronóstico dado lo siguiente:
Hasta 40%: el equipo simplemente no ganará (perderá o empatará)
Del 40% al 60%: alta probabilidad de empate
Desde 60%: el equipo definitivamente no perderá (gane o empate)
Obtenga pronósticos para CSKA contra todos los otros clubes
for team_name in teamList: team1_name = "" team2_name = team_name if(team1_name != team2_name): team1_vector = GetSeasonTeamStat(team1_name, 2019) team2_vector = GetSeasonTeamStat(team2_name, 2019) print(team1_name, createGamePrediction(team1_vector, team2_vector), " - ", team2_name, createGamePrediction(team2_vector, team1_vector,))

El algoritmo dio un pronóstico correcto para casi todos los partidos que no terminaron en empate. El único pronóstico inexacto: CSKA Moscú - Zenit. La probabilidad de la victoria del CSKA es mayor en 0.001, se podría suponer que los equipos tienen la misma fuerza y jugarán en un empate, pero al final Zenit ganó (3-1).
Conclusión
Nuestro algoritmo es muy primitivo. Solo tiene en cuenta las estadísticas de los partidos (y luego solo 15 parámetros básicos), y el resultado en el fútbol depende de muchos factores. Incluso las condiciones del campo o el clima pueden afectar el resultado del juego.
A continuación, me gustaría aumentar el número de signos, crear una muestra de prueba, probar varios algoritmos, configurar el modelo y obtener los pronósticos más precisos.
Le agradecería que deje sus ideas y comentarios.