Skip to content

Commit 6b481b7

Browse files
committed
feat: working v2
1 parent 8b5cc8e commit 6b481b7

File tree

5 files changed

+219
-11
lines changed

5 files changed

+219
-11
lines changed

.gitignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
__pycache__/
2-
.mypy_cache
3-
.sofascore_cache
2+
*_cache
3+
.vscode

poetry.lock

+145-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ rich = "^13.3.5"
2323
requests-cache = "^1.0.1"
2424
pyrate-limiter = "^2.10.0"
2525
requests-ratelimiter = "^0.4.0"
26+
pandas = "^2.0.2"
2627

2728

2829
[tool.poetry.group.dev.dependencies]

sofascore/sofascore.py

+22
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,28 @@ def decisive_goal_for_win(self) -> bool:
114114
# TODO: We need to read yellow and red cards from the incident call:
115115
# https://api.sofascore.com/api/v1/event/11227333/incidents
116116

117+
@property
118+
def features(self) -> dict:
119+
return {
120+
"assists": self.assists,
121+
"expectedAssists": self.expectedAssists,
122+
"expectedGoals": self.expectedGoals,
123+
"goals": self.goals,
124+
"goalsPrevented": self.goalsPrevented,
125+
"minutesPlayed": self.minutesPlayed,
126+
"onTargetScoringAttempt": self.onTargetScoringAttempt,
127+
"savedShotsFromInsideTheBox": self.savedShotsFromInsideTheBox,
128+
"saves": self.saves,
129+
"team_goals": self.team_goals,
130+
"team_goals_conceded": self.team_goals_conceded,
131+
"win": int(self.win),
132+
"loss": int(self.loss),
133+
"draw": int(self.draw),
134+
"clean_sheet": int(self.clean_sheet),
135+
"decisive_goal_for_draw": int(self.decisive_goal_for_draw),
136+
"decisive_goal_for_win": int(self.decisive_goal_for_win),
137+
}
138+
117139
def __init__(self, **kwargs):
118140
for key, value in kwargs.items():
119141
setattr(self, key, value)

v2.py

+49-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
#!/usr/bin/env python3
2-
32
import logging
43
from dataclasses import dataclass
54
from datetime import datetime, timezone
65

6+
import numpy as np
7+
import pandas as pd
78
from rich import print
89
from rich.console import Console
910
from rich.logging import RichHandler
1011
from rich.table import Table
12+
from sklearn.linear_model import LinearRegression # type: ignore
13+
from sklearn.metrics import mean_squared_error # type: ignore
14+
from sklearn.model_selection import train_test_split # type: ignore
1115

1216
from holdet import holdet
13-
from lp import lp
1417
from sofascore import sofascore
1518

1619

@@ -71,9 +74,13 @@ def xGrowth(self) -> float:
7174

7275
return growth
7376

77+
@property
78+
def growth(self) -> int:
79+
return self.values.growth
80+
7481
@property
7582
def diff(self) -> float:
76-
return self.xGrowth - self.values.growth
83+
return self.xGrowth - self.growth
7784

7885
def __lt__(self, other: "Round") -> bool:
7986
return self.number < other.number
@@ -375,8 +382,42 @@ def get_holdet(game: holdet.Game) -> list[Holdet]:
375382
candidates.append(Candidate(h, s))
376383
status.console.log(f"Found {len(candidates)} players on Sofascore")
377384

378-
with console.status("Finding optimal team..."):
379-
solution = lp.find_optimal_team(candidates, 70 * 1000000)
380-
status.console.log(f"Found optimal 11 out of {len(candidates)} players")
381-
382-
print(Formation(solution))
385+
# Extract and flatten the data
386+
data = []
387+
for candidate in candidates:
388+
for round in candidate.rounds:
389+
for stat in round.stats:
390+
row = {
391+
"id": candidate.id,
392+
"round": round.number,
393+
}
394+
row.update(stat.features)
395+
row.update({"growth": round.growth})
396+
data.append(row)
397+
398+
# Create a pandas DataFrame
399+
df = pd.DataFrame(data)
400+
401+
# Define features (X) and target (y)
402+
X = df.iloc[:, :-1]
403+
y = df.iloc[:, -1]
404+
405+
# Split the data into training and testing sets
406+
X_train, X_test, y_train, y_test = train_test_split(X, y)
407+
408+
# Create and fit the model
409+
model = LinearRegression()
410+
model.fit(X_train, y_train)
411+
412+
# Make predictions
413+
y_pred = model.predict(X_test)
414+
415+
# Evaluate the model
416+
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
417+
print("Root Mean Squared Error:", rmse)
418+
419+
# with console.status("Finding optimal team..."):
420+
# solution = lp.find_optimal_team(candidates, 70 * 1000000)
421+
# status.console.log(f"Found optimal 11 out of {len(candidates)} players")
422+
423+
# print(Formation(solution))

0 commit comments

Comments
 (0)