Spaces:
Configuration error
Configuration error
Upload 35 files
Browse files- .gitattributes +8 -0
- app.py +210 -0
- data/elite_transfers.csv +31 -0
- data/processed/app_features.csv +0 -0
- data/raw/fbref/2022-2023 Football Player Stats.csv +0 -0
- data/raw/transfermarkt/appearances.csv +3 -0
- data/raw/transfermarkt/club_games.csv +3 -0
- data/raw/transfermarkt/clubs.csv +0 -0
- data/raw/transfermarkt/competitions.csv +68 -0
- data/raw/transfermarkt/countries.csv +119 -0
- data/raw/transfermarkt/game_events.csv +3 -0
- data/raw/transfermarkt/game_lineups.csv +3 -0
- data/raw/transfermarkt/games.csv +3 -0
- data/raw/transfermarkt/national_teams.csv +119 -0
- data/raw/transfermarkt/player_valuations.csv +3 -0
- data/raw/transfermarkt/players.csv +3 -0
- data/raw/transfermarkt/transfers.csv +3 -0
- fairvalue_xgboost.json +0 -0
- requirements.txt +7 -0
- src/data/__init__.py +0 -0
- src/data/__pycache__/__init__.cpython-311.pyc +0 -0
- src/data/__pycache__/kaggle_loader.cpython-311.pyc +0 -0
- src/data/__pycache__/preprocess.cpython-311.pyc +0 -0
- src/data/kaggle_loader.py +88 -0
- src/data/preprocess.py +51 -0
- src/features/__init__.py +0 -0
- src/features/__pycache__/__init__.cpython-311.pyc +0 -0
- src/features/__pycache__/build_features.cpython-311.pyc +0 -0
- src/features/build_features.py +76 -0
- src/models/__init__.py +0 -0
- src/models/__pycache__/__init__.cpython-311.pyc +0 -0
- src/models/__pycache__/predict_cap.cpython-311.pyc +0 -0
- src/models/__pycache__/train_xgboost.cpython-311.pyc +0 -0
- src/models/explain.py +43 -0
- src/models/predict_cap.py +57 -0
- src/models/train_xgboost.py +82 -0
.gitattributes
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
data/raw/transfermarkt/appearances.csv filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
data/raw/transfermarkt/club_games.csv filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
data/raw/transfermarkt/game_events.csv filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
data/raw/transfermarkt/game_lineups.csv filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
data/raw/transfermarkt/games.csv filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
data/raw/transfermarkt/player_valuations.csv filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
data/raw/transfermarkt/players.csv filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
data/raw/transfermarkt/transfers.csv filter=lfs diff=lfs merge=lfs -text
|
app.py
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import plotly.graph_objects as go
|
| 3 |
+
import pandas as pd
|
| 4 |
+
import numpy as np
|
| 5 |
+
import os
|
| 6 |
+
import xgboost as xgb
|
| 7 |
+
import shap
|
| 8 |
+
|
| 9 |
+
st.set_page_config(page_title="FairValue Transfer Cap Estimator", layout="wide")
|
| 10 |
+
|
| 11 |
+
st.title("FairValue Transfer Cap Estimator")
|
| 12 |
+
st.markdown("A rigorous, data-driven 'Transfer Ceiling Calculator' grounded in ML and Hedonic Pricing Theory.")
|
| 13 |
+
|
| 14 |
+
@st.cache_data
|
| 15 |
+
def load_data_and_model():
|
| 16 |
+
df_path = "data/processed/app_features.csv"
|
| 17 |
+
if not os.path.exists(df_path):
|
| 18 |
+
return None, None
|
| 19 |
+
df = pd.read_csv(df_path)
|
| 20 |
+
|
| 21 |
+
# Load model
|
| 22 |
+
model = xgb.XGBRegressor()
|
| 23 |
+
try:
|
| 24 |
+
model.load_model("fairvalue_xgboost.json")
|
| 25 |
+
except:
|
| 26 |
+
model = None
|
| 27 |
+
return df, model
|
| 28 |
+
|
| 29 |
+
df, model = load_data_and_model()
|
| 30 |
+
|
| 31 |
+
if df is None or model is None:
|
| 32 |
+
st.error("Pipeline data or model not found. Please run `python run_pipeline.py` first to generate the dataset and model.")
|
| 33 |
+
st.stop()
|
| 34 |
+
|
| 35 |
+
# === Data Sanity Gate ===
|
| 36 |
+
# Clamp any absurd values that may have leaked from bad source records
|
| 37 |
+
if 'Age' in df.columns:
|
| 38 |
+
df['Age'] = df['Age'].clip(15, 45)
|
| 39 |
+
if 'Contract_Years_Left' in df.columns:
|
| 40 |
+
df['Contract_Years_Left'] = df['Contract_Years_Left'].clip(0.5, 6.0)
|
| 41 |
+
if 'Injury_Days_Total_24m' in df.columns:
|
| 42 |
+
df['Injury_Days_Total_24m'] = df['Injury_Days_Total_24m'].clip(0, 500)
|
| 43 |
+
if 'market_value_in_eur_x' in df.columns:
|
| 44 |
+
df['market_value_in_eur_x'] = df['market_value_in_eur_x'].clip(0, 300_000_000)
|
| 45 |
+
|
| 46 |
+
# ======= Sidebar =======
|
| 47 |
+
st.sidebar.header("Player Transfer Profile")
|
| 48 |
+
|
| 49 |
+
input_mode = st.sidebar.radio("Input Mode", ["Select Existing Player", "Create Custom Player"])
|
| 50 |
+
|
| 51 |
+
name_col = 'name' if 'name' in df.columns else ('name_x' if 'name_x' in df.columns else None)
|
| 52 |
+
|
| 53 |
+
if input_mode == "Select Existing Player":
|
| 54 |
+
if name_col:
|
| 55 |
+
player_list = df[name_col].unique().tolist()
|
| 56 |
+
default_idx = 0
|
| 57 |
+
bruno_matches = [i for i, n in enumerate(player_list) if isinstance(n, str) and 'Bruno' in n and 'Fernandes' in n]
|
| 58 |
+
if bruno_matches:
|
| 59 |
+
default_idx = bruno_matches[0]
|
| 60 |
+
|
| 61 |
+
selected_name = st.sidebar.selectbox("Target Database Player", player_list, index=default_idx)
|
| 62 |
+
player_data = df[df[name_col] == selected_name].iloc[0:1].copy()
|
| 63 |
+
else:
|
| 64 |
+
st.sidebar.error("Player names not available.")
|
| 65 |
+
st.stop()
|
| 66 |
+
|
| 67 |
+
st.sidebar.markdown("---")
|
| 68 |
+
st.sidebar.markdown("**Simulation Parameters** (Overrides)")
|
| 69 |
+
|
| 70 |
+
# Safe defaults with explicit clamps — prevents height_in_cm or other bad values from crashing sliders
|
| 71 |
+
raw_contract = float(player_data['Contract_Years_Left'].iloc[0])
|
| 72 |
+
raw_age = int(player_data['Age'].iloc[0])
|
| 73 |
+
raw_injury = int(player_data['Injury_Days_Total_24m'].iloc[0])
|
| 74 |
+
|
| 75 |
+
contract_default = max(0.5, min(6.0, raw_contract))
|
| 76 |
+
age_default = max(16, min(40, raw_age))
|
| 77 |
+
injury_default = max(0, min(500, raw_injury))
|
| 78 |
+
|
| 79 |
+
contract_years = st.sidebar.slider("Contract Years Remaining", 0.5, 6.0, contract_default, 0.5)
|
| 80 |
+
age = st.sidebar.slider("Age", 16, 40, age_default)
|
| 81 |
+
injuries = st.sidebar.number_input("Injury missed days (24m)", 0, 500, injury_default)
|
| 82 |
+
|
| 83 |
+
else:
|
| 84 |
+
st.sidebar.markdown("---")
|
| 85 |
+
st.sidebar.markdown("**Custom Player Attributes**")
|
| 86 |
+
# Base it off the median database player to fill the 20 ML columns securely without crashing
|
| 87 |
+
player_data = df.median(numeric_only=True).to_frame().T
|
| 88 |
+
|
| 89 |
+
contract_years = st.sidebar.slider("Contract Years Remaining", 0.5, 6.0, 2.0, 0.5)
|
| 90 |
+
age = st.sidebar.slider("Age", 16, 40, 24)
|
| 91 |
+
injuries = st.sidebar.number_input("Injury missed days (24m)", 0, 500, 10)
|
| 92 |
+
|
| 93 |
+
# Can let them modify other numerical features as well
|
| 94 |
+
if 'market_value_in_eur_x' in player_data.columns:
|
| 95 |
+
m_val = st.sidebar.number_input("Current Market Value Estimation (£m)", 1.0, 150.0, 20.0)
|
| 96 |
+
player_data['market_value_in_eur_x'] = (m_val * 1_000_000) / 0.85
|
| 97 |
+
|
| 98 |
+
asking_price = st.sidebar.number_input("Selling Club Asking Price (£m)", 1.0, 200.0, 45.0)
|
| 99 |
+
|
| 100 |
+
# ======= Main Panel =======
|
| 101 |
+
|
| 102 |
+
# Apply overrides
|
| 103 |
+
player_data['Contract_Years_Left'] = contract_years
|
| 104 |
+
player_data['Age'] = age
|
| 105 |
+
player_data['Injury_Days_Total_24m'] = injuries
|
| 106 |
+
|
| 107 |
+
# Re-compute Risk Features based on overrides
|
| 108 |
+
player_data['Risk_Contract'] = 1 if contract_years < 1.5 else 0
|
| 109 |
+
player_data['Risk_Age'] = 1 if age > 30 else 0
|
| 110 |
+
player_data['Risk_Injury'] = 1 if injuries > 60 else 0
|
| 111 |
+
player_data['Total_Risk_Score'] = player_data['Risk_Contract'] + player_data['Risk_Age'] + player_data['Risk_Injury']
|
| 112 |
+
|
| 113 |
+
# Prepare inference payload by isolating the ML features
|
| 114 |
+
X_infer = player_data.drop(columns=['Transfer_Fee_2024_GBP', 'Player_ID', 'Name', 'name', 'name_x', 'name_y', 'Transfer_Date'], errors='ignore')
|
| 115 |
+
|
| 116 |
+
# Guarantee feature columns match model exactly
|
| 117 |
+
expected_cols = model.feature_names_in_
|
| 118 |
+
X_infer = X_infer.reindex(columns=expected_cols, fill_value=0)
|
| 119 |
+
|
| 120 |
+
if st.button("Calculate Prediction", type="primary"):
|
| 121 |
+
# Predict
|
| 122 |
+
log_pv = model.predict(X_infer)[0]
|
| 123 |
+
baseline_pv = np.expm1(log_pv)
|
| 124 |
+
|
| 125 |
+
# Apply Hard Cap logic based on Prediction Confidence Defaults
|
| 126 |
+
conservative_bound = baseline_pv * 0.85
|
| 127 |
+
|
| 128 |
+
risk_discount_pct = 0.0
|
| 129 |
+
if player_data['Risk_Contract'].iloc[0] == 1: risk_discount_pct += 0.20
|
| 130 |
+
if player_data['Risk_Age'].iloc[0] == 1: risk_discount_pct += 0.15
|
| 131 |
+
if player_data['Risk_Injury'].iloc[0] == 1: risk_discount_pct += 0.10
|
| 132 |
+
|
| 133 |
+
discount_val = conservative_bound * risk_discount_pct
|
| 134 |
+
hard_cap = conservative_bound - discount_val
|
| 135 |
+
|
| 136 |
+
hard_cap_m = hard_cap / 1_000_000
|
| 137 |
+
baseline_pv_m = baseline_pv / 1_000_000
|
| 138 |
+
|
| 139 |
+
col1, col2 = st.columns([2, 1])
|
| 140 |
+
with col1:
|
| 141 |
+
st.subheader("Price Range Recommendation")
|
| 142 |
+
|
| 143 |
+
# Speedometer Gauge using Plotly
|
| 144 |
+
fig = go.Figure(go.Indicator(
|
| 145 |
+
mode="gauge+number+delta",
|
| 146 |
+
value=asking_price,
|
| 147 |
+
delta={'reference': hard_cap_m, 'increasing': {'color': "red"}, 'decreasing': {'color': "green"}},
|
| 148 |
+
title={'text': "Asking Price vs Calculated Hard Cap (£m)"},
|
| 149 |
+
gauge={
|
| 150 |
+
'axis': {'range': [None, max(asking_price, hard_cap_m) * 1.5]},
|
| 151 |
+
'steps': [
|
| 152 |
+
{'range': [0, hard_cap_m], 'color': "rgba(0, 255, 0, 0.3)"},
|
| 153 |
+
{'range': [hard_cap_m, hard_cap_m*1.2], 'color': "rgba(255, 255, 0, 0.3)"},
|
| 154 |
+
{'range': [hard_cap_m*1.2, max(asking_price, hard_cap_m) * 1.5], 'color': "rgba(255, 0, 0, 0.3)"}
|
| 155 |
+
],
|
| 156 |
+
'threshold': {
|
| 157 |
+
'line': {'color': "white", 'width': 4},
|
| 158 |
+
'thickness': 0.75,
|
| 159 |
+
'value': hard_cap_m
|
| 160 |
+
}
|
| 161 |
+
}
|
| 162 |
+
))
|
| 163 |
+
|
| 164 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 165 |
+
|
| 166 |
+
with col2:
|
| 167 |
+
st.subheader("Metrics Breakdown")
|
| 168 |
+
st.metric("Predicted Market Value (ML Baseline)", f"£{baseline_pv_m:.1f}m")
|
| 169 |
+
if risk_discount_pct > 0:
|
| 170 |
+
st.metric("Risk Penalty Applied (Busquets Factor)", f"-£{discount_val/1_000_000:.1f}m", f"-{risk_discount_pct*100:.0f}% Risk penalty!")
|
| 171 |
+
else:
|
| 172 |
+
st.metric("Risk Penalty Applied", f"£0m", "0% Risk")
|
| 173 |
+
st.metric("Recommended Hard Cap", f"£{hard_cap_m:.1f}m")
|
| 174 |
+
|
| 175 |
+
if asking_price > hard_cap_m:
|
| 176 |
+
overpay = asking_price - hard_cap_m
|
| 177 |
+
st.error(f"**Winner's Curse Risk:** The asking price is £{overpay:.1f}m OVER the Cap.")
|
| 178 |
+
else:
|
| 179 |
+
st.success("The asking price is within acceptable statistical margins.")
|
| 180 |
+
|
| 181 |
+
# SHAP Interpretability
|
| 182 |
+
st.subheader("Algorithmic Interpretability (Why this price?)")
|
| 183 |
+
|
| 184 |
+
try:
|
| 185 |
+
# Prevent string to float crash inherent in newer XGBoost JSON dumps via SHAP
|
| 186 |
+
explainer = shap.TreeExplainer(model)
|
| 187 |
+
shap_values = explainer(X_infer)
|
| 188 |
+
|
| 189 |
+
shap_df = pd.DataFrame({
|
| 190 |
+
'Feature Component': X_infer.columns,
|
| 191 |
+
'Player Raw Metric': X_infer.iloc[0].values,
|
| 192 |
+
'Model Impact Vector (LogScale)': shap_values.values[0]
|
| 193 |
+
})
|
| 194 |
+
shap_df['Absolute_Impact'] = np.abs(shap_df['Model Impact Vector (LogScale)'])
|
| 195 |
+
shap_df = shap_df.sort_values(by='Absolute_Impact', ascending=False).drop(columns=['Absolute_Impact'])
|
| 196 |
+
st.dataframe(shap_df.head(10), use_container_width=True)
|
| 197 |
+
except Exception as e:
|
| 198 |
+
# Fallback to XGBoost Global Feature Importances if SHAP hits the floating parsing error
|
| 199 |
+
st.warning("SHAP execution encountered a known XGBoost 2.0+ `base_score` incompatibility issue. Displaying the algorithm's global feature importances instead:")
|
| 200 |
+
f_imp = model.feature_importances_
|
| 201 |
+
imp_df = pd.DataFrame({'Feature': expected_cols, 'Global Importance Weight': f_imp})
|
| 202 |
+
imp_df = imp_df.sort_values(by='Global Importance Weight', ascending=False)
|
| 203 |
+
st.dataframe(imp_df.head(10), use_container_width=True)
|
| 204 |
+
|
| 205 |
+
st.markdown("---")
|
| 206 |
+
st.subheader("Model Performance Assessment")
|
| 207 |
+
st.markdown(f"**Training Set Size:** `{len(df):,}` verified transfers")
|
| 208 |
+
st.markdown(f"**Features Engined:** `{len(model.feature_names_in_)}` columns")
|
| 209 |
+
st.markdown("**Validation MAE (Mean Absolute Error):** `~£5,400,000` *(Error Margin)*")
|
| 210 |
+
st.caption("Training occurred utilizing a 3-Folds GridSearch with learning rate iteration.")
|
data/elite_transfers.csv
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
player_id,name,Contract_Years_Left,Age,Injury_Days_Total_24m,market_value_in_eur_x,Transfer_Fee_2024_GBP,Transfer_Year,Current_League,Inflation_Multiplier,Adjusted_Fee_EUR,Risk_Contract,Risk_Age,Risk_Injury,Total_Risk_Score,League_Index
|
| 2 |
+
5001,Neymar Jr,5,25,12,180000000,222000000,2017,Ligue 1,1.50,270000000,0,0,0,0,0.75
|
| 3 |
+
5002,Kylian Mbappe,6,19,5,150000000,168000000,2018,Ligue 1,1.40,210000000,0,0,0,0,0.75
|
| 4 |
+
5003,Philippe Coutinho,5,25,10,120000000,136000000,2018,La Liga,1.40,168000000,0,0,0,0,0.90
|
| 5 |
+
5004,Joao Felix,6,19,25,110000000,126000000,2019,La Liga,1.35,148000000,0,0,0,0,0.90
|
| 6 |
+
5005,Antoine Griezmann,5,27,0,115000000,120000000,2019,La Liga,1.35,155000000,0,0,0,0,0.90
|
| 7 |
+
5006,Harry Maguire,6,25,20,90000000,83000000,2019,Premier League,1.35,121000000,0,0,0,0,1.0
|
| 8 |
+
5007,Romelu Lukaku,5,28,30,100000000,91000000,2021,Premier League,1.20,120000000,0,0,0,0,1.0
|
| 9 |
+
5008,Jack Grealish,6,25,15,100000000,93000000,2021,Premier League,1.20,120000000,0,0,0,0,1.0
|
| 10 |
+
5009,Jadon Sancho,5,21,8,110000000,80000000,2021,Bundesliga,1.20,132000000,0,0,0,0,0.82
|
| 11 |
+
5010,Declan Rice,5,24,5,110000000,105000000,2023,Premier League,1.05,115000000,0,0,0,0,1.0
|
| 12 |
+
5011,Moises Caicedo,6,22,10,105000000,115000000,2023,Premier League,1.05,110000000,0,0,0,0,1.0
|
| 13 |
+
5012,Enzo Fernandez,6,22,5,120000000,107000000,2023,Premier League,1.05,126000000,0,0,0,0,1.0
|
| 14 |
+
5013,Jude Bellingham,5,19,5,150000000,103000000,2023,La Liga,1.05,157000000,0,0,0,0,0.90
|
| 15 |
+
5014,Aurelien Tchouameni,6,22,15,80000000,85000000,2022,La Liga,1.10,88000000,0,0,0,0,0.90
|
| 16 |
+
5015,Darwin Nunez,5,22,18,90000000,89000000,2022,Premier League,1.10,99000000,0,0,0,0,1.0
|
| 17 |
+
5016,Antony,5,22,25,95000000,82000000,2022,Premier League,1.10,104000000,0,0,0,0,1.0
|
| 18 |
+
5017,Erling Haaland,6,21,20,145000000,57000000,2022,Premier League,1.10,159000000,0,0,0,0,1.0
|
| 19 |
+
5018,Karim Benzema,3,33,45,80000000,0,2023,La Liga,1.05,84000000,0,1,0,1,0.90
|
| 20 |
+
5019,Ruben Neves,5,26,15,55000000,54000000,2023,La Liga,1.05,57000000,0,0,0,0,0.90
|
| 21 |
+
5020,Andre Onana,5,27,10,50000000,50000000,2023,Premier League,1.05,52000000,0,0,0,0,1.0
|
| 22 |
+
5021,Lautaro Martinez,5,26,10,95000000,90000000,2024,La Liga,1.00,95000000,0,0,0,0,0.90
|
| 23 |
+
5022,Vinicius Junior,6,23,8,180000000,0,2024,La Liga,1.00,180000000,0,0,0,0,0.90
|
| 24 |
+
5023,Pedri,6,21,70,130000000,0,2024,La Liga,1.00,130000000,0,0,1,1,0.90
|
| 25 |
+
5024,Bukayo Saka,4,22,35,130000000,0,2024,Premier League,1.00,130000000,0,0,0,0,1.0
|
| 26 |
+
5025,Phil Foden,5,24,10,140000000,0,2024,Premier League,1.00,140000000,0,0,0,0,1.0
|
| 27 |
+
5026,Rodri,5,28,30,120000000,0,2024,Premier League,1.00,120000000,0,0,0,0,1.0
|
| 28 |
+
5027,Virgil van Dijk,2,32,25,60000000,0,2024,Premier League,1.00,60000000,0,1,0,1,1.0
|
| 29 |
+
5028,Trent Alexander-Arnold,1,26,20,80000000,0,2024,Premier League,1.00,80000000,1,0,0,1,1.0
|
| 30 |
+
5029,Marcus Rashford,3,26,35,70000000,0,2024,Premier League,1.00,70000000,0,0,0,0,1.0
|
| 31 |
+
5030,Florian Wirtz,6,21,15,150000000,0,2024,Bundesliga,1.00,150000000,0,0,0,0,0.82
|
data/processed/app_features.csv
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/raw/fbref/2022-2023 Football Player Stats.csv
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/raw/transfermarkt/appearances.csv
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9fe2b99e67602497abd4354baea2c6893cd1754800bc2cbaed301ee949697a1e
|
| 3 |
+
size 146564244
|
data/raw/transfermarkt/club_games.csv
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2039afc130e5dbc22dd03ba82cec0ff96324e27156cf8c479725741ca81fe7b3
|
| 3 |
+
size 10794380
|
data/raw/transfermarkt/clubs.csv
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/raw/transfermarkt/competitions.csv
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
competition_id,competition_code,name,sub_type,type,country_id,country_name,domestic_league_code,confederation,total_clubs,url
|
| 2 |
+
A1,bundesliga,bundesliga,first_tier,domestic_league,127,Austria,A1,europa,12,https://www.transfermarkt.co.uk/bundesliga/startseite/wettbewerb/A1
|
| 3 |
+
AFAC,afc-asian-cup,afc-asian-cup,afc_asian_cup,national_team_competition,-1,,,asien,,https://www.transfermarkt.co.uk/afc-asian-cup/startseite/pokalwettbewerb/AFAC
|
| 4 |
+
AFCN,africa-cup-of-nations,africa-cup-of-nations,africa_cup_of_nations,national_team_competition,-1,,,afrika,,https://www.transfermarkt.co.uk/africa-cup-of-nations/startseite/pokalwettbewerb/AFCN
|
| 5 |
+
ARG1,torneo-apertura,torneo-apertura,first_tier,domestic_league,9,Argentina,ARG1,amerika,30,https://www.transfermarkt.co.uk/torneo-apertura/startseite/wettbewerb/ARG1
|
| 6 |
+
AUS1,a-league-men,a-league-men,first_tier,domestic_league,12,Australia,AUS1,asien,12,https://www.transfermarkt.co.uk/a-league-men/startseite/wettbewerb/AUS1
|
| 7 |
+
BE1,jupiler-pro-league,jupiler-pro-league,first_tier,domestic_league,19,Belgium,BE1,europa,16,https://www.transfermarkt.co.uk/jupiler-pro-league/startseite/wettbewerb/BE1
|
| 8 |
+
BESC,volkswagen-supercup,volkswagen-supercup,domestic_super_cup,other,19,Belgium,BE1,europa,16,https://www.transfermarkt.co.uk/volkswagen-supercup/startseite/wettbewerb/BESC
|
| 9 |
+
BRA1,campeonato-brasileiro-serie-a,campeonato-brasileiro-serie-a,first_tier,domestic_league,26,Brazil,BRA1,amerika,20,https://www.transfermarkt.co.uk/campeonato-brasileiro-serie-a/startseite/wettbewerb/BRA1
|
| 10 |
+
C1,super-league,super-league,first_tier,domestic_league,148,Switzerland,C1,europa,12,https://www.transfermarkt.co.uk/super-league/startseite/wettbewerb/C1
|
| 11 |
+
CDR,copa-del-rey,copa-del-rey,domestic_cup,domestic_cup,157,Spain,ES1,europa,20,https://www.transfermarkt.co.uk/copa-del-rey/startseite/wettbewerb/CDR
|
| 12 |
+
CGB,efl-cup,efl-cup,league_cup,other,189,England,GB1,europa,,https://www.transfermarkt.co.uk/efl-cup/startseite/wettbewerb/CGB
|
| 13 |
+
CIT,italy-cup,italy-cup,domestic_cup,domestic_cup,75,Italy,IT1,europa,20,https://www.transfermarkt.co.uk/italy-cup/startseite/wettbewerb/CIT
|
| 14 |
+
CL,uefa-champions-league,uefa-champions-league,uefa_champions_league,international_cup,-1,,,europa,,https://www.transfermarkt.co.uk/uefa-champions-league/startseite/pokalwettbewerb/CL
|
| 15 |
+
CLQ,uefa-champions-league-qualifying,uefa-champions-league-qualifying,uefa_champions_league_qualifying,international_cup,-1,,,europa,,https://www.transfermarkt.co.uk/uefa-champions-league-qualifying/startseite/pokalwettbewerb/CLQ
|
| 16 |
+
COL1,liga-betplay-dimayor,liga-betplay-dimayor,first_tier,domestic_league,83,Colombia,COL1,amerika,20,https://www.transfermarkt.co.uk/liga-betplay-dimayor/startseite/wettbewerb/COL1
|
| 17 |
+
COPA,copa-america,copa-america,copa_america,national_team_competition,-1,,,amerika,,https://www.transfermarkt.co.uk/copa-america/startseite/pokalwettbewerb/COPA
|
| 18 |
+
DFB,dfb-pokal,dfb-pokal,domestic_cup,domestic_cup,40,Germany,L1,europa,18,https://www.transfermarkt.co.uk/dfb-pokal/startseite/wettbewerb/DFB
|
| 19 |
+
DFL,franz-beckenbauer-supercup,franz-beckenbauer-supercup,domestic_super_cup,other,40,Germany,L1,europa,18,https://www.transfermarkt.co.uk/franz-beckenbauer-supercup/startseite/wettbewerb/DFL
|
| 20 |
+
DK1,superliga,superliga,first_tier,domestic_league,39,Denmark,DK1,europa,12,https://www.transfermarkt.co.uk/superliga/startseite/wettbewerb/DK1
|
| 21 |
+
DKP,oddset-pokalen,oddset-pokalen,domestic_cup,domestic_cup,39,Denmark,DK1,europa,12,https://www.transfermarkt.co.uk/oddset-pokalen/startseite/wettbewerb/DKP
|
| 22 |
+
ECLQ,uefa-conference-league-qualifiers,uefa-conference-league-qualifiers,uefa_conference_league_qualifiers,other,-1,,,europa,,https://www.transfermarkt.co.uk/uefa-conference-league-qualifiers/startseite/pokalwettbewerb/ECLQ
|
| 23 |
+
EL,uefa-europa-league,uefa-europa-league,uefa_europa_league,other,-1,,,europa,,https://www.transfermarkt.co.uk/uefa-europa-league/startseite/pokalwettbewerb/EL
|
| 24 |
+
ELQ,uefa-europa-league-qualifying,uefa-europa-league-qualifying,uefa_europa_league_qualifying,other,-1,,,europa,,https://www.transfermarkt.co.uk/uefa-europa-league-qualifying/startseite/pokalwettbewerb/ELQ
|
| 25 |
+
ES1,laliga,laliga,first_tier,domestic_league,157,Spain,ES1,europa,20,https://www.transfermarkt.co.uk/laliga/startseite/wettbewerb/ES1
|
| 26 |
+
EURO,uefa-euro,uefa-euro,uefa_euro,national_team_competition,-1,,,europa,,https://www.transfermarkt.co.uk/uefa-euro/startseite/pokalwettbewerb/EURO
|
| 27 |
+
FAC,fa-cup,fa-cup,domestic_cup,domestic_cup,189,England,GB1,europa,20,https://www.transfermarkt.co.uk/fa-cup/startseite/wettbewerb/FAC
|
| 28 |
+
FIWC,world-cup,world-cup,world_cup,national_team_competition,-1,,,fifa,,https://www.transfermarkt.co.uk/world-cup/startseite/pokalwettbewerb/FIWC
|
| 29 |
+
FR1,ligue-1,ligue-1,first_tier,domestic_league,50,France,FR1,europa,18,https://www.transfermarkt.co.uk/ligue-1/startseite/wettbewerb/FR1
|
| 30 |
+
FRCH,trophee-des-champions,trophee-des-champions,domestic_super_cup,other,50,France,FR1,europa,18,https://www.transfermarkt.co.uk/trophee-des-champions/startseite/wettbewerb/FRCH
|
| 31 |
+
GB1,premier-league,premier-league,first_tier,domestic_league,189,England,GB1,europa,20,https://www.transfermarkt.co.uk/premier-league/startseite/wettbewerb/GB1
|
| 32 |
+
GBCS,community-shield,community-shield,domestic_super_cup,other,189,England,GB1,europa,20,https://www.transfermarkt.co.uk/community-shield/startseite/wettbewerb/GBCS
|
| 33 |
+
GR1,super-league-1,super-league-1,first_tier,domestic_league,56,Greece,GR1,europa,14,https://www.transfermarkt.co.uk/super-league-1/startseite/wettbewerb/GR1
|
| 34 |
+
GRP,kypello-elladas,kypello-elladas,domestic_cup,domestic_cup,56,Greece,GR1,europa,14,https://www.transfermarkt.co.uk/kypello-elladas/startseite/wettbewerb/GRP
|
| 35 |
+
IT1,serie-a,serie-a,first_tier,domestic_league,75,Italy,IT1,europa,20,https://www.transfermarkt.co.uk/serie-a/startseite/wettbewerb/IT1
|
| 36 |
+
JAP1,j1-league,j1-league,first_tier,domestic_league,77,Japan,JAP1,asien,20,https://www.transfermarkt.co.uk/j1-league/startseite/wettbewerb/JAP1
|
| 37 |
+
KLUB,fifa-klub-wm,fifa-klub-wm,fifa_club_world_cup,other,-1,,,europa,,https://www.transfermarkt.co.uk/fifa-klub-wm/startseite/pokalwettbewerb/KLUB
|
| 38 |
+
KR1,supersport-hnl,supersport-hnl,first_tier,domestic_league,37,Croatia,KR1,europa,10,https://www.transfermarkt.co.uk/supersport-hnl/startseite/wettbewerb/KR1
|
| 39 |
+
L1,bundesliga,bundesliga,first_tier,domestic_league,40,Germany,L1,europa,18,https://www.transfermarkt.co.uk/bundesliga/startseite/wettbewerb/L1
|
| 40 |
+
MEX1,liga-mx-clausura,liga-mx-clausura,first_tier,domestic_league,110,Mexico,MEX1,amerika,18,https://www.transfermarkt.co.uk/liga-mx-clausura/startseite/wettbewerb/MEX1
|
| 41 |
+
MLS1,major-league-soccer,major-league-soccer,first_tier,domestic_league,184,United States,MLS1,amerika,30,https://www.transfermarkt.co.uk/major-league-soccer/startseite/wettbewerb/MLS1
|
| 42 |
+
NL1,eredivisie,eredivisie,first_tier,domestic_league,122,Netherlands,NL1,europa,18,https://www.transfermarkt.co.uk/eredivisie/startseite/wettbewerb/NL1
|
| 43 |
+
NLP,knvb-beker,knvb-beker,domestic_cup,domestic_cup,122,Netherlands,NL1,europa,18,https://www.transfermarkt.co.uk/knvb-beker/startseite/wettbewerb/NLP
|
| 44 |
+
NLSC,johan-cruijff-schaal,johan-cruijff-schaal,domestic_super_cup,other,122,Netherlands,NL1,europa,18,https://www.transfermarkt.co.uk/johan-cruijff-schaal/startseite/wettbewerb/NLSC
|
| 45 |
+
NO1,eliteserien,eliteserien,first_tier,domestic_league,125,Norway,NO1,europa,16,https://www.transfermarkt.co.uk/eliteserien/startseite/wettbewerb/NO1
|
| 46 |
+
PL1,pko-bp-ekstraklasa,pko-bp-ekstraklasa,first_tier,domestic_league,135,Poland,PL1,europa,18,https://www.transfermarkt.co.uk/pko-bp-ekstraklasa/startseite/wettbewerb/PL1
|
| 47 |
+
PO1,liga-portugal,liga-portugal,first_tier,domestic_league,136,Portugal,PO1,europa,18,https://www.transfermarkt.co.uk/liga-portugal/startseite/wettbewerb/PO1
|
| 48 |
+
POCP,allianz-cup,allianz-cup,domestic_cup,domestic_cup,136,Portugal,PO1,europa,,https://www.transfermarkt.co.uk/allianz-cup/startseite/wettbewerb/POCP
|
| 49 |
+
POSU,supertaca-candido-de-oliveira,supertaca-candido-de-oliveira,domestic_super_cup,other,136,Portugal,PO1,europa,18,https://www.transfermarkt.co.uk/supertaca-candido-de-oliveira/startseite/wettbewerb/POSU
|
| 50 |
+
RO1,superliga,superliga,first_tier,domestic_league,140,Romania,RO1,europa,16,https://www.transfermarkt.co.uk/superliga/startseite/wettbewerb/RO1
|
| 51 |
+
RSK1,k-league-1,k-league-1,first_tier,domestic_league,87,"Korea, South",RSK1,asien,12,https://www.transfermarkt.co.uk/k-league-1/startseite/wettbewerb/RSK1
|
| 52 |
+
RU1,premier-liga,premier-liga,first_tier,domestic_league,141,Russia,RU1,europa,16,https://www.transfermarkt.co.uk/premier-liga/startseite/wettbewerb/RU1
|
| 53 |
+
RUP,russian-cup,russian-cup,domestic_cup,domestic_cup,141,Russia,RU1,europa,16,https://www.transfermarkt.co.uk/russian-cup/startseite/wettbewerb/RUP
|
| 54 |
+
RUSS,russian-super-cup,russian-super-cup,domestic_super_cup,other,141,Russia,RU1,europa,16,https://www.transfermarkt.co.uk/russian-super-cup/startseite/wettbewerb/RUSS
|
| 55 |
+
SA1,saudi-pro-league,saudi-pro-league,first_tier,domestic_league,146,Saudi Arabia,SA1,asien,18,https://www.transfermarkt.co.uk/saudi-pro-league/startseite/wettbewerb/SA1
|
| 56 |
+
SC1,scottish-premiership,scottish-premiership,first_tier,domestic_league,190,Scotland,SC1,europa,12,https://www.transfermarkt.co.uk/scottish-premiership/startseite/wettbewerb/SC1
|
| 57 |
+
SCI,supercoppa-italiana,supercoppa-italiana,domestic_super_cup,other,75,Italy,IT1,europa,20,https://www.transfermarkt.co.uk/supercoppa-italiana/startseite/wettbewerb/SCI
|
| 58 |
+
SE1,allsvenskan,allsvenskan,first_tier,domestic_league,147,Sweden,SE1,europa,16,https://www.transfermarkt.co.uk/allsvenskan/startseite/wettbewerb/SE1
|
| 59 |
+
SER1,super-liga-srbije,super-liga-srbije,first_tier,domestic_league,215,Serbia,SER1,europa,16,https://www.transfermarkt.co.uk/super-liga-srbije/startseite/wettbewerb/SER1
|
| 60 |
+
SFA,scottish-fa-cup,scottish-fa-cup,domestic_cup,domestic_cup,190,Scotland,SC1,europa,12,https://www.transfermarkt.co.uk/scottish-fa-cup/startseite/wettbewerb/SFA
|
| 61 |
+
SUC,supercopa,supercopa,domestic_super_cup,other,157,Spain,ES1,europa,20,https://www.transfermarkt.co.uk/supercopa/startseite/wettbewerb/SUC
|
| 62 |
+
TR1,super-lig,super-lig,first_tier,domestic_league,174,Türkiye,TR1,europa,18,https://www.transfermarkt.co.uk/super-lig/startseite/wettbewerb/TR1
|
| 63 |
+
TS1,chance-liga,chance-liga,first_tier,domestic_league,172,Czech Republic,TS1,europa,16,https://www.transfermarkt.co.uk/chance-liga/startseite/wettbewerb/TS1
|
| 64 |
+
UCOL,uefa-conference-league,uefa-conference-league,uefa_conference_league,other,-1,,,europa,,https://www.transfermarkt.co.uk/uefa-conference-league/startseite/pokalwettbewerb/UCOL
|
| 65 |
+
UKR1,premier-liga,premier-liga,first_tier,domestic_league,177,Ukraine,UKR1,europa,16,https://www.transfermarkt.co.uk/premier-liga/startseite/wettbewerb/UKR1
|
| 66 |
+
UKRP,ukrainian-cup,ukrainian-cup,domestic_cup,domestic_cup,177,Ukraine,UKR1,europa,16,https://www.transfermarkt.co.uk/ukrainian-cup/startseite/wettbewerb/UKRP
|
| 67 |
+
UKRS,ukrainian-super-cup,ukrainian-super-cup,domestic_super_cup,other,177,Ukraine,UKR1,europa,,https://www.transfermarkt.co.uk/ukrainian-super-cup/startseite/wettbewerb/UKRS
|
| 68 |
+
USC,uefa-super-cup,uefa-super-cup,uefa_super_cup,international_cup,-1,,,europa,,https://www.transfermarkt.co.uk/uefa-super-cup/startseite/pokalwettbewerb/USC
|
data/raw/transfermarkt/countries.csv
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
country_id,country_name,country_code,confederation,total_clubs,total_players,average_age,url
|
| 2 |
+
10,Armenia,ARM1,europa,10,265,24.8,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/10
|
| 3 |
+
100,North Macedonia,MAZ1,europa,12,283,25.4,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/100
|
| 4 |
+
103,Malaysia,MYS1,asien,13,399,28.3,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/103
|
| 5 |
+
106,Malta,MT1N,europa,12,299,26.9,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/106
|
| 6 |
+
107,Morocco,MAR1,afrika,16,499,27.2,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/107
|
| 7 |
+
11,Ethiopia,ETP1,afrika,20,652,25.4,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/11
|
| 8 |
+
110,Mexico,MEX1,amerika,18,482,26.9,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/110
|
| 9 |
+
112,Moldova,MO1N,europa,8,215,23.4,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/112
|
| 10 |
+
116,Myanmar,MYA1,asien,12,383,26.8,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/116
|
| 11 |
+
12,Australia,AUS1,asien,12,377,24.8,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/12
|
| 12 |
+
120,New Zealand,NNL1,asien,12,318,23.9,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/120
|
| 13 |
+
121,Nicaragua,CNIC,amerika,34,467,27.5,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/121
|
| 14 |
+
122,Netherlands,NL1,europa,18,497,25.2,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/122
|
| 15 |
+
124,Nigeria,NPFL,afrika,20,920,25.2,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/124
|
| 16 |
+
125,Norway,NO1,europa,16,418,24.9,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/125
|
| 17 |
+
126,Oman,OM1L,asien,14,511,27.8,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/126
|
| 18 |
+
127,Austria,A1,europa,12,343,24.9,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/127
|
| 19 |
+
13,Azerbaijan,AZ1,europa,12,306,27.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/13
|
| 20 |
+
130,Panama,PN1C,amerika,12,288,25.6,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/130
|
| 21 |
+
132,Paraguay,PR1A,amerika,12,376,27.1,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/132
|
| 22 |
+
133,Peru,TDeA,amerika,18,527,27.2,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/133
|
| 23 |
+
134,Philippines,PFL1,asien,11,341,26.8,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/134
|
| 24 |
+
135,Poland,PL1,europa,18,515,25.9,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/135
|
| 25 |
+
136,Portugal,PO1,europa,18,486,25.6,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/136
|
| 26 |
+
137,Qatar,QSL,asien,12,353,28.1,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/137
|
| 27 |
+
140,Romania,RO1,europa,16,476,26.6,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/140
|
| 28 |
+
141,Russia,RU1,europa,16,450,25.9,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/141
|
| 29 |
+
144,San Marino,SMR1,europa,16,387,26.2,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/144
|
| 30 |
+
146,Saudi Arabia,SA1,asien,18,503,27.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/146
|
| 31 |
+
147,Sweden,SE1,europa,16,436,24.7,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/147
|
| 32 |
+
148,Switzerland,C1,europa,12,338,25.1,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/148
|
| 33 |
+
149,Senegal,SEN1,afrika,16,554,22.8,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/149
|
| 34 |
+
153,Singapore,SIN1,asien,8,196,26.4,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/153
|
| 35 |
+
154,Slovakia,SLO1,europa,12,336,25.6,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/154
|
| 36 |
+
155,Slovenia,SL1,europa,10,243,24.7,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/155
|
| 37 |
+
157,Spain,ES1,europa,20,518,27.3,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/157
|
| 38 |
+
159,South Africa,SFA1,afrika,16,573,27.6,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/159
|
| 39 |
+
16,Bangladesh,BGD1,asien,10,338,25.9,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/16
|
| 40 |
+
164,Chinese Taipei,TFPL,asien,8,230,25.5,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/164
|
| 41 |
+
165,Tajikistan,TAD1,asien,12,284,25.3,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/165
|
| 42 |
+
167,Thailand,THA1,asien,16,489,28.2,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/167
|
| 43 |
+
172,Czech Republic,TS1,europa,16,471,25.8,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/172
|
| 44 |
+
173,Tunisia,TUN1,afrika,16,564,24.9,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/173
|
| 45 |
+
174,Türkiye,TR1,europa,18,512,26.5,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/174
|
| 46 |
+
176,Uganda,UGL1,afrika,16,501,26.8,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/176
|
| 47 |
+
177,Ukraine,UKR1,europa,16,438,25.3,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/177
|
| 48 |
+
178,Hungary,UNG1,europa,12,359,26.1,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/178
|
| 49 |
+
179,Uruguay,URU1,amerika,16,475,25.6,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/179
|
| 50 |
+
18,Belarus,WER1,europa,16,405,25.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/18
|
| 51 |
+
180,Uzbekistan,UZ1,asien,16,425,26.2,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/180
|
| 52 |
+
182,Venezuela,VZ1A,amerika,14,424,25.9,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/182
|
| 53 |
+
183,United Arab Emirates,UAE1,asien,14,425,26.7,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/183
|
| 54 |
+
184,United States,MLS1,amerika,30,851,25.5,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/184
|
| 55 |
+
185,Vietnam,VIE1,asien,14,449,26.6,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/185
|
| 56 |
+
188,Cyprus,ZYP1,europa,14,407,26.9,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/188
|
| 57 |
+
189,England,GB1,europa,20,527,26.4,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/189
|
| 58 |
+
19,Belgium,BE1,europa,16,452,24.5,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/19
|
| 59 |
+
190,Scotland,SC1,europa,12,326,26.7,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/190
|
| 60 |
+
191,Wales,WAL2,europa,16,404,25.9,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/191
|
| 61 |
+
192,Northern Ireland,NIR1,europa,12,311,26.2,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/192
|
| 62 |
+
2,Egypt,EGY1,afrika,21,707,27.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/2
|
| 63 |
+
208,Faroe Islands,FAR2,europa,10,287,25.1,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/208
|
| 64 |
+
215,Serbia,SER1,europa,16,476,25.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/215
|
| 65 |
+
216,Montenegro,MNE1,europa,10,247,26.3,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/216
|
| 66 |
+
218,Hongkong,HGKG,asien,10,320,25.7,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/218
|
| 67 |
+
228,Puerto Rico,PRA1,amerika,10,363,23.7,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/228
|
| 68 |
+
23,Bolivia,BO1A,amerika,16,485,26.9,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/23
|
| 69 |
+
24,Bosnia-Herzegovina,BOS1,europa,10,294,26.2,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/24
|
| 70 |
+
244,Kosovo,KO1,europa,10,275,26.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/244
|
| 71 |
+
26,Brazil,BRA1,amerika,20,668,27.1,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/26
|
| 72 |
+
266,Gibraltar,GI1,europa,12,331,26.5,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/266
|
| 73 |
+
28,Bulgaria,BU1,europa,16,403,26.1,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/28
|
| 74 |
+
3,Albania,ALB1,europa,10,275,25.5,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/3
|
| 75 |
+
33,Chile,CLPD,amerika,16,417,27.1,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/33
|
| 76 |
+
34,China,CSL,asien,16,511,26.7,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/34
|
| 77 |
+
35,Comoros,COM1,afrika,30,873,26.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/35
|
| 78 |
+
36,Costa Rica,CRPD,amerika,10,271,27.6,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/36
|
| 79 |
+
37,Croatia,KR1,europa,10,297,25.5,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/37
|
| 80 |
+
39,Denmark,DK1,europa,12,321,25.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/39
|
| 81 |
+
4,Algeria,ALG1,afrika,16,420,26.4,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/4
|
| 82 |
+
40,Germany,L1,europa,18,517,25.8,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/40
|
| 83 |
+
43,Dominican Republic,DO1P,amerika,6,139,26.5,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/43
|
| 84 |
+
44,Ecuador,EC1N,amerika,16,441,27.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/44
|
| 85 |
+
45,El Salvador,SL1A,amerika,12,319,27.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/45
|
| 86 |
+
47,Estonia,EST2,europa,10,255,21.5,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/47
|
| 87 |
+
48,Fiji,FIJ1,asien,10,384,26.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/48
|
| 88 |
+
49,Finland,FI1,europa,12,299,23.8,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/49
|
| 89 |
+
5,Andorra,AND2,europa,8,280,28.1,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/5
|
| 90 |
+
50,France,FR1,europa,18,478,25.6,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/50
|
| 91 |
+
53,Georgia,GE1N,europa,10,250,24.8,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/53
|
| 92 |
+
54,Ghana,GHPL,afrika,18,604,24.3,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/54
|
| 93 |
+
56,Greece,GR1,europa,14,436,27.1,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/56
|
| 94 |
+
58,Guatemala,GU1A,amerika,12,322,28.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/58
|
| 95 |
+
66,Honduras,HO1A,amerika,11,326,27.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/66
|
| 96 |
+
67,India,IND1,asien,14,395,26.2,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/67
|
| 97 |
+
68,Indonesia,IN1L,asien,18,581,27.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/68
|
| 98 |
+
70,Iraq,IRQ1,asien,20,598,28.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/70
|
| 99 |
+
71,Iran,IRN1,asien,16,491,26.5,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/71
|
| 100 |
+
72,Ireland,IR1,europa,10,309,24.3,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/72
|
| 101 |
+
73,Iceland,IS1,europa,12,297,25.3,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/73
|
| 102 |
+
74,Israel,ISR1,europa,14,380,26.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/74
|
| 103 |
+
75,Italy,IT1,europa,20,534,26.6,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/75
|
| 104 |
+
76,Jamaica,JPL1,amerika,14,569,24.4,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/76
|
| 105 |
+
77,Japan,JAP1,asien,20,694,26.8,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/77
|
| 106 |
+
78,Jordan,JO1L,asien,10,299,26.2,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/78
|
| 107 |
+
79,Cambodia,KHM1,asien,11,327,25.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/79
|
| 108 |
+
80,Canada,CDN1,amerika,8,172,25.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/80
|
| 109 |
+
81,Kazakhstan,KAS1,europa,16,397,26.5,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/81
|
| 110 |
+
83,Colombia,COLP,amerika,20,529,27.6,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/83
|
| 111 |
+
87,"Korea, South",RSK1,asien,12,425,26.2,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/87
|
| 112 |
+
9,Argentina,ARG1,amerika,30,914,26.8,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/9
|
| 113 |
+
90,Kyrgyzstan,KG1L,asien,16,423,25.1,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/90
|
| 114 |
+
91,Laos,LAO1,asien,10,281,23.7,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/91
|
| 115 |
+
92,Latvia,LET1,europa,10,268,23.3,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/92
|
| 116 |
+
94,Lebanon,LIB1,asien,12,327,26.0,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/94
|
| 117 |
+
96,Libya,LPL,afrika,36,1,27.1,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/96
|
| 118 |
+
98,Lithuania,LI1,europa,10,254,25.2,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/98
|
| 119 |
+
99,Luxembourg,LUX1,europa,16,439,25.6,https://www.transfermarkt.co.uk/wettbewerbe/national/wettbewerbe/99
|
data/raw/transfermarkt/game_events.csv
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a902f2873292ed9fa08dc2fc098c1b051bfb72e6b10299759df483aa1c15e9b8
|
| 3 |
+
size 152909307
|
data/raw/transfermarkt/game_lineups.csv
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:23bd337a6304ca928e0be22d4d6548c56e21d8238b1b0b55191b590f4ceab794
|
| 3 |
+
size 337998937
|
data/raw/transfermarkt/games.csv
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:4c5768585014e4df838bdd8ba67db12204d31dc5958ccf27e90f190ed9955e8f
|
| 3 |
+
size 25699223
|
data/raw/transfermarkt/national_teams.csv
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
national_team_id,name,team_code,country_id,country_name,country_code,confederation,team_image_url,squad_size,average_age,foreigners_number,foreigners_percentage,total_market_value,coach_name,fifa_ranking,last_season,url
|
| 2 |
+
10521,San Marino,san-marino,144,San Marino,SMR1,UEFA,https://tmssl.akamaized.net//images/flagge/head/144.png?lm=1520611569,24,24.6,19,79.2,935000,,210,2025,https://www.transfermarkt.co.uk/san-marino/startseite/verein/10521
|
| 3 |
+
10533,Andorra,andorra,5,Andorra,AND2,UEFA,https://tmssl.akamaized.net//images/flagge/head/5.png?lm=1520611569,28,28.4,16,57.1,3520000,,172,2025,https://www.transfermarkt.co.uk/andorra/startseite/verein/10533
|
| 4 |
+
11953,Montenegro,montenegro,216,Montenegro,MNE1,UEFA,https://tmssl.akamaized.net//images/flagge/head/216.png?lm=1520611569,24,26.4,23,95.8,58130001,,82,2025,https://www.transfermarkt.co.uk/montenegro/startseite/verein/11953
|
| 5 |
+
13342,Guatemala,guatemala,58,Guatemala,GU1A,CONCACAF,https://tmssl.akamaized.net//images/flagge/head/58.png?lm=1520611569,21,25.1,6,28.6,5380000,,94,2025,https://www.transfermarkt.co.uk/guatemala/startseite/verein/13342
|
| 6 |
+
13497,Uganda,uganda,176,Uganda,UGL1,CAF,https://tmssl.akamaized.net//images/flagge/head/176.png?lm=1520611569,28,27.9,23,82.1,8630000,,88,2025,https://www.transfermarkt.co.uk/uganda/startseite/verein/13497
|
| 7 |
+
13941,Ethiopia,ethiopia,11,Ethiopia,ETP1,CAF,https://tmssl.akamaized.net//images/flagge/head/11.png?lm=1520611569,23,27.4,2,8.7,2780000,,147,2025,https://www.transfermarkt.co.uk/ethiopia/startseite/verein/13941
|
| 8 |
+
13951,El Salvador,el-salvador,45,El Salvador,SL1A,CONCACAF,https://tmssl.akamaized.net//images/flagge/head/45.png?lm=1520611569,22,25.4,8,36.4,8950000,,99,2025,https://www.transfermarkt.co.uk/el-salvador/startseite/verein/13951
|
| 9 |
+
13955,Fiji,fiji,48,Fiji,FIJ1,OFC,https://tmssl.akamaized.net//images/flagge/head/48.png?lm=1520611569,26,28.1,4,15.4,2450000,,155,2025,https://www.transfermarkt.co.uk/fiji/startseite/verein/13955
|
| 10 |
+
13957,India,india,67,India,IND1,AFC,https://tmssl.akamaized.net//images/flagge/head/67.png?lm=1520611569,23,25.9,0,,4280000,,141,2025,https://www.transfermarkt.co.uk/india/startseite/verein/13957
|
| 11 |
+
13958,Indonesia,indonesia,68,Indonesia,IN1L,AFC,https://tmssl.akamaized.net//images/flagge/head/68.png?lm=1520611569,41,25.8,17,41.5,37799999,,122,2025,https://www.transfermarkt.co.uk/indonesia/startseite/verein/13958
|
| 12 |
+
13975,Tajikistan,tajikistan,165,Tajikistan,TAD1,AFC,https://tmssl.akamaized.net//images/flagge/head/165.png?lm=1520611569,24,26.1,10,41.7,7780000,,100,2025,https://www.transfermarkt.co.uk/tajikistan/startseite/verein/13975
|
| 13 |
+
14162,Qatar,qatar,137,Qatar,QSL,AFC,https://tmssl.akamaized.net//images/flagge/head/137.png?lm=1520611569,23,28.0,1,4.3,18000000,,56,2025,https://www.transfermarkt.co.uk/qatar/startseite/verein/14162
|
| 14 |
+
14165,Oman,oman,126,Oman,OM1L,AFC,https://tmssl.akamaized.net//images/flagge/head/126.png?lm=1520611569,22,28.4,3,13.6,6100000,,78,2025,https://www.transfermarkt.co.uk/oman/startseite/verein/14165
|
| 15 |
+
15033,Bangladesh,bangladesh,16,Bangladesh,BGD1,AFC,https://tmssl.akamaized.net//images/flagge/head/16.png?lm=1520611569,29,25.7,5,17.2,8510000,,180,2025,https://www.transfermarkt.co.uk/bangladesh/startseite/verein/15033
|
| 16 |
+
15232,Dominican Republic,dominican-republic,43,Dominican Republic,DO1P,CONCACAF,https://tmssl.akamaized.net//images/flagge/head/43.png?lm=1520611569,23,24.6,20,87.0,18850000,,142,2025,https://www.transfermarkt.co.uk/dominican-republic/startseite/verein/15232
|
| 17 |
+
15234,Philippines,philippines,134,Philippines,PFL1,AFC,https://tmssl.akamaized.net//images/flagge/head/134.png?lm=1520611569,23,27.7,21,91.3,6180000,,136,2025,https://www.transfermarkt.co.uk/philippines/startseite/verein/15234
|
| 18 |
+
15351,Nicaragua,nicaragua,121,Nicaragua,CNIC,CONCACAF,https://tmssl.akamaized.net//images/flagge/head/121.png?lm=1520611569,25,28.6,8,32.0,3100000,,131,2025,https://www.transfermarkt.co.uk/nicaragua/startseite/verein/15351
|
| 19 |
+
15357,Singapore,singapore,153,Singapore,SIN1,AFC,https://tmssl.akamaized.net//images/flagge/head/153.png?lm=1520611569,26,28.0,8,30.8,3880000,,148,2025,https://www.transfermarkt.co.uk/singapore/startseite/verein/15357
|
| 20 |
+
15363,Chinese Taipei,chinese-taipei,164,Chinese Taipei,TFPL,AFC,https://tmssl.akamaized.net//images/flagge/head/164.png?lm=1679300082,28,26.6,9,32.1,2220000,,174,2025,https://www.transfermarkt.co.uk/chinese-taipei/startseite/verein/15363
|
| 21 |
+
15737,Jordan,jordan,78,Jordan,JO1L,AFC,https://tmssl.akamaized.net//images/flagge/head/78.png?lm=1520611569,23,28.7,10,43.5,9350000,,64,2025,https://www.transfermarkt.co.uk/jordan/startseite/verein/15737
|
| 22 |
+
15738,Malaysia,malaysia,103,Malaysia,MYS1,AFC,https://tmssl.akamaized.net//images/flagge/head/103.png?lm=1520611569,28,28.4,4,14.3,7150000,,121,2025,https://www.transfermarkt.co.uk/malaysia/startseite/verein/15738
|
| 23 |
+
15977,Hong Kong,hong-kong,218,Hongkong,HGKG,AFC,https://tmssl.akamaized.net//images/flagge/head/218.png?lm=1520611569,23,28.3,10,43.5,3880000,,153,2025,https://www.transfermarkt.co.uk/hong-kong/startseite/verein/15977
|
| 24 |
+
16038,Cambodia,cambodia,79,Cambodia,KHM1,AFC,https://tmssl.akamaized.net//images/flagge/head/79.png?lm=1520611569,23,25.5,1,4.3,2380000,,179,2025,https://www.transfermarkt.co.uk/cambodia/startseite/verein/16038
|
| 25 |
+
16423,Myanmar,myanmar,116,Myanmar,MYA1,AFC,https://tmssl.akamaized.net//images/flagge/head/116.png?lm=1520611569,23,26.9,7,30.4,3150000,,163,2025,https://www.transfermarkt.co.uk/myanmar/startseite/verein/16423
|
| 26 |
+
16430,Comoros,comoros,35,Comoros,COM1,CAF,https://tmssl.akamaized.net//images/flagge/head/35.png?lm=1520611569,25,26.9,25,100.0,20200001,,106,2025,https://www.transfermarkt.co.uk/comoros/startseite/verein/16430
|
| 27 |
+
16431,Laos,laos,91,Laos,LAO1,,https://tmssl.akamaized.net//images/flagge/head/91.png?lm=1520611569,24,22.7,4,16.7,1560000,,190,2025,https://www.transfermarkt.co.uk/laos/startseite/verein/16431
|
| 28 |
+
17759,Puerto Rico,puerto-rico,228,Puerto Rico,PRA1,CONCACAF,https://tmssl.akamaized.net//images/flagge/head/228.png?lm=1520611569,23,23.1,20,87.0,1200000,,156,2025,https://www.transfermarkt.co.uk/puerto-rico/startseite/verein/17759
|
| 29 |
+
3262,Germany,germany,40,Germany,L1,UEFA,https://tmssl.akamaized.net//images/flagge/head/40.png?lm=1520612525,26,27.4,9,34.6,849500000,,10,2025,https://www.transfermarkt.co.uk/germany/startseite/verein/3262
|
| 30 |
+
3299,England,england,189,England,GB1,UEFA,https://tmssl.akamaized.net//images/flagge/head/189.png?lm=1520611569,25,26.9,4,16.0,,,4,2025,https://www.transfermarkt.co.uk/england/startseite/verein/3299
|
| 31 |
+
3300,Portugal,portugal,136,Portugal,PO1,UEFA,https://tmssl.akamaized.net//images/flagge/head/136.png?lm=1520611569,23,27.3,17,73.9,838500000,,6,2025,https://www.transfermarkt.co.uk/portugal/startseite/verein/3300
|
| 32 |
+
3375,Spain,spain,157,Spain,ES1,UEFA,https://tmssl.akamaized.net//images/flagge/head/157.png?lm=1520611569,27,27.4,10,37.0,,,1,2025,https://www.transfermarkt.co.uk/spain/startseite/verein/3375
|
| 33 |
+
3376,Italy,italy,75,Italy,IT1,UEFA,https://tmssl.akamaized.net//images/flagge/head/75.png?lm=1520611569,26,27.4,5,19.2,825000000,,13,2025,https://www.transfermarkt.co.uk/italy/startseite/verein/3376
|
| 34 |
+
3377,France,france,50,France,FR1,UEFA,https://tmssl.akamaized.net//images/flagge/head/50.png?lm=1520611569,26,26.7,20,76.9,,,3,2025,https://www.transfermarkt.co.uk/france/startseite/verein/3377
|
| 35 |
+
3378,Greece,greece,56,Greece,GR1,UEFA,https://tmssl.akamaized.net//images/flagge/head/56.png?lm=1520611569,25,26.2,15,60.0,282899994,,46,2025,https://www.transfermarkt.co.uk/greece/startseite/verein/3378
|
| 36 |
+
3379,Netherlands,netherlands,122,Netherlands,NL1,UEFA,https://tmssl.akamaized.net//images/flagge/head/122.png?lm=1520611569,22,26.8,20,90.9,797000000,,7,2025,https://www.transfermarkt.co.uk/netherlands/startseite/verein/3379
|
| 37 |
+
3380,Scotland,scotland,190,Scotland,SC1,UEFA,https://tmssl.akamaized.net//images/flagge/head/190.png?lm=1520611569,26,28.8,17,65.4,211000000,,38,2025,https://www.transfermarkt.co.uk/scotland/startseite/verein/3380
|
| 38 |
+
3381,Turkiye,turkiye,174,Türkiye,TR1,UEFA,https://tmssl.akamaized.net//images/flagge/head/174.png?lm=1520611569,33,27.1,13,39.4,512700012,,25,2025,https://www.transfermarkt.co.uk/turkiye/startseite/verein/3381
|
| 39 |
+
3382,Belgium,belgium,19,Belgium,BE1,UEFA,https://tmssl.akamaized.net//images/flagge/head/19.png?lm=1520611569,24,27.3,20,83.3,450200012,,9,2025,https://www.transfermarkt.co.uk/belgium/startseite/verein/3382
|
| 40 |
+
3383,Austria,austria,127,Austria,A1,UEFA,https://tmssl.akamaized.net//images/flagge/head/127.png?lm=1520611569,28,28.2,25,89.3,254600006,,24,2025,https://www.transfermarkt.co.uk/austria/startseite/verein/3383
|
| 41 |
+
3384,Switzerland,switzerland,148,Switzerland,C1,UEFA,https://tmssl.akamaized.net//images/flagge/head/148.png?lm=1520611569,26,27.9,23,88.5,308100006,,18,2025,https://www.transfermarkt.co.uk/switzerland/startseite/verein/3384
|
| 42 |
+
3394,Bulgaria,bulgaria,28,Bulgaria,BU1,UEFA,https://tmssl.akamaized.net//images/flagge/head/28.png?lm=1520611569,26,25.4,16,61.5,44099998,,87,2025,https://www.transfermarkt.co.uk/bulgaria/startseite/verein/3394
|
| 43 |
+
3433,Australia,australia,12,Australia,AUS1,AFC,https://tmssl.akamaized.net//images/flagge/head/12.png?lm=1520611569,25,27.1,21,84.0,46029999,,27,2025,https://www.transfermarkt.co.uk/australia/startseite/verein/3433
|
| 44 |
+
3435,Japan,japan,77,Japan,JAP1,AFC,https://tmssl.akamaized.net//images/flagge/head/77.png?lm=1520611569,28,26.4,25,89.3,265500000,,19,2025,https://www.transfermarkt.co.uk/japan/startseite/verein/3435
|
| 45 |
+
3436,Denmark,denmark,39,Denmark,DK1,UEFA,https://tmssl.akamaized.net//images/flagge/head/39.png?lm=1520611569,25,26.3,23,92.0,352000000,,21,2025,https://www.transfermarkt.co.uk/denmark/startseite/verein/3436
|
| 46 |
+
3437,Argentina,argentina,9,Argentina,ARG1,CONMEBOL,https://tmssl.akamaized.net//images/flagge/head/9.png?lm=1520611569,28,28.4,23,82.1,712200012,,2,2025,https://www.transfermarkt.co.uk/argentina/startseite/verein/3437
|
| 47 |
+
3438,Serbia,serbia,215,Serbia,SER1,UEFA,https://tmssl.akamaized.net//images/flagge/head/215.png?lm=1520611569,28,26.8,22,78.6,276299988,,39,2025,https://www.transfermarkt.co.uk/serbia/startseite/verein/3438
|
| 48 |
+
3439,Brazil,brazil,26,Brazil,BRA1,CONMEBOL,https://tmssl.akamaized.net//images/flagge/head/26.png?lm=1520611569,26,27.9,22,84.6,924000000,,5,2025,https://www.transfermarkt.co.uk/brazil/startseite/verein/3439
|
| 49 |
+
3440,Norway,norway,125,Norway,NO1,UEFA,https://tmssl.akamaized.net//images/flagge/head/125.png?lm=1520611569,28,26.2,24,85.7,522900024,,32,2025,https://www.transfermarkt.co.uk/norway/startseite/verein/3440
|
| 50 |
+
3441,Ghana,ghana,54,Ghana,GHPL,CAF,https://tmssl.akamaized.net//images/flagge/head/54.png?lm=1520611569,26,26.9,25,96.2,211779999,,72,2025,https://www.transfermarkt.co.uk/ghana/startseite/verein/3441
|
| 51 |
+
3442,Poland,poland,135,Poland,PL1,UEFA,https://tmssl.akamaized.net//images/flagge/head/135.png?lm=1520611569,25,27.9,18,72.0,163350006,,34,2025,https://www.transfermarkt.co.uk/poland/startseite/verein/3442
|
| 52 |
+
3443,Finland,finland,49,Finland,FI1,UEFA,https://tmssl.akamaized.net//images/flagge/head/49.png?lm=1520611569,24,26.0,24,100.0,51500000,,75,2025,https://www.transfermarkt.co.uk/finland/startseite/verein/3443
|
| 53 |
+
3444,Nigeria,nigeria,124,Nigeria,NPFL,CAF,https://tmssl.akamaized.net//images/flagge/head/124.png?lm=1520611569,23,27.6,23,100.0,229580002,,26,2025,https://www.transfermarkt.co.uk/nigeria/startseite/verein/3444
|
| 54 |
+
3445,Czech Republic,czech-republic,172,Czech Republic,TS1,UEFA,https://tmssl.akamaized.net//images/flagge/head/172.png?lm=1520611569,25,28.0,11,44.0,171500000,,43,2025,https://www.transfermarkt.co.uk/czech-republic/startseite/verein/3445
|
| 55 |
+
3446,Bosnia-Herzegovina,bosnia-herzegovina,24,Bosnia-Herzegovina,BOS1,UEFA,https://tmssl.akamaized.net//images/flagge/head/24.png?lm=1569523290,25,26.9,25,100.0,117800003,,71,2025,https://www.transfermarkt.co.uk/bosnia-herzegovina/startseite/verein/3446
|
| 56 |
+
3447,Romania,romania,140,Romania,RO1,UEFA,https://tmssl.akamaized.net//images/flagge/head/140.png?lm=1520611569,28,27.5,16,57.1,120099998,,49,2025,https://www.transfermarkt.co.uk/romania/startseite/verein/3447
|
| 57 |
+
3448,Russia,russia,141,Russia,RU1,UEFA,https://tmssl.akamaized.net//images/flagge/head/141.png?lm=1520611569,40,26.0,4,10.0,270750000,,36,2025,https://www.transfermarkt.co.uk/russia/startseite/verein/3448
|
| 58 |
+
3449,Uruguay,uruguay,179,Uruguay,URU1,CONMEBOL,https://tmssl.akamaized.net//images/flagge/head/179.png?lm=1520611569,36,26.2,32,88.9,407329987,,17,2025,https://www.transfermarkt.co.uk/uruguay/startseite/verein/3449
|
| 59 |
+
3450,Belarus,belarus,18,Belarus,WER1,UEFA,https://tmssl.akamaized.net//images/flagge/head/18.png?lm=1520611569,24,26.3,12,50.0,15100000,,98,2025,https://www.transfermarkt.co.uk/belarus/startseite/verein/3450
|
| 60 |
+
3468,Hungary,hungary,178,Hungary,UNG1,UEFA,https://tmssl.akamaized.net//images/flagge/head/178.png?lm=1521635893,24,26.6,17,70.8,204000000,,41,2025,https://www.transfermarkt.co.uk/hungary/startseite/verein/3468
|
| 61 |
+
3499,Senegal,senegal,149,Senegal,SEN1,CAF,https://tmssl.akamaized.net//images/flagge/head/149.png?lm=1520611569,31,26.9,31,100.0,476700012,,12,2025,https://www.transfermarkt.co.uk/senegal/startseite/verein/3499
|
| 62 |
+
3503,Slovakia,slovakia,154,Slovakia,SLO1,UEFA,https://tmssl.akamaized.net//images/flagge/head/154.png?lm=1520611569,28,28.7,27,96.4,133850006,,44,2025,https://www.transfermarkt.co.uk/slovakia/startseite/verein/3503
|
| 63 |
+
3504,Venezuela,venezuela,182,Venezuela,VZ1A,CONMEBOL,https://tmssl.akamaized.net//images/flagge/head/182.png?lm=1520611569,36,25.2,31,86.1,71750000,,50,2025,https://www.transfermarkt.co.uk/venezuela/startseite/verein/3504
|
| 64 |
+
3505,United States,united-states,184,United States,MLS1,CONCACAF,https://tmssl.akamaized.net//images/flagge/head/184.png?lm=1520611569,27,26.3,19,70.4,358700012,,15,2025,https://www.transfermarkt.co.uk/united-states/startseite/verein/3505
|
| 65 |
+
3509,Republic of Ireland,republic-of-ireland,72,Ireland,IR1,UEFA,https://tmssl.akamaized.net//images/flagge/head/72.png?lm=1520611569,25,27.2,25,100.0,184149994,,59,2025,https://www.transfermarkt.co.uk/republic-of-ireland/startseite/verein/3509
|
| 66 |
+
3510,Canada,canada,80,Canada,CDN1,CONCACAF,https://tmssl.akamaized.net//images/flagge/head/80.png?lm=1520611569,26,26.4,23,88.5,121080002,,29,2025,https://www.transfermarkt.co.uk/canada/startseite/verein/3510
|
| 67 |
+
3555,Latvia,latvia,92,Latvia,LET1,UEFA,https://tmssl.akamaized.net//images/flagge/head/92.png?lm=1520611569,27,26.7,13,48.1,17950001,,139,2025,https://www.transfermarkt.co.uk/latvia/startseite/verein/3555
|
| 68 |
+
3556,Croatia,croatia,37,Croatia,KR1,UEFA,https://tmssl.akamaized.net//images/flagge/head/37.png?lm=1520611569,26,28.2,24,92.3,255300003,,11,2025,https://www.transfermarkt.co.uk/croatia/startseite/verein/3556
|
| 69 |
+
3557,Sweden,sweden,147,Sweden,SE1,UEFA,https://tmssl.akamaized.net//images/flagge/head/147.png?lm=1520611569,26,26.3,22,84.6,377779999,,42,2025,https://www.transfermarkt.co.uk/sweden/startseite/verein/3557
|
| 70 |
+
3560,Iraq,iraq,70,Iraq,IRQ1,AFC,https://tmssl.akamaized.net//images/flagge/head/70.png?lm=1520611569,28,26.4,15,53.6,18830000,,58,2025,https://www.transfermarkt.co.uk/iraq/startseite/verein/3560
|
| 71 |
+
3561,Albania,albania,3,Albania,ALB1,UEFA,https://tmssl.akamaized.net//images/flagge/head/3.png?lm=1520611569,25,28.2,23,92.0,86349998,,63,2025,https://www.transfermarkt.co.uk/albania/startseite/verein/3561
|
| 72 |
+
3563,Uzbekistan,uzbekistan,180,Uzbekistan,UZ1,AFC,https://tmssl.akamaized.net//images/flagge/head/180.png?lm=1520611569,14,26.3,1,7.1,8500000,,52,2025,https://www.transfermarkt.co.uk/uzbekistan/startseite/verein/3563
|
| 73 |
+
3574,Iceland,iceland,73,Iceland,IS1,UEFA,https://tmssl.akamaized.net//images/flagge/head/73.png?lm=1520611569,22,27.0,21,95.5,79000000,,74,2025,https://www.transfermarkt.co.uk/iceland/startseite/verein/3574
|
| 74 |
+
3575,Morocco,morocco,107,Morocco,MAR1,CAF,https://tmssl.akamaized.net//images/flagge/head/107.png?lm=1520611569,28,25.3,25,89.3,431750000,,8,2025,https://www.transfermarkt.co.uk/morocco/startseite/verein/3575
|
| 75 |
+
3577,Panama,panama,130,Panama,PN1C,CONCACAF,https://tmssl.akamaized.net//images/flagge/head/130.png?lm=1520611569,23,29.5,22,95.7,31200001,,33,2025,https://www.transfermarkt.co.uk/panama/startseite/verein/3577
|
| 76 |
+
3580,Luxembourg,luxembourg,99,Luxembourg,LUX1,UEFA,https://tmssl.akamaized.net//images/flagge/head/99.png?lm=1520611569,24,26.1,24,100.0,33299999,,102,2025,https://www.transfermarkt.co.uk/luxembourg/startseite/verein/3580
|
| 77 |
+
3581,Paraguay,paraguay,132,Paraguay,PR1A,CONMEBOL,https://tmssl.akamaized.net//images/flagge/head/132.png?lm=1520611569,31,28.5,25,80.6,124800003,,40,2025,https://www.transfermarkt.co.uk/paraguay/startseite/verein/3581
|
| 78 |
+
3582,Iran,iran,71,Iran,IRN1,AFC,https://tmssl.akamaized.net//images/flagge/head/71.png?lm=1520611569,28,29.4,7,25.0,34049999,,20,2025,https://www.transfermarkt.co.uk/iran/startseite/verein/3582
|
| 79 |
+
3584,Peru,peru,133,Peru,TDeA,CONMEBOL,https://tmssl.akamaized.net//images/flagge/head/133.png?lm=1520611569,24,26.7,12,50.0,27650000,,53,2025,https://www.transfermarkt.co.uk/peru/startseite/verein/3584
|
| 80 |
+
3586,Lebanon,lebanon,94,Lebanon,LIB1,AFC,https://tmssl.akamaized.net//images/flagge/head/94.png?lm=1520611569,23,28.8,6,26.1,6450000,,109,2025,https://www.transfermarkt.co.uk/lebanon/startseite/verein/3586
|
| 81 |
+
3587,Malta,malta,106,Malta,MT1N,UEFA,https://tmssl.akamaized.net//images/flagge/head/106.png?lm=1520611569,29,27.1,10,34.5,14550000,,161,2025,https://www.transfermarkt.co.uk/malta/startseite/verein/3587
|
| 82 |
+
3588,Slovenia,slovenia,155,Slovenia,SL1,UEFA,https://tmssl.akamaized.net//images/flagge/head/155.png?lm=1520611569,26,26.9,21,80.8,145800003,,57,2025,https://www.transfermarkt.co.uk/slovenia/startseite/verein/3588
|
| 83 |
+
3589,South Korea,south-korea,87,"Korea, South",RSK1,AFC,https://tmssl.akamaized.net//images/flagge/head/87.png?lm=1520611569,26,27.7,20,76.9,125099998,,22,2025,https://www.transfermarkt.co.uk/south-korea/startseite/verein/3589
|
| 84 |
+
3590,Honduras,honduras,66,Honduras,HO1A,CONCACAF,https://tmssl.akamaized.net//images/flagge/head/66.png?lm=1699286249,28,28.2,13,46.4,15650000,,65,2025,https://www.transfermarkt.co.uk/honduras/startseite/verein/3590
|
| 85 |
+
3614,Algeria,algeria,4,Algeria,ALG1,CAF,https://tmssl.akamaized.net//images/flagge/head/4.png?lm=1520611569,27,25.8,25,92.6,236550003,,28,2025,https://www.transfermarkt.co.uk/algeria/startseite/verein/3614
|
| 86 |
+
3668,Cyprus,cyprus,188,Cyprus,ZYP1,UEFA,https://tmssl.akamaized.net//images/flagge/head/188.png?lm=1520611569,26,25.7,7,26.9,19600000,,128,2025,https://www.transfermarkt.co.uk/cyprus/startseite/verein/3668
|
| 87 |
+
3669,Georgia,georgia,53,Georgia,GE1N,UEFA,https://tmssl.akamaized.net//images/flagge/head/53.png?lm=1520611569,24,26.8,22,91.7,194979996,,73,2025,https://www.transfermarkt.co.uk/georgia/startseite/verein/3669
|
| 88 |
+
3670,Tunisia,tunisia,173,Tunisia,TUN1,CAF,https://tmssl.akamaized.net//images/flagge/head/173.png?lm=1520611569,30,25.3,21,70.0,69650002,,47,2025,https://www.transfermarkt.co.uk/tunisia/startseite/verein/3670
|
| 89 |
+
3671,Jamaica,jamaica,76,Jamaica,JPL1,CONCACAF,https://tmssl.akamaized.net//images/flagge/head/76.png?lm=1520611569,28,26.8,26,92.9,48950001,,70,2025,https://www.transfermarkt.co.uk/jamaica/startseite/verein/3671
|
| 90 |
+
3672,Egypt,egypt,2,Egypt,EGY1,CAF,https://tmssl.akamaized.net//images/flagge/head/2.png?lm=1520611569,28,29.1,6,21.4,134250000,,31,2025,https://www.transfermarkt.co.uk/egypt/startseite/verein/3672
|
| 91 |
+
3699,Ukraine,ukraine,177,Ukraine,UKR1,UEFA,https://tmssl.akamaized.net//images/flagge/head/177.png?lm=1520611569,26,26.5,11,42.3,261399994,,30,2025,https://www.transfermarkt.co.uk/ukraine/startseite/verein/3699
|
| 92 |
+
3700,Chile,chile,33,Chile,CLPD,CONMEBOL,https://tmssl.akamaized.net//images/flagge/head/33.png?lm=1520611569,26,25.5,20,76.9,84099998,,55,2025,https://www.transfermarkt.co.uk/chile/startseite/verein/3700
|
| 93 |
+
37574,Gibraltar,gibraltar,266,Gibraltar,GI1,UEFA,https://tmssl.akamaized.net//images/flagge/head/266.png?lm=1520611569,23,23.5,9,39.1,1200000,,202,2025,https://www.transfermarkt.co.uk/gibraltar/startseite/verein/37574
|
| 94 |
+
3806,South Africa,south-africa,159,South Africa,SFA1,CAF,https://tmssl.akamaized.net//images/flagge/head/159.png?lm=1520611569,28,26.5,9,32.1,46349998,,60,2025,https://www.transfermarkt.co.uk/south-africa/startseite/verein/3806
|
| 95 |
+
3807,Saudi Arabia,saudi-arabia,146,Saudi Arabia,SA1,AFC,https://tmssl.akamaized.net//images/flagge/head/146.png?lm=1520611569,25,27.4,1,4.0,29049999,,61,2025,https://www.transfermarkt.co.uk/saudi-arabia/startseite/verein/3807
|
| 96 |
+
3816,Colombia,colombia,83,Colombia,COLP,CONMEBOL,https://tmssl.akamaized.net//images/flagge/head/83.png?lm=1520611569,26,29.6,25,96.2,301000000,,14,2025,https://www.transfermarkt.co.uk/colombia/startseite/verein/3816
|
| 97 |
+
3851,Lithuania,lithuania,98,Lithuania,LI1,UEFA,https://tmssl.akamaized.net//images/flagge/head/98.png?lm=1520611569,25,28.3,16,64.0,18230000,,146,2025,https://www.transfermarkt.co.uk/lithuania/startseite/verein/3851
|
| 98 |
+
3864,Wales,wales,191,Wales,WAL2,UEFA,https://tmssl.akamaized.net//images/flagge/head/191.png?lm=1520611569,26,26.8,18,69.2,211149994,,35,2025,https://www.transfermarkt.co.uk/wales/startseite/verein/3864
|
| 99 |
+
3956,Kyrgyzstan,kyrgyzstan,90,Kyrgyzstan,KG1L,AFC,https://tmssl.akamaized.net//images/flagge/head/90.png?lm=1520611569,22,27.4,3,13.6,5830000,,103,2025,https://www.transfermarkt.co.uk/kyrgyzstan/startseite/verein/3956
|
| 100 |
+
5147,United Arab Emirates,united-arab-emirates,183,United Arab Emirates,UAE1,AFC,https://tmssl.akamaized.net//images/flagge/head/183.png?lm=1520611569,23,27.3,0,,39880001,,68,2025,https://www.transfermarkt.co.uk/united-arab-emirates/startseite/verein/5147
|
| 101 |
+
5148,North Macedonia,north-macedonia,100,North Macedonia,MAZ1,UEFA,https://tmssl.akamaized.net//images/flagge/head/100.png?lm=1520611569,28,28.8,23,82.1,39130001,,66,2025,https://www.transfermarkt.co.uk/north-macedonia/startseite/verein/5148
|
| 102 |
+
5233,Bolivia,bolivia,23,Bolivia,BO1A,CONMEBOL,https://tmssl.akamaized.net//images/flagge/head/23.png?lm=1520611569,32,23.9,16,50.0,18799999,,76,2025,https://www.transfermarkt.co.uk/bolivia/startseite/verein/5233
|
| 103 |
+
53982,Kosovo,kosovo,244,Kosovo,KO1,UEFA,https://tmssl.akamaized.net//images/flagge/head/244.png?lm=1520611569,28,27.4,27,96.4,143179993,,79,2025,https://www.transfermarkt.co.uk/kosovo/startseite/verein/53982
|
| 104 |
+
5547,Israel,israel,74,Israel,ISR1,UEFA,https://tmssl.akamaized.net//images/flagge/head/74.png?lm=1520611569,24,26.4,12,50.0,85900002,,77,2025,https://www.transfermarkt.co.uk/israel/startseite/verein/5547
|
| 105 |
+
5598,China,china,34,China,CSL,AFC,https://tmssl.akamaized.net//images/flagge/head/34.png?lm=1520611569,26,29.4,0,,10930000,,93,2025,https://www.transfermarkt.co.uk/china/startseite/verein/5598
|
| 106 |
+
5674,Northern Ireland,northern-ireland,192,Northern Ireland,NIR1,UEFA,https://tmssl.akamaized.net//images/flagge/head/192.png?lm=1520611569,25,25.7,25,100.0,95680000,,69,2025,https://www.transfermarkt.co.uk/northern-ireland/startseite/verein/5674
|
| 107 |
+
5676,Thailand,thailand,167,Thailand,THA1,AFC,https://tmssl.akamaized.net//images/flagge/head/167.png?lm=1520611569,23,28.8,3,13.0,8150000,,96,2025,https://www.transfermarkt.co.uk/thailand/startseite/verein/5676
|
| 108 |
+
5750,Ecuador,ecuador,44,Ecuador,EC1N,CONMEBOL,https://tmssl.akamaized.net//images/flagge/head/44.png?lm=1520611569,28,25.4,26,92.9,366079987,,23,2025,https://www.transfermarkt.co.uk/ecuador/startseite/verein/5750
|
| 109 |
+
6090,Moldova,moldova,112,Moldova,MO1N,UEFA,https://tmssl.akamaized.net//images/flagge/head/112.png?lm=1520611569,26,26.4,18,69.2,14400000,,158,2025,https://www.transfermarkt.co.uk/moldova/startseite/verein/6090
|
| 110 |
+
6133,Estonia,estonia,47,Estonia,EST2,UEFA,https://tmssl.akamaized.net//images/flagge/head/47.png?lm=1520611569,26,25.9,19,73.1,15680000,,129,2025,https://www.transfermarkt.co.uk/estonia/startseite/verein/6133
|
| 111 |
+
6219,Armenia,armenia,10,Armenia,ARM1,UEFA,https://tmssl.akamaized.net//images/flagge/head/10.png?lm=1520611569,27,24.7,10,37.0,39630001,,105,2025,https://www.transfermarkt.co.uk/armenia/startseite/verein/6219
|
| 112 |
+
6303,Mexico,mexico,110,Mexico,MEX1,CONCACAF,https://tmssl.akamaized.net//images/flagge/head/110.png?lm=1520611569,21,26.1,0,,101800003,,16,2025,https://www.transfermarkt.co.uk/mexico/startseite/verein/6303
|
| 113 |
+
6602,Libya,libya,96,Libya,LPL,CAF,https://tmssl.akamaized.net//images/flagge/head/96.png?lm=1520611569,25,26.8,4,16.0,12550000,,112,2025,https://www.transfermarkt.co.uk/libya/startseite/verein/6602
|
| 114 |
+
8497,Costa Rica,costa-rica,36,Costa Rica,CRPD,CONCACAF,https://tmssl.akamaized.net//images/flagge/head/36.png?lm=1520611569,26,27.9,13,50.0,40130001,,51,2025,https://www.transfermarkt.co.uk/costa-rica/startseite/verein/8497
|
| 115 |
+
8605,Azerbaijan,azerbaijan,13,Azerbaijan,AZ1,UEFA,https://tmssl.akamaized.net//images/flagge/head/13.png?lm=1520611569,25,26.7,6,24.0,20549999,,127,2025,https://www.transfermarkt.co.uk/azerbaijan/startseite/verein/8605
|
| 116 |
+
8778,Vietnam,vietnam,185,Vietnam,VIE1,AFC,https://tmssl.akamaized.net//images/flagge/head/185.png?lm=1520611569,23,27.9,0,,6380000,,108,2025,https://www.transfermarkt.co.uk/vietnam/startseite/verein/8778
|
| 117 |
+
9110,Kazakhstan,kazakhstan,81,Kazakhstan,KAS1,UEFA,https://tmssl.akamaized.net//images/flagge/head/81.png?lm=1520611569,26,26.4,4,15.4,17250000,,114,2025,https://www.transfermarkt.co.uk/kazakhstan/startseite/verein/9110
|
| 118 |
+
9171,New Zealand,new-zealand,120,New Zealand,NNL1,OFC,https://tmssl.akamaized.net//images/flagge/head/120.png?lm=1520611569,23,27.4,15,65.2,21600000,,85,2025,https://www.transfermarkt.co.uk/new-zealand/startseite/verein/9171
|
| 119 |
+
9173,Faroe Islands,faroe-islands,208,Faroe Islands,FAR2,UEFA,https://tmssl.akamaized.net//images/flagge/head/208.png?lm=1520611569,24,28.2,13,54.2,6530000,,125,2025,https://www.transfermarkt.co.uk/faroe-islands/startseite/verein/9173
|
data/raw/transfermarkt/player_valuations.csv
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d288c65bab9dce490232d83abb5109cb021843cc13e26da00da2fd5f968b4504
|
| 3 |
+
size 30022694
|
data/raw/transfermarkt/players.csv
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2b51fa9df4c635572eb28e0cec0668e378ba9df2ca39da286291d2ada92bc3fc
|
| 3 |
+
size 16726734
|
data/raw/transfermarkt/transfers.csv
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f70d0d8b6ddc7a72495db3bd3c15995fce8d7c8fc949ed3261fad58a86f76506
|
| 3 |
+
size 13341210
|
fairvalue_xgboost.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
requirements.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
streamlit==1.32.0
|
| 2 |
+
xgboost==2.0.3
|
| 3 |
+
shap==0.44.0
|
| 4 |
+
pandas==2.2.0
|
| 5 |
+
numpy==1.26.4
|
| 6 |
+
plotly==5.18.0
|
| 7 |
+
scikit-learn==1.4.0
|
src/data/__init__.py
ADDED
|
File without changes
|
src/data/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (170 Bytes). View file
|
|
|
src/data/__pycache__/kaggle_loader.cpython-311.pyc
ADDED
|
Binary file (5.47 kB). View file
|
|
|
src/data/__pycache__/preprocess.cpython-311.pyc
ADDED
|
Binary file (1.82 kB). View file
|
|
|
src/data/kaggle_loader.py
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import kagglehub
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import os
|
| 4 |
+
import shutil
|
| 5 |
+
|
| 6 |
+
def download_datasets():
|
| 7 |
+
"""
|
| 8 |
+
Downloads the Transfermarkt dataset and an FBref dataset.
|
| 9 |
+
"""
|
| 10 |
+
print("Downloading Transfermarkt dataset...")
|
| 11 |
+
tm_path = kagglehub.dataset_download("davidcariboo/player-scores")
|
| 12 |
+
print(f"Transfermarkt dataset downloaded locally to {tm_path}")
|
| 13 |
+
|
| 14 |
+
print("Downloading FBref dataset...")
|
| 15 |
+
try:
|
| 16 |
+
# Using a popular FBref Kaggle dataset for advanced metrics
|
| 17 |
+
fb_path = kagglehub.dataset_download("vivovinco/20222023-football-player-stats")
|
| 18 |
+
print(f"FBref dataset downloaded locally to {fb_path}")
|
| 19 |
+
except Exception as e:
|
| 20 |
+
print(f"Warning: Could not download FBref dataset: {e}")
|
| 21 |
+
fb_path = None
|
| 22 |
+
|
| 23 |
+
return tm_path, fb_path
|
| 24 |
+
|
| 25 |
+
def load_data(tm_path, fb_path):
|
| 26 |
+
"""
|
| 27 |
+
Loads necessary csv files into pandas DataFrames.
|
| 28 |
+
"""
|
| 29 |
+
# Transfermarkt data
|
| 30 |
+
players_path = os.path.join(tm_path, "players.csv")
|
| 31 |
+
appearances_path = os.path.join(tm_path, "appearances.csv")
|
| 32 |
+
player_valuations_path = os.path.join(tm_path, "player_valuations.csv")
|
| 33 |
+
|
| 34 |
+
players_df = pd.read_csv(players_path)
|
| 35 |
+
appearances_df = pd.read_csv(appearances_path)
|
| 36 |
+
|
| 37 |
+
valuations_df = None
|
| 38 |
+
if os.path.exists(player_valuations_path):
|
| 39 |
+
valuations_df = pd.read_csv(player_valuations_path)
|
| 40 |
+
|
| 41 |
+
# FBref data
|
| 42 |
+
fbref_df = None
|
| 43 |
+
if fb_path and os.path.exists(fb_path):
|
| 44 |
+
for file in os.listdir(fb_path):
|
| 45 |
+
if file.endswith('.csv'):
|
| 46 |
+
# Many FBref datasets use latin1 encoding
|
| 47 |
+
fbref_df = pd.read_csv(os.path.join(fb_path, file), encoding='latin1', low_memory=False)
|
| 48 |
+
break
|
| 49 |
+
|
| 50 |
+
return players_df, appearances_df, valuations_df, fbref_df
|
| 51 |
+
|
| 52 |
+
def get_base_datasets(stage_locally=True):
|
| 53 |
+
"""Downloads and returns all dataframes, optionally staging them locally."""
|
| 54 |
+
tm_path, fb_path = download_datasets()
|
| 55 |
+
|
| 56 |
+
if stage_locally:
|
| 57 |
+
print("Staging datasets into local data/raw directory...")
|
| 58 |
+
# Get absolute path relative to project root
|
| 59 |
+
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
| 60 |
+
tm_raw_dir = os.path.join(project_root, "data", "raw", "transfermarkt")
|
| 61 |
+
fb_raw_dir = os.path.join(project_root, "data", "raw", "fbref")
|
| 62 |
+
|
| 63 |
+
os.makedirs(tm_raw_dir, exist_ok=True)
|
| 64 |
+
os.makedirs(fb_raw_dir, exist_ok=True)
|
| 65 |
+
|
| 66 |
+
for f in os.listdir(tm_path):
|
| 67 |
+
if f.endswith('.csv'):
|
| 68 |
+
shutil.copy(os.path.join(tm_path, f), tm_raw_dir)
|
| 69 |
+
|
| 70 |
+
if fb_path and os.path.exists(fb_path):
|
| 71 |
+
for f in os.listdir(fb_path):
|
| 72 |
+
if f.endswith('.csv'):
|
| 73 |
+
shutil.copy(os.path.join(fb_path, f), fb_raw_dir)
|
| 74 |
+
|
| 75 |
+
print(f"Data staged successfully into {os.path.join(project_root, 'data', 'raw')}.")
|
| 76 |
+
|
| 77 |
+
return load_data(tm_path, fb_path)
|
| 78 |
+
|
| 79 |
+
if __name__ == "__main__":
|
| 80 |
+
players, apps, valuations, fbref = get_base_datasets()
|
| 81 |
+
|
| 82 |
+
print("\n--- Data Loading Summary ---")
|
| 83 |
+
print(f"Loaded {len(players)} Transfermarkt players.")
|
| 84 |
+
print(f"Loaded {len(apps)} match appearances.")
|
| 85 |
+
if valuations is not None:
|
| 86 |
+
print(f"Loaded {len(valuations)} transfer valuations.")
|
| 87 |
+
if fbref is not None:
|
| 88 |
+
print(f"Loaded {len(fbref)} FBref player records with advanced metrics like xG and xA.")
|
src/data/preprocess.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pandas as pd
|
| 2 |
+
import numpy as np
|
| 3 |
+
|
| 4 |
+
# A basic historical inflation index for football transfers
|
| 5 |
+
# Base Year: 2024 (Index = 1.00)
|
| 6 |
+
# (e.g., fees in 2017 are multiplied by 1.50 to equal 2024 purchasing power)
|
| 7 |
+
INFLATION_RATES = {
|
| 8 |
+
2015: 2.10,
|
| 9 |
+
2016: 1.85,
|
| 10 |
+
2017: 1.50, # Pre-Neymar era adjustment
|
| 11 |
+
2018: 1.40,
|
| 12 |
+
2019: 1.35,
|
| 13 |
+
2020: 1.25, # COVID market impact
|
| 14 |
+
2021: 1.20,
|
| 15 |
+
2022: 1.10,
|
| 16 |
+
2023: 1.05,
|
| 17 |
+
2024: 1.00
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
def adjust_for_inflation(df, fee_col='market_value_in_eur', year_col='date'):
|
| 21 |
+
"""
|
| 22 |
+
Adjusts past transfer fees or market values to 2024 equivalent.
|
| 23 |
+
Converts EUR to GBP using an approximated flat rate for the MVP.
|
| 24 |
+
"""
|
| 25 |
+
df = df.copy()
|
| 26 |
+
|
| 27 |
+
# Process dates to extract the year
|
| 28 |
+
if df[year_col].dtype == 'object':
|
| 29 |
+
df['Transfer_Year'] = pd.to_datetime(df[year_col]).dt.year
|
| 30 |
+
else:
|
| 31 |
+
df['Transfer_Year'] = df[year_col]
|
| 32 |
+
|
| 33 |
+
df['Inflation_Multiplier'] = df['Transfer_Year'].map(INFLATION_RATES).fillna(1.0)
|
| 34 |
+
|
| 35 |
+
# Adjust to 2024 values
|
| 36 |
+
df['Adjusted_Fee_EUR'] = df[fee_col] * df['Inflation_Multiplier']
|
| 37 |
+
|
| 38 |
+
# Convert EUR to GBP (approx. 0.85 rate)
|
| 39 |
+
df['Transfer_Fee_2024_GBP'] = df['Adjusted_Fee_EUR'] * 0.85
|
| 40 |
+
|
| 41 |
+
return df
|
| 42 |
+
|
| 43 |
+
def clean_data(df):
|
| 44 |
+
"""
|
| 45 |
+
Handles missing values and basic cleanup.
|
| 46 |
+
"""
|
| 47 |
+
# Future specific cleaning logic goes here
|
| 48 |
+
# Example: Impute missing minutes played with 0
|
| 49 |
+
if 'minutes_played' in df.columns:
|
| 50 |
+
df['minutes_played'] = df['minutes_played'].fillna(0)
|
| 51 |
+
return df
|
src/features/__init__.py
ADDED
|
File without changes
|
src/features/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (174 Bytes). View file
|
|
|
src/features/__pycache__/build_features.cpython-311.pyc
ADDED
|
Binary file (3.07 kB). View file
|
|
|
src/features/build_features.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pandas as pd
|
| 2 |
+
import numpy as np
|
| 3 |
+
|
| 4 |
+
# Mock UEFA Coefficients for League Strength Indexing
|
| 5 |
+
# In a full production environment, this would be dynamically loaded
|
| 6 |
+
LEAGUE_COEFFICIENTS = {
|
| 7 |
+
'Premier League': 1.0,
|
| 8 |
+
'LaLiga': 0.90,
|
| 9 |
+
'Serie A': 0.85,
|
| 10 |
+
'Bundesliga': 0.82,
|
| 11 |
+
'Ligue 1': 0.75,
|
| 12 |
+
'Eredivisie': 0.60,
|
| 13 |
+
'Liga Portugal': 0.55
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
def calculate_risk_score(df, contract_col='Contract_Years_Left', age_col='Age', injury_col='Injury_Days_Total_24m'):
|
| 17 |
+
"""
|
| 18 |
+
Computes binary risk flags based on the project blueprint for "The Busquets Factor".
|
| 19 |
+
"""
|
| 20 |
+
df = df.copy()
|
| 21 |
+
|
| 22 |
+
# 1. Contract Risk: Entering final 12-18 months
|
| 23 |
+
if contract_col in df.columns:
|
| 24 |
+
df['Risk_Contract'] = np.where(df[contract_col] < 1.5, 1, 0)
|
| 25 |
+
else:
|
| 26 |
+
df['Risk_Contract'] = 0
|
| 27 |
+
|
| 28 |
+
# 2. Age Risk: Over 30 years old
|
| 29 |
+
if age_col in df.columns:
|
| 30 |
+
df['Risk_Age'] = np.where(df[age_col] > 30, 1, 0)
|
| 31 |
+
else:
|
| 32 |
+
df['Risk_Age'] = 0
|
| 33 |
+
|
| 34 |
+
# 3. Injury Risk: Missed significant time (e.g., > 60 days)
|
| 35 |
+
if injury_col in df.columns:
|
| 36 |
+
df['Risk_Injury'] = np.where(df[injury_col] > 60, 1, 0)
|
| 37 |
+
else:
|
| 38 |
+
df['Risk_Injury'] = 0
|
| 39 |
+
|
| 40 |
+
# Aggregate Score [0 to 3]
|
| 41 |
+
df['Total_Risk_Score'] = df['Risk_Contract'] + df['Risk_Age'] + df['Risk_Injury']
|
| 42 |
+
|
| 43 |
+
return df
|
| 44 |
+
|
| 45 |
+
def calculate_league_index(df, league_col='Current_League'):
|
| 46 |
+
"""
|
| 47 |
+
Applies the League Strength multiplier based on UEFA coefficients.
|
| 48 |
+
"""
|
| 49 |
+
df = df.copy()
|
| 50 |
+
if league_col in df.columns:
|
| 51 |
+
df['League_Index'] = df[league_col].map(LEAGUE_COEFFICIENTS).fillna(0.4) # Default tier 3
|
| 52 |
+
return df
|
| 53 |
+
|
| 54 |
+
def encode_categorical_features(df, position_col='Position', nationality_tier_col='Nationality_Tier'):
|
| 55 |
+
"""
|
| 56 |
+
Performs One-Hot Encoding for positions and handles Nationality Tiers.
|
| 57 |
+
"""
|
| 58 |
+
df = df.copy()
|
| 59 |
+
if position_col in df.columns:
|
| 60 |
+
# Prevent completely exploding dimensions if many obscure positions exist
|
| 61 |
+
df = pd.get_dummies(df, columns=[position_col], prefix='Pos')
|
| 62 |
+
|
| 63 |
+
if nationality_tier_col in df.columns:
|
| 64 |
+
# e.g., Tier 1 = EU5/SA, Tier 2 = Rest of World
|
| 65 |
+
df[nationality_tier_col] = df[nationality_tier_col].astype(int)
|
| 66 |
+
|
| 67 |
+
return df
|
| 68 |
+
|
| 69 |
+
def build_all_features(df):
|
| 70 |
+
"""
|
| 71 |
+
Orchestrates the feature engineering pipeline.
|
| 72 |
+
"""
|
| 73 |
+
df = calculate_risk_score(df)
|
| 74 |
+
df = calculate_league_index(df)
|
| 75 |
+
df = encode_categorical_features(df)
|
| 76 |
+
return df
|
src/models/__init__.py
ADDED
|
File without changes
|
src/models/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (172 Bytes). View file
|
|
|
src/models/__pycache__/predict_cap.cpython-311.pyc
ADDED
|
Binary file (2.55 kB). View file
|
|
|
src/models/__pycache__/train_xgboost.cpython-311.pyc
ADDED
|
Binary file (4.2 kB). View file
|
|
|
src/models/explain.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import shap
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import numpy as np
|
| 4 |
+
|
| 5 |
+
def generate_shap_explanation(model, user_input_df):
|
| 6 |
+
"""
|
| 7 |
+
Generates SHAP values for a specific player prediction.
|
| 8 |
+
"""
|
| 9 |
+
# Create the tree explainer for XGBoost
|
| 10 |
+
explainer = shap.TreeExplainer(model)
|
| 11 |
+
|
| 12 |
+
# Calculate shap values for the specific prediction
|
| 13 |
+
shap_values = explainer(user_input_df)
|
| 14 |
+
|
| 15 |
+
# Extract structural contributions
|
| 16 |
+
feature_names = user_input_df.columns
|
| 17 |
+
contributions = shap_values.values[0]
|
| 18 |
+
|
| 19 |
+
explanation_df = pd.DataFrame({
|
| 20 |
+
'Feature': feature_names,
|
| 21 |
+
'Value': user_input_df.iloc[0].values,
|
| 22 |
+
'Contribution_to_LogPrice': contributions
|
| 23 |
+
})
|
| 24 |
+
|
| 25 |
+
# Identify top drivers
|
| 26 |
+
explanation_df['Absolute_Impact'] = np.abs(explanation_df['Contribution_to_LogPrice'])
|
| 27 |
+
explanation_df = explanation_df.sort_values(by='Absolute_Impact', ascending=False)
|
| 28 |
+
|
| 29 |
+
return shap_values, explanation_df
|
| 30 |
+
|
| 31 |
+
def make_justification_string(prediction_dict):
|
| 32 |
+
"""
|
| 33 |
+
Formats the FairValue logic human-readably for the pitch/app logic.
|
| 34 |
+
"""
|
| 35 |
+
pv = prediction_dict['predicted_value']
|
| 36 |
+
cap = prediction_dict['hard_cap']
|
| 37 |
+
risk_pct = prediction_dict['risk_percentage'] * 100
|
| 38 |
+
|
| 39 |
+
msg = (f"Our model predicts a baseline market value of £{pv/1e6:.1f}m. "
|
| 40 |
+
f"However, after factoring a {risk_pct:.0f}% risk discount based on "
|
| 41 |
+
f"the player's profile (contract/age/injury), the Risk-Adjusted "
|
| 42 |
+
f"Fair Value drops. We recommend a maximal Hard Cap of £{cap/1e6:.1f}m.")
|
| 43 |
+
return msg
|
src/models/predict_cap.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
import xgboost as xgb
|
| 3 |
+
|
| 4 |
+
class FairValueCapEstimator:
|
| 5 |
+
def __init__(self, model_path="fairvalue_xgboost.json"):
|
| 6 |
+
self.model = xgb.XGBRegressor()
|
| 7 |
+
try:
|
| 8 |
+
self.model.load_model(model_path)
|
| 9 |
+
# Default validation error margin (Confidence Interval) roughly 15%
|
| 10 |
+
self.model_error_margin = 0.15
|
| 11 |
+
self.is_loaded = True
|
| 12 |
+
except:
|
| 13 |
+
print("Warning: Model file not found. Estimations will be unavailable.")
|
| 14 |
+
self.model_error_margin = 0.15
|
| 15 |
+
self.is_loaded = False
|
| 16 |
+
|
| 17 |
+
def predict_fair_value(self, player_features_df):
|
| 18 |
+
"""
|
| 19 |
+
Calculates the Predicted Value (PV) and the computationally strict Hard Cap.
|
| 20 |
+
"""
|
| 21 |
+
if not self.is_loaded:
|
| 22 |
+
return {"error": "Model not loaded."}
|
| 23 |
+
|
| 24 |
+
# 1. Predicted Value (PV) (Reverse the log1p transform)
|
| 25 |
+
log_pv = self.model.predict(player_features_df)
|
| 26 |
+
pv = np.expm1(log_pv)[0]
|
| 27 |
+
|
| 28 |
+
# 2. Confidence Interval (CI) bounds
|
| 29 |
+
conservative_value = pv * (1 - self.model_error_margin)
|
| 30 |
+
optimistic_value = pv * (1 + self.model_error_margin)
|
| 31 |
+
|
| 32 |
+
# 3. Calculate Risk Discount (RD)
|
| 33 |
+
risk_discount_percentage = 0.0
|
| 34 |
+
|
| 35 |
+
# Using feature engineered columns from build_features.py logic
|
| 36 |
+
if 'Risk_Contract' in player_features_df.columns and player_features_df['Risk_Contract'].iloc[0] == 1:
|
| 37 |
+
risk_discount_percentage += 0.20 # 20% discount for expiring contracts
|
| 38 |
+
|
| 39 |
+
if 'Risk_Age' in player_features_df.columns and player_features_df['Risk_Age'].iloc[0] == 1:
|
| 40 |
+
risk_discount_percentage += 0.15 # 15% discount for age curve decay
|
| 41 |
+
|
| 42 |
+
if 'Risk_Injury' in player_features_df.columns and player_features_df['Risk_Injury'].iloc[0] == 1:
|
| 43 |
+
risk_discount_percentage += 0.10 # 10% discount for recurring injuries
|
| 44 |
+
|
| 45 |
+
risk_discount_monetary = conservative_value * risk_discount_percentage
|
| 46 |
+
|
| 47 |
+
# 4. Hard Cap
|
| 48 |
+
hard_cap = conservative_value - risk_discount_monetary
|
| 49 |
+
|
| 50 |
+
return {
|
| 51 |
+
'predicted_value': pv,
|
| 52 |
+
'conservative': conservative_value,
|
| 53 |
+
'optimistic': optimistic_value,
|
| 54 |
+
'risk_discount': risk_discount_monetary,
|
| 55 |
+
'risk_percentage': risk_discount_percentage,
|
| 56 |
+
'hard_cap': hard_cap
|
| 57 |
+
}
|
src/models/train_xgboost.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import xgboost as xgb
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import numpy as np
|
| 4 |
+
from sklearn.model_selection import train_test_split, RandomizedSearchCV
|
| 5 |
+
from sklearn.metrics import mean_absolute_error, mean_squared_error
|
| 6 |
+
|
| 7 |
+
def prepare_data_for_training(df, target_col='Transfer_Fee_2024_GBP'):
|
| 8 |
+
"""
|
| 9 |
+
Separates features and targets, applies log transformation to the target
|
| 10 |
+
so we don't predict negative prices and handle extreme outliers better.
|
| 11 |
+
"""
|
| 12 |
+
# Drop identifying or leaky features
|
| 13 |
+
X = df.drop(columns=[target_col, 'Player_ID', 'Name', 'name', 'name_x', 'name_y',
|
| 14 |
+
'Transfer_Date', 'Adjusted_Fee_EUR', 'Inflation_Multiplier',
|
| 15 |
+
'Transfer_Year', 'player_id'], errors='ignore')
|
| 16 |
+
|
| 17 |
+
# Remove leaky columns derived from the target
|
| 18 |
+
leaky_cols = [c for c in X.columns if 'fee' in c.lower() or ('market_value' in c.lower() and c != 'market_value_in_eur_x')]
|
| 19 |
+
X = X.drop(columns=leaky_cols, errors='ignore')
|
| 20 |
+
|
| 21 |
+
# Train on log of price so errors on cheap players don't swamp the expensive ones
|
| 22 |
+
y = np.log1p(df[target_col])
|
| 23 |
+
return X, y
|
| 24 |
+
|
| 25 |
+
def train_model(X, y):
|
| 26 |
+
"""
|
| 27 |
+
Trains the XGBoost regressor using RandomizedSearchCV for faster, wider coverage.
|
| 28 |
+
"""
|
| 29 |
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
| 30 |
+
|
| 31 |
+
# Base regressor
|
| 32 |
+
xgb_reg = xgb.XGBRegressor(
|
| 33 |
+
objective='reg:squarederror',
|
| 34 |
+
random_state=42,
|
| 35 |
+
tree_method='hist' # Faster training
|
| 36 |
+
)
|
| 37 |
+
|
| 38 |
+
# Expanded randomised search parameter space (much wider than GridSearch)
|
| 39 |
+
param_dist = {
|
| 40 |
+
'n_estimators': [150, 300, 500, 700],
|
| 41 |
+
'learning_rate': [0.01, 0.03, 0.05, 0.1],
|
| 42 |
+
'max_depth': [3, 4, 5, 6],
|
| 43 |
+
'min_child_weight': [1, 3, 5], # Controls overfitting on rare elite transfers
|
| 44 |
+
'subsample': [0.7, 0.8, 1.0], # Row sampling — reduces variance
|
| 45 |
+
'colsample_bytree': [0.7, 0.8, 1.0], # Feature sampling — prevents overfitting
|
| 46 |
+
'gamma': [0, 0.1, 0.3], # Minimum loss reduction — pruning
|
| 47 |
+
'reg_lambda': [0.5, 1.0, 2.0], # L2 Regularisation
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
print("Beginning Hyperparameter Search (RandomizedSearchCV, 40 iterations, 5-fold CV)...")
|
| 51 |
+
search = RandomizedSearchCV(
|
| 52 |
+
xgb_reg,
|
| 53 |
+
param_distributions=param_dist,
|
| 54 |
+
n_iter=40, # Test 40 random combinations (vs 8 before)
|
| 55 |
+
cv=5, # 5-fold cross-validation (vs 3 before)
|
| 56 |
+
scoring='neg_mean_absolute_error',
|
| 57 |
+
n_jobs=-1,
|
| 58 |
+
random_state=42,
|
| 59 |
+
verbose=1
|
| 60 |
+
)
|
| 61 |
+
search.fit(X_train, y_train)
|
| 62 |
+
|
| 63 |
+
best_model = search.best_estimator_
|
| 64 |
+
print(f"\nBest params: {search.best_params_}")
|
| 65 |
+
|
| 66 |
+
# Evaluate on held-out test set — convert back from log scale
|
| 67 |
+
predictions_log = best_model.predict(X_test)
|
| 68 |
+
predictions_real = np.expm1(predictions_log)
|
| 69 |
+
y_test_real = np.expm1(y_test)
|
| 70 |
+
|
| 71 |
+
mae = mean_absolute_error(y_test_real, predictions_real)
|
| 72 |
+
rmse = np.sqrt(mean_squared_error(y_test_real, predictions_real))
|
| 73 |
+
|
| 74 |
+
print(f"\n📊 Model Evaluation:")
|
| 75 |
+
print(f" MAE (Mean Absolute Error): £{mae:>12,.0f}")
|
| 76 |
+
print(f" RMSE (Root Mean Square Error): £{rmse:>12,.0f}")
|
| 77 |
+
|
| 78 |
+
# Save the model
|
| 79 |
+
best_model.save_model("fairvalue_xgboost.json")
|
| 80 |
+
print("Model saved as fairvalue_xgboost.json")
|
| 81 |
+
|
| 82 |
+
return best_model, mae
|