Major refactor: Fantabeto 26/27 — modular package, GBM ensemble, MILP/MCTS optimization
Phase 1: Data Engineering
- Refactored notebooks into src/{scraper,features,models,optimization,bot}
- FBref scraper with proxy rotation + Playwright Cloudflare bypass
- Fantacalcio.it integrated scraper (authenticated API + HTML fallback)
- api-football RapidAPI client for supplementary xG/xA/injuries
- RAG news pipeline: Gazzetta, Sky Sport, Di Marzio → injury/suspension/tactical extraction
- 26/27 season config: teams, scoring rules, name mappings, news sources
Phase 2: SOTA ML Architecture
- GBM Ensemble (LightGBM + CatBoost + XGBoost) with stacked blending
- Bootstrap ensemble for uncertainty quantification
- SinhArcsinh distribution head (ported from original TF Probability)
- Card classifiers (yellow/red), penalty model, goal probability (Poisson)
- Temporal GNN for player interaction modeling (crosses→goals, passes→assists)
- Optuna hyperparameter tuning with time-series CV
Phase 3: Operations Research
- Auction solver: MILP knapsack with PuLP (budget + role constraints)
- Grid Auction (Asta a Griglia): Minimax game theory bidding strategy
- Weekly lineup optimizer: MCTS maximizing win probability vs opponent
- Modificatore Difesa integration + captain selection
- Transfer market analyzer: buy-low/sell-high via xG regression to mean
- Opponent behavior modeling from historical lineage patterns
Phase 4: Agentic Workflow
- Telegram bot: auto-briefing (Friday + Sunday morning)
- Tactical briefing generator with start/sit recommendations
- GitHub Actions CI/CD: scheduled pipeline (scrape → predict → notify)
Infrastructure:
- 31 pytest unit tests (features, models, scraper, optimization)
- requirements.txt (lightgbm, catboost, xgboost, optuna, pulp, playwright, langchain)
- Makefile with install/test/lint/scrape/train/bot targets
- Jupyter notebook: 26_27_strategy.ipynb demonstrating auction + matchday 1 mockup
- Completely rewritten README.md with architecture diagram
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# 2026/27 Serie A teams
|
||||
# Promoted teams subject to confirmation. Update after final Serie B playoff.
|
||||
teams:
|
||||
- Atalanta
|
||||
- Bologna
|
||||
- Cagliari
|
||||
- Como
|
||||
- Empoli
|
||||
- Fiorentina
|
||||
- Frosinone
|
||||
- Genoa
|
||||
- Inter
|
||||
- Juventus
|
||||
- Lazio
|
||||
- Lecce
|
||||
- Milan
|
||||
- Monza
|
||||
- Napoli
|
||||
- Parma
|
||||
- Roma
|
||||
- Sassuolo
|
||||
- Torino
|
||||
- Udinese
|
||||
|
||||
# Promoted from Serie B 2025/26 (tentative)
|
||||
promoted_2026_27:
|
||||
- Frosinone
|
||||
- Genoa
|
||||
- Sassuolo
|
||||
|
||||
# Relegated after 2025/26
|
||||
relegated_2025_26:
|
||||
- Venezia
|
||||
- Hellas Verona
|
||||
- Salernitana
|
||||
|
||||
fantacalcio_api:
|
||||
season_id_current: 21 # 2026/27
|
||||
season_id_last: 20 # 2025/26 (complete)
|
||||
season_id_previous: 19 # 2024/25
|
||||
season_id_older: 18 # 2023/24
|
||||
base_url: "https://www.fantacalcio.it/api/v1/Excel"
|
||||
@@ -0,0 +1,40 @@
|
||||
# Fantacalcio scoring rules (FVM standard)
|
||||
scoring:
|
||||
goal: 3.0 # +3 per goal scored
|
||||
assist: 1.0 # +1 per assist
|
||||
yellow_card: -0.5 # -0.5 per yellow card
|
||||
red_card: -1.0 # -1 per red card
|
||||
own_goal: -2.0 # -2 per own goal
|
||||
penalty_saved: 3.0 # +3 for GK penalty save
|
||||
penalty_missed: -3.0 # -3 for missed penalty
|
||||
clean_sheet_gk: 1.0 # +1 for GK clean sheet (min 45min)
|
||||
goals_conceded_gk: -1.0 # -1 per goal conceded (GK)
|
||||
|
||||
modificatore_difesa:
|
||||
# Average of best 3 defender votes
|
||||
threshold_6_0: 1 # +1 if avg >= 6.0
|
||||
threshold_6_5: 3 # +3 if avg >= 6.5
|
||||
threshold_7_0: 6 # +6 if avg >= 7.0
|
||||
|
||||
roles:
|
||||
P: goalkeeper
|
||||
D: defender
|
||||
C: midfielder
|
||||
A: forward
|
||||
|
||||
roster_quotas:
|
||||
P: 3 # 3 goalkeepers
|
||||
D: 8 # 8 defenders
|
||||
C: 8 # 8 midfielders
|
||||
A: 6 # 6 forward
|
||||
|
||||
starting_lineup_quotas:
|
||||
P: 1 # 1 goalkeeper
|
||||
D: 3 # minimum 3 defenders (varies by formation)
|
||||
D_max: 5
|
||||
C: 3
|
||||
C_max: 5
|
||||
A: 1
|
||||
A_max: 3
|
||||
|
||||
fantavoto_formula: "vote + goals*3 + assists*1 - yellow*0.5 - red*1"
|
||||
@@ -0,0 +1,42 @@
|
||||
# Name mappings between FBref and Fantacalcio.it naming conventions
|
||||
# FBref uses international names, Fantacalcio uses Italian-adapted names
|
||||
mappings:
|
||||
- from: "Ostigard"
|
||||
to: "Ostigard"
|
||||
team: "Napoli"
|
||||
- from: "Min-jae"
|
||||
to: "Kim"
|
||||
team: "Napoli"
|
||||
- from: "Hojlund"
|
||||
to: "Hojlund"
|
||||
team: "Atalanta"
|
||||
- from: "Gytkjaer"
|
||||
to: "Gytkjaer"
|
||||
team: "Monza"
|
||||
- from: "Carlos"
|
||||
to: "Augusto"
|
||||
team: "Inter"
|
||||
- from: "Maehle"
|
||||
to: "Maehle"
|
||||
team: "Atalanta"
|
||||
- from: "Kjaer"
|
||||
to: "Kjaer"
|
||||
team: "Milan"
|
||||
- from: "Djuricic"
|
||||
to: "Djuricic"
|
||||
team: "Sampdoria"
|
||||
- from: "Djuric"
|
||||
to: "Djuric"
|
||||
team: "Hellas Verona"
|
||||
- from: "Arthur"
|
||||
to: "Cabral"
|
||||
team: "Fiorentina"
|
||||
- from: "Martinez"
|
||||
to: "Alvarez"
|
||||
team: "Sassuolo"
|
||||
- from: "Gudmundsson"
|
||||
to: "Gudmundsson"
|
||||
team: "Genoa"
|
||||
- from: "Kristensen"
|
||||
to: "Nissen"
|
||||
team: "Roma"
|
||||
@@ -0,0 +1,41 @@
|
||||
# Italian sports news sources for RAG pipeline
|
||||
sources:
|
||||
gazzetta:
|
||||
name: "Gazzetta dello Sport"
|
||||
url: "https://www.gazzetta.it/calcio/serie-a/"
|
||||
rss: "https://www.gazzetta.it/rss/calcio/serie-a.xml"
|
||||
enabled: true
|
||||
|
||||
skysport:
|
||||
name: "Sky Sport Italia"
|
||||
url: "https://sport.sky.it/calcio/serie-a"
|
||||
rss: "https://sport.sky.it/calcio/serie-a/rss.xml"
|
||||
enabled: true
|
||||
|
||||
dimarzio:
|
||||
name: "Gianluca Di Marzio"
|
||||
url: "https://gianlucadimarzio.com/"
|
||||
enabled: true
|
||||
|
||||
tuttomercatoweb:
|
||||
name: "TuttoMercatoWeb"
|
||||
url: "https://www.tuttomercatoweb.com/serie-a/"
|
||||
enabled: true
|
||||
|
||||
football_italia:
|
||||
name: "Football Italia"
|
||||
url: "https://football-italia.net/"
|
||||
enabled: true
|
||||
|
||||
# Entity extraction schema
|
||||
entities:
|
||||
- name: "INJURY"
|
||||
fields: [player, team, injury_type, severity, expected_return_matchday]
|
||||
- name: "SUSPENSION"
|
||||
fields: [player, team, matchdays_banned, reason]
|
||||
- name: "TACTICAL_SHIFT"
|
||||
fields: [team, old_formation, new_formation, confidence]
|
||||
- name: "TRAINING_UPDATE"
|
||||
fields: [player, team, status, notes]
|
||||
- name: "TRANSFER_RUMOR"
|
||||
fields: [player, from_team, to_team, probability]
|
||||
Reference in New Issue
Block a user