Britzzy commited on
Commit
b899ba7
·
verified ·
1 Parent(s): 8ee7b6b

Upload 35 files

Browse files
Files changed (36) hide show
  1. .gitattributes +8 -0
  2. app.py +210 -0
  3. data/elite_transfers.csv +31 -0
  4. data/processed/app_features.csv +0 -0
  5. data/raw/fbref/2022-2023 Football Player Stats.csv +0 -0
  6. data/raw/transfermarkt/appearances.csv +3 -0
  7. data/raw/transfermarkt/club_games.csv +3 -0
  8. data/raw/transfermarkt/clubs.csv +0 -0
  9. data/raw/transfermarkt/competitions.csv +68 -0
  10. data/raw/transfermarkt/countries.csv +119 -0
  11. data/raw/transfermarkt/game_events.csv +3 -0
  12. data/raw/transfermarkt/game_lineups.csv +3 -0
  13. data/raw/transfermarkt/games.csv +3 -0
  14. data/raw/transfermarkt/national_teams.csv +119 -0
  15. data/raw/transfermarkt/player_valuations.csv +3 -0
  16. data/raw/transfermarkt/players.csv +3 -0
  17. data/raw/transfermarkt/transfers.csv +3 -0
  18. fairvalue_xgboost.json +0 -0
  19. requirements.txt +7 -0
  20. src/data/__init__.py +0 -0
  21. src/data/__pycache__/__init__.cpython-311.pyc +0 -0
  22. src/data/__pycache__/kaggle_loader.cpython-311.pyc +0 -0
  23. src/data/__pycache__/preprocess.cpython-311.pyc +0 -0
  24. src/data/kaggle_loader.py +88 -0
  25. src/data/preprocess.py +51 -0
  26. src/features/__init__.py +0 -0
  27. src/features/__pycache__/__init__.cpython-311.pyc +0 -0
  28. src/features/__pycache__/build_features.cpython-311.pyc +0 -0
  29. src/features/build_features.py +76 -0
  30. src/models/__init__.py +0 -0
  31. src/models/__pycache__/__init__.cpython-311.pyc +0 -0
  32. src/models/__pycache__/predict_cap.cpython-311.pyc +0 -0
  33. src/models/__pycache__/train_xgboost.cpython-311.pyc +0 -0
  34. src/models/explain.py +43 -0
  35. src/models/predict_cap.py +57 -0
  36. 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