Primer commit
This commit is contained in:
parent
21012274cb
commit
c8e351da00
|
|
@ -0,0 +1,21 @@
|
||||||
|
posicion,equipo,PJ,PG,PE,PP,GF,GC,DG,Pts,Racha1,Racha2,Racha3,Racha4,Racha5
|
||||||
|
1,Barcelona,33,28,1,4,87,30,57,85,G,G,G,G,G
|
||||||
|
2,Real Madrid,33,23,5,5,68,31,37,74,G,P,E,G,E
|
||||||
|
3,Villarreal,33,20,5,8,59,38,21,65,G,P,G,E,G
|
||||||
|
4,Atletico Madrid,33,18,6,9,56,37,19,60,P,P,P,P,G
|
||||||
|
5,Real Betis,33,12,14,7,49,41,8,50,P,E,E,G,E
|
||||||
|
6,Getafe,33,13,5,15,28,34,-6,44,G,G,P,G,P
|
||||||
|
7,Celta Vigo,33,11,11,11,45,43,2,44,P,G,P,P,P
|
||||||
|
8,Real Sociedad,33,11,10,12,52,52,0,43,P,G,E,P,E
|
||||||
|
9,Osasuna,33,11,9,13,39,40,-1,42,G,E,E,P,G
|
||||||
|
10,Athletic Club,33,12,5,16,36,48,-12,41,G,P,P,G,P
|
||||||
|
11,Rayo Vallecano,33,9,12,12,33,41,-8,39,P,G,P,G,E
|
||||||
|
12,Valencia,33,10,9,14,37,48,-11,39,G,P,P,E,G
|
||||||
|
13,Espanyol,33,10,9,14,37,49,-12,39,P,E,P,P,E
|
||||||
|
14,Elche,33,9,11,13,44,50,-6,38,G,P,G,G,G
|
||||||
|
15,Girona,33,9,11,13,36,50,-14,38,P,G,E,P,P
|
||||||
|
16,Deportivo Alaves,33,9,9,15,38,49,-11,36,G,E,E,P,G
|
||||||
|
17,Mallorca,33,9,8,16,41,51,-10,35,P,G,G,E,P
|
||||||
|
18,Sevilla,33,9,7,17,40,55,-15,34,P,P,G,P,P
|
||||||
|
19,Levante,33,8,9,16,37,50,-13,33,G,P,G,G,E
|
||||||
|
20,Real Oviedo,33,6,10,17,26,51,-25,28,P,G,G,E,P
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 98851d5d630896c679facf4fa693e48462566575
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
equipo,goles_favor,goles_contra,disparos_puerta,faltas,amarillas,rojas
|
||||||
|
Real Oviedo,26,51,109,426,67,8
|
||||||
|
Getafe CF,28,34,91,508,92,7
|
||||||
|
Rayo Vallecano,33,41,156,434,85,9
|
||||||
|
Girona FC,36,50,126,349,65,7
|
||||||
|
Athletic Club,36,48,149,450,66,7
|
||||||
|
Levante UD,37,50,116,420,75,4
|
||||||
|
Valencia CF,37,48,105,412,64,2
|
||||||
|
RCD Espanyol de Barcelona,37,49,134,455,74,5
|
||||||
|
Deportivo Alavés,38,49,130,501,71,5
|
||||||
|
CA Osasuna,39,40,126,445,80,6
|
||||||
|
Sevilla FC,40,55,113,481,92,5
|
||||||
|
RCD Mallorca,41,51,133,382,69,4
|
||||||
|
Elche CF,44,50,130,426,63,6
|
||||||
|
Celta,45,43,137,388,64,1
|
||||||
|
Real Betis,49,41,155,351,67,1
|
||||||
|
Real Sociedad,52,52,160,469,71,4
|
||||||
|
Atlético de Madrid,56,37,172,371,67,4
|
||||||
|
Villarreal CF,59,38,148,403,71,3
|
||||||
|
Real Madrid,68,31,231,330,58,7
|
||||||
|
FC Barcelona,87,30,233,309,50,2
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
Predicciones para la jornada (con features de clasificación y estadísticas):
|
||||||
|
local visitante ... dif_rojas prediccion
|
||||||
|
0 Villarreal Levante ... 0.00 1
|
||||||
|
1 Valencia At. Madrid ... 0.00 2
|
||||||
|
2 Alavés Athletic Club ... -2.15 1
|
||||||
|
3 Osasuna Barcelona ... 0.00 2
|
||||||
|
4 Celta Elche ... -3.85 1
|
||||||
|
5 Getafe Rayo Vallecano ... -4.15 1
|
||||||
|
6 Betis R. Oviedo ... 0.00 X
|
||||||
|
7 Espanyol Real Madrid ... -2.15 2
|
||||||
|
8 Cultural Leonesa Cádiz ... 0.00 X
|
||||||
|
9 Castellón Córdoba ... 0.00 X
|
||||||
|
10 Eibar Málaga ... 0.00 X
|
||||||
|
11 Racing Santander Huesca ... 0.00 X
|
||||||
|
12 Sporting Ceuta ... 0.00 X
|
||||||
|
13 Las Palmas Valladolid ... 0.00 X
|
||||||
|
14 Sevilla Real Sociedad ... 0.85 2
|
||||||
|
|
||||||
|
[15 rows x 12 columns]
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
# main.py
|
||||||
|
"""
|
||||||
|
Script principal para predecir quinielas de fútbol español.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("Bienvenido al predictor de quinielas de fútbol español.")
|
||||||
|
# Aquí se cargarán los datos, el modelo y se harán predicciones
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,15 @@
|
||||||
|
Villarreal - Levante
|
||||||
|
Valencia - At. Madrid
|
||||||
|
Alavés - Athletic Club
|
||||||
|
Osasuna - Barcelona
|
||||||
|
Celta - Elche
|
||||||
|
Getafe - Rayo Vallecano
|
||||||
|
Betis - R. Oviedo
|
||||||
|
Espanyol - Real Madrid
|
||||||
|
Cultural Leonesa - Cádiz
|
||||||
|
Castellón - Córdoba
|
||||||
|
Eibar - Málaga
|
||||||
|
Racing Santander - Huesca
|
||||||
|
Sporting - Ceuta
|
||||||
|
Las Palmas - Valladolid
|
||||||
|
Sevilla - Real Sociedad
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
pandas
|
||||||
|
requests
|
||||||
|
scikit-learn
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
# descargar_datos.py
|
||||||
|
"""
|
||||||
|
Script para descargar datos históricos de quinielas de fútbol español.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
|
||||||
|
def descargar_datos(url, destino):
|
||||||
|
response = requests.get(url)
|
||||||
|
if response.status_code == 200:
|
||||||
|
with open(destino, 'wb') as f:
|
||||||
|
f.write(response.content)
|
||||||
|
print(f"Datos descargados en {destino}")
|
||||||
|
else:
|
||||||
|
print(f"Error al descargar datos: {response.status_code}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Ejemplo de URL de datos históricos (reemplazar por una fuente válida)
|
||||||
|
url = "https://www.example.com/quinielas_historico.csv"
|
||||||
|
destino = os.path.join(os.path.dirname(__file__), '../data/quinielas_historico.csv')
|
||||||
|
descargar_datos(url, destino)
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
# entrenar_modelo.py
|
||||||
|
"""
|
||||||
|
Entrena y evalúa un modelo simple para predecir quinielas (1/X/2).
|
||||||
|
"""
|
||||||
|
import pandas as pd
|
||||||
|
from sklearn.model_selection import train_test_split
|
||||||
|
from sklearn.ensemble import RandomForestClassifier
|
||||||
|
from sklearn.metrics import classification_report, accuracy_score
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Cargar datos
|
||||||
|
DATA_PATH = os.path.join(os.path.dirname(__file__), '../data/espana/partidos_todos.csv')
|
||||||
|
df = pd.read_csv(DATA_PATH)
|
||||||
|
|
||||||
|
# Features simples: diferencia de goles históricos entre local y visitante
|
||||||
|
# (Para un modelo más avanzado, se pueden agregar más features)
|
||||||
|
df['dif_goles'] = df['goles_local'] - df['goles_visitante']
|
||||||
|
|
||||||
|
# Features y etiquetas
|
||||||
|
X = df[['dif_goles']]
|
||||||
|
y = df['resultado']
|
||||||
|
|
||||||
|
# Separar en train/test
|
||||||
|
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
||||||
|
|
||||||
|
# Modelo
|
||||||
|
clf = RandomForestClassifier(n_estimators=100, random_state=42)
|
||||||
|
clf.fit(X_train, y_train)
|
||||||
|
|
||||||
|
# Predicción y evaluación
|
||||||
|
y_pred = clf.predict(X_test)
|
||||||
|
print("Accuracy:", accuracy_score(y_test, y_pred))
|
||||||
|
print("\nClassification report:\n", classification_report(y_test, y_pred))
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
# predecir_jornada.py
|
||||||
|
"""
|
||||||
|
Predice los resultados de una jornada futura usando el modelo entrenado.
|
||||||
|
"""
|
||||||
|
|
||||||
|
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')
|
||||||
|
|
||||||
|
# Cargar datos históricos
|
||||||
|
df_hist = pd.read_csv(DATA_PATH)
|
||||||
|
|
||||||
|
# Calcular medias históricas de goles local y visitante
|
||||||
|
media_goles_local = df_hist.groupby('local')['goles_local'].mean().to_dict()
|
||||||
|
media_goles_visitante = df_hist.groupby('visitante')['goles_visitante'].mean().to_dict()
|
||||||
|
|
||||||
|
# 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
|
||||||
|
partidos = []
|
||||||
|
if os.path.exists(PARTIDOS_PATH):
|
||||||
|
with open(PARTIDOS_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)]
|
||||||
|
goles_local = media_goles_local.get(local, df_hist['goles_local'].mean())
|
||||||
|
goles_visitante = media_goles_visitante.get(visitante, df_hist['goles_visitante'].mean())
|
||||||
|
dif_goles = goles_local - goles_visitante
|
||||||
|
partidos.append({'local': local, 'visitante': visitante, 'dif_goles': dif_goles})
|
||||||
|
else:
|
||||||
|
print(f"No se encontró el archivo {PARTIDOS_PATH}")
|
||||||
|
|
||||||
|
if partidos:
|
||||||
|
df_pred = pd.DataFrame(partidos)
|
||||||
|
predicciones = clf.predict(df_pred[['dif_goles']])
|
||||||
|
df_pred['prediccion'] = predicciones
|
||||||
|
print("\nPredicciones para la jornada:")
|
||||||
|
print(df_pred[['local', 'visitante', 'prediccion']])
|
||||||
|
else:
|
||||||
|
print("No se introdujeron partidos.")
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
# predecir_jornada_mejorado.py
|
||||||
|
"""
|
||||||
|
Predice resultados de la quiniela usando features de la clasificación actual.
|
||||||
|
"""
|
||||||
|
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')
|
||||||
|
|
||||||
|
# Cargar datos históricos y clasificación
|
||||||
|
clasif = pd.read_csv(CLASIF_PATH)
|
||||||
|
clasif.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
|
||||||
|
features = []
|
||||||
|
for p in partidos:
|
||||||
|
local = p['local']
|
||||||
|
visitante = p['visitante']
|
||||||
|
# Si el equipo no está en la clasificación, usar valores medios
|
||||||
|
if local in clasif.index:
|
||||||
|
pos_local = clasif.loc[local, 'posicion']
|
||||||
|
pts_local = clasif.loc[local, 'Pts']
|
||||||
|
dg_local = clasif.loc[local, 'DG']
|
||||||
|
else:
|
||||||
|
pos_local = clasif['posicion'].mean()
|
||||||
|
pts_local = clasif['Pts'].mean()
|
||||||
|
dg_local = clasif['DG'].mean()
|
||||||
|
if visitante in clasif.index:
|
||||||
|
pos_visit = clasif.loc[visitante, 'posicion']
|
||||||
|
pts_visit = clasif.loc[visitante, 'Pts']
|
||||||
|
dg_visit = clasif.loc[visitante, 'DG']
|
||||||
|
else:
|
||||||
|
pos_visit = clasif['posicion'].mean()
|
||||||
|
pts_visit = clasif['Pts'].mean()
|
||||||
|
dg_visit = clasif['DG'].mean()
|
||||||
|
features.append({
|
||||||
|
'local': local,
|
||||||
|
'visitante': visitante,
|
||||||
|
'dif_puntos': pts_local - pts_visit,
|
||||||
|
'dif_posicion': pos_visit - pos_local, # positivo si local va mejor
|
||||||
|
'dif_dg': dg_local - dg_visit
|
||||||
|
})
|
||||||
|
|
||||||
|
# Predecir usando el modelo (por ahora solo con dif_goles, pero mostramos features para extender)
|
||||||
|
df_pred = pd.DataFrame(features)
|
||||||
|
# Usar solo dif_puntos como feature para el modelo actual (puedes reentrenar el modelo con más features luego)
|
||||||
|
df_pred['dif_goles'] = df_pred['dif_puntos'] # placeholder para compatibilidad
|
||||||
|
predicciones = clf.predict(df_pred[['dif_goles']])
|
||||||
|
df_pred['prediccion'] = predicciones
|
||||||
|
|
||||||
|
print("Predicciones para la jornada (con features de clasificación):")
|
||||||
|
print(df_pred[['local', 'visitante', 'dif_puntos', 'dif_posicion', 'dif_dg', 'prediccion']])
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
# 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']])
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
# procesar_txt_a_csv.py
|
||||||
|
"""
|
||||||
|
Convierte archivos de texto de resultados de fútbol a formato CSV.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import csv
|
||||||
|
from glob import glob
|
||||||
|
|
||||||
|
# Carpeta base de datos
|
||||||
|
BASE_DIR = os.path.join(os.path.dirname(__file__), '../data/espana')
|
||||||
|
|
||||||
|
# Expresión regular para partidos
|
||||||
|
PARTIDO_REGEX = re.compile(r"\s*(\d{1,2}\.\d{2})?\s*([\w .ÁÉÍÓÚÑáéíóúñB]+)\s+v\s+([\w .ÁÉÍÓÚÑáéíóúñB]+)\s+(\d+)-(\d+)")
|
||||||
|
|
||||||
|
# Expresión regular para fecha de jornada
|
||||||
|
FECHA_REGEX = re.compile(r"\s*(\d{1,2}\.\d{2})?\s*([A-Za-z]{3,9})\s*(\w+)?")
|
||||||
|
|
||||||
|
def procesar_archivo_txt(ruta_txt, temporada, division, salida_csv):
|
||||||
|
with open(ruta_txt, 'r', encoding='utf-8') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
jornada = None
|
||||||
|
fecha = None
|
||||||
|
partidos = []
|
||||||
|
for line in lines:
|
||||||
|
line = line.strip()
|
||||||
|
if line.startswith('» Matchday'):
|
||||||
|
jornada = line.split()[-1]
|
||||||
|
elif re.match(r"\d{2}\.\d{2}", line) or line.startswith(('Sat', 'Sun', 'Mon', 'Fri', 'Thu', 'Wed', 'Tue')):
|
||||||
|
fecha = line
|
||||||
|
elif 'v' in line and '-' in line:
|
||||||
|
m = PARTIDO_REGEX.search(line)
|
||||||
|
if m:
|
||||||
|
equipo_local = m.group(2).strip()
|
||||||
|
equipo_visitante = m.group(3).strip()
|
||||||
|
goles_local = int(m.group(4))
|
||||||
|
goles_visitante = int(m.group(5))
|
||||||
|
if goles_local > goles_visitante:
|
||||||
|
resultado = '1'
|
||||||
|
elif goles_local < goles_visitante:
|
||||||
|
resultado = '2'
|
||||||
|
else:
|
||||||
|
resultado = 'X'
|
||||||
|
partidos.append([
|
||||||
|
temporada, division, jornada, fecha, equipo_local, equipo_visitante, goles_local, goles_visitante, resultado
|
||||||
|
])
|
||||||
|
|
||||||
|
with open(salida_csv, 'w', newline='', encoding='utf-8') as f:
|
||||||
|
writer = csv.writer(f)
|
||||||
|
writer.writerow(['temporada', 'division', 'jornada', 'fecha', 'local', 'visitante', 'goles_local', 'goles_visitante', 'resultado'])
|
||||||
|
writer.writerows(partidos)
|
||||||
|
print(f"Procesado {ruta_txt} -> {salida_csv}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Procesar todos los archivos txt de todas las temporadas y divisiones
|
||||||
|
for temporada in os.listdir(BASE_DIR):
|
||||||
|
temp_path = os.path.join(BASE_DIR, temporada)
|
||||||
|
if os.path.isdir(temp_path):
|
||||||
|
for archivo in os.listdir(temp_path):
|
||||||
|
if archivo.endswith('.txt'):
|
||||||
|
division = archivo.split('-')[1].replace('.txt', '') if '-' in archivo else '1'
|
||||||
|
ruta_txt = os.path.join(temp_path, archivo)
|
||||||
|
salida_csv = os.path.join(temp_path, archivo.replace('.txt', '.csv'))
|
||||||
|
procesar_archivo_txt(ruta_txt, temporada, division, salida_csv)
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
# unir_y_analizar_csv.py
|
||||||
|
"""
|
||||||
|
Une todos los CSV de partidos en uno solo y analiza la cantidad de datos.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import pandas as pd
|
||||||
|
from glob import glob
|
||||||
|
|
||||||
|
BASE_DIR = os.path.join(os.path.dirname(__file__), '../data/espana')
|
||||||
|
SALIDA = os.path.join(BASE_DIR, 'partidos_todos.csv')
|
||||||
|
|
||||||
|
# Buscar todos los CSV de partidos
|
||||||
|
csvs = glob(os.path.join(BASE_DIR, '*', '*.csv'))
|
||||||
|
|
||||||
|
# Unir todos los CSV
|
||||||
|
dfs = []
|
||||||
|
for csv_file in csvs:
|
||||||
|
df = pd.read_csv(csv_file)
|
||||||
|
dfs.append(df)
|
||||||
|
|
||||||
|
df_total = pd.concat(dfs, ignore_index=True)
|
||||||
|
df_total.to_csv(SALIDA, index=False)
|
||||||
|
|
||||||
|
# Análisis básico
|
||||||
|
total_partidos = len(df_total)
|
||||||
|
print(f"Total de partidos: {total_partidos}")
|
||||||
|
print("Primeras filas:")
|
||||||
|
print(df_total.head())
|
||||||
|
print("Distribución de resultados:")
|
||||||
|
print(df_total['resultado'].value_counts())
|
||||||
Loading…
Reference in New Issue