95 lines
4.7 KiB
Python
95 lines
4.7 KiB
Python
# predecir_jornada_stats.py
|
|
"""
|
|
Predice resultados de la quiniela usando features de la clasificación y estadísticas por equipo.
|
|
"""
|
|
import pandas as pd
|
|
import os
|
|
import joblib
|
|
from sklearn.ensemble import RandomForestClassifier
|
|
|
|
MODEL_PATH = os.path.join(os.path.dirname(__file__), '../models/modelo_rf.pkl')
|
|
DATA_PATH = os.path.join(os.path.dirname(__file__), '../data/espana/partidos_todos.csv')
|
|
PARTIDOS_PATH = os.path.join(os.path.dirname(__file__), '../partidos_jornada.txt')
|
|
CLASIF_PATH = os.path.join(os.path.dirname(__file__), '../data/clasificacion2026.csv')
|
|
STATS_PATH = os.path.join(os.path.dirname(__file__), '../data/estadisticas_por_equipo.csv')
|
|
|
|
# Cargar datos
|
|
clasif = pd.read_csv(CLASIF_PATH)
|
|
clasif.set_index('equipo', inplace=True)
|
|
stats = pd.read_csv(STATS_PATH)
|
|
stats.set_index('equipo', inplace=True)
|
|
df_hist = pd.read_csv(DATA_PATH)
|
|
|
|
# Cargar modelo entrenado o entrenar si no existe
|
|
if os.path.exists(MODEL_PATH):
|
|
clf = joblib.load(MODEL_PATH)
|
|
else:
|
|
df_hist['dif_goles'] = df_hist['goles_local'] - df_hist['goles_visitante']
|
|
X = df_hist[['dif_goles']]
|
|
y = df_hist['resultado']
|
|
clf = RandomForestClassifier(n_estimators=100, random_state=42)
|
|
clf.fit(X, y)
|
|
joblib.dump(clf, MODEL_PATH)
|
|
|
|
# Leer partidos desde archivo
|
|
def leer_partidos(path):
|
|
partidos = []
|
|
with open(path, 'r', encoding='utf-8') as f:
|
|
for linea in f:
|
|
linea = linea.strip()
|
|
if not linea or '-' not in linea:
|
|
continue
|
|
local, visitante = [x.strip() for x in linea.split('-', 1)]
|
|
partidos.append({'local': local, 'visitante': visitante})
|
|
return partidos
|
|
|
|
partidos = leer_partidos(PARTIDOS_PATH)
|
|
|
|
# Generar features usando la clasificación y estadísticas
|
|
features = []
|
|
for p in partidos:
|
|
local = p['local']
|
|
visitante = p['visitante']
|
|
# Clasificación
|
|
pos_local = clasif.loc[local, 'posicion'] if local in clasif.index else clasif['posicion'].mean()
|
|
pos_visit = clasif.loc[visitante, 'posicion'] if visitante in clasif.index else clasif['posicion'].mean()
|
|
pts_local = clasif.loc[local, 'Pts'] if local in clasif.index else clasif['Pts'].mean()
|
|
pts_visit = clasif.loc[visitante, 'Pts'] if visitante in clasif.index else clasif['Pts'].mean()
|
|
dg_local = clasif.loc[local, 'DG'] if local in clasif.index else clasif['DG'].mean()
|
|
dg_visit = clasif.loc[visitante, 'DG'] if visitante in clasif.index else clasif['DG'].mean()
|
|
# Estadísticas
|
|
gf_local = stats.loc[local, 'goles_favor'] if local in stats.index else stats['goles_favor'].mean()
|
|
gf_visit = stats.loc[visitante, 'goles_favor'] if visitante in stats.index else stats['goles_favor'].mean()
|
|
gc_local = stats.loc[local, 'goles_contra'] if local in stats.index else stats['goles_contra'].mean()
|
|
gc_visit = stats.loc[visitante, 'goles_contra'] if visitante in stats.index else stats['goles_contra'].mean()
|
|
disparos_local = stats.loc[local, 'disparos_puerta'] if local in stats.index else stats['disparos_puerta'].mean()
|
|
disparos_visit = stats.loc[visitante, 'disparos_puerta'] if visitante in stats.index else stats['disparos_puerta'].mean()
|
|
faltas_local = stats.loc[local, 'faltas'] if local in stats.index else stats['faltas'].mean()
|
|
faltas_visit = stats.loc[visitante, 'faltas'] if visitante in stats.index else stats['faltas'].mean()
|
|
amarillas_local = stats.loc[local, 'amarillas'] if local in stats.index else stats['amarillas'].mean()
|
|
amarillas_visit = stats.loc[visitante, 'amarillas'] if visitante in stats.index else stats['amarillas'].mean()
|
|
rojas_local = stats.loc[local, 'rojas'] if local in stats.index else stats['rojas'].mean()
|
|
rojas_visit = stats.loc[visitante, 'rojas'] if visitante in stats.index else stats['rojas'].mean()
|
|
features.append({
|
|
'local': local,
|
|
'visitante': visitante,
|
|
'dif_puntos': pts_local - pts_visit,
|
|
'dif_posicion': pos_visit - pos_local,
|
|
'dif_dg': dg_local - dg_visit,
|
|
'dif_gf': gf_local - gf_visit,
|
|
'dif_gc': gc_local - gc_visit,
|
|
'dif_disparos': disparos_local - disparos_visit,
|
|
'dif_faltas': faltas_local - faltas_visit,
|
|
'dif_amarillas': amarillas_local - amarillas_visit,
|
|
'dif_rojas': rojas_local - rojas_visit
|
|
})
|
|
|
|
# Por compatibilidad con el modelo actual, usamos solo dif_puntos (puedes reentrenar el modelo con más features luego)
|
|
df_pred = pd.DataFrame(features)
|
|
df_pred['dif_goles'] = df_pred['dif_puntos']
|
|
predicciones = clf.predict(df_pred[['dif_goles']])
|
|
df_pred['prediccion'] = predicciones
|
|
|
|
print("Predicciones para la jornada (con features de clasificación y estadísticas):")
|
|
print(df_pred[['local', 'visitante', 'dif_puntos', 'dif_posicion', 'dif_dg', 'dif_gf', 'dif_gc', 'dif_disparos', 'dif_faltas', 'dif_amarillas', 'dif_rojas', 'prediccion']])
|