BraydenMoore commited on
Commit
d547283
1 Parent(s): a2525f9

Update with up to date data

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +0 -36
  2. Dockerfile +0 -31
  3. README.md +0 -10
  4. Source/Build/__pycache__/build.cpython-310.pyc +0 -0
  5. Source/Build/__pycache__/build.cpython-311.pyc +0 -0
  6. Source/Build/__pycache__/build.cpython-39.pyc +0 -0
  7. Source/Build/build.py +0 -197
  8. Source/Build/nfl_data_py +0 -1
  9. Source/Build/update.py +0 -59
  10. Source/Data/gbg.csv +0 -3
  11. Source/Data/gbg_and_odds.csv +0 -3
  12. Source/Data/gbg_and_odds_this_year-Thinkpad.csv +0 -3
  13. Source/Data/predictions.csv +0 -3
  14. Source/Data/record.json +1 -1
  15. Source/Models/__init__.py +0 -0
  16. Source/Models/xgboost_ATS_no_odds_57.3%.json +0 -0
  17. Source/Models/xgboost_ML_75.4%.json +0 -0
  18. Source/Models/xgboost_ML_no_odds_56.8%.json +0 -0
  19. Source/Models/xgboost_ML_no_odds_60.8%.json +0 -0
  20. Source/Models/xgboost_ML_no_odds_61.3%.json +0 -0
  21. Source/Models/xgboost_ML_no_odds_62.3%.json +0 -0
  22. Source/Models/xgboost_ML_no_odds_63.3%.json +0 -0
  23. Source/Models/xgboost_ML_no_odds_63.8%.json +0 -0
  24. Source/Models/xgboost_ML_no_odds_64.3%.json +0 -0
  25. Source/Models/xgboost_ML_no_odds_64.8%.json +0 -0
  26. Source/Models/xgboost_ML_no_odds_66.3%.json +0 -0
  27. Source/Models/xgboost_ML_no_odds_66.8%.json +0 -0
  28. Source/Models/xgboost_ML_no_odds_68.8%.json +0 -0
  29. Source/Models/xgboost_ML_no_odds_69.3%.json +0 -0
  30. Source/Models/xgboost_ML_no_odds_70.4%.json +0 -0
  31. Source/Models/xgboost_ML_no_odds_71.4%.json +0 -0
  32. Source/Models/xgboost_OU_59.3%.json +0 -0
  33. Source/Models/xgboost_OU_no_odds_51.8%.json +0 -0
  34. Source/Models/xgboost_OU_no_odds_53.3%.json +0 -0
  35. Source/Models/xgboost_OU_no_odds_55.8%.json +0 -0
  36. Source/Models/xgboost_OU_no_odds_58.3%.json +0 -0
  37. Source/Models/xgboost_OU_no_odds_59.8%.json +0 -0
  38. Source/Models/xgboost_OU_no_odds_60.8%.json +0 -0
  39. Source/Predict/.DS_Store +0 -0
  40. Source/Predict/__pycache__/predict.cpython-310.pyc +0 -0
  41. Source/Predict/__pycache__/predict.cpython-311.pyc +0 -0
  42. Source/Predict/__pycache__/predict.cpython-312.pyc +0 -0
  43. Source/Predict/__pycache__/predict.cpython-39.pyc +0 -0
  44. Source/Predict/predict.py +0 -156
  45. Source/Test/__init__.py +0 -0
  46. Source/Test/xgboost_ATS.py +0 -73
  47. Source/Test/xgboost_ATS_no_odds_55.3%_dark.png +0 -0
  48. Source/Test/xgboost_ATS_no_odds_57.3%_dark.png +0 -0
  49. Source/Test/xgboost_ML.py +0 -59
  50. Source/Test/xgboost_ML_75.4%.png +0 -0
.gitattributes DELETED
@@ -1,36 +0,0 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
36
- *.csv filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Dockerfile DELETED
@@ -1,31 +0,0 @@
1
-
2
- # Use the official lightweight Python image.
3
- # https://hub.docker.com/_/python
4
- FROM python:3.11-slim
5
-
6
- # Allow statements and log messages to immediately appear in the logs
7
- ENV PYTHONUNBUFFERED True
8
-
9
- # Copy local code to the container image.
10
- ENV APP_HOME /app
11
- WORKDIR $APP_HOME
12
- COPY . ./
13
-
14
- # Install production dependencies.
15
- RUN pip install -r requirements.txt
16
-
17
- RUN useradd -m -u 1000 user
18
- USER user
19
- ENV HOME=/home/user \
20
- PATH=/home/user/.local/bin:$PATH
21
-
22
- WORKDIR $APP_HOME
23
-
24
- COPY --chown=user . $HOME/app
25
-
26
- # Run the web service on container startup. Here we use the gunicorn
27
- # webserver, with one worker process and 8 threads.
28
- # For environments with multiple CPU cores, increase the number of workers
29
- # to be equal to the cores available.
30
- # Timeout is set to 0 to disable the timeouts of the workers to allow Cloud Run to handle instance scaling.
31
- CMD exec gunicorn --bind 0.0.0.0:7860 --workers 4 --threads 8 --timeout 0 main:app
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README.md DELETED
@@ -1,10 +0,0 @@
1
- ---
2
- title: MARCI (NFL Betting)
3
- emoji: 🏈
4
- colorFrom: red
5
- colorTo: blue
6
- sdk: docker
7
- pinned: false
8
- ---
9
-
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
Source/Build/__pycache__/build.cpython-310.pyc DELETED
Binary file (9.16 kB)
 
Source/Build/__pycache__/build.cpython-311.pyc DELETED
Binary file (20.3 kB)
 
Source/Build/__pycache__/build.cpython-39.pyc DELETED
Binary file (9.41 kB)
 
Source/Build/build.py DELETED
@@ -1,197 +0,0 @@
1
- from nfl_data_py import nfl_data_py as nfl
2
- from tqdm import tqdm
3
- import numpy as np
4
- import pandas as pd
5
- pd.set_option('chained_assignment',None)
6
- pd.set_option('display.max_columns',None)
7
- import os
8
- import datetime as dt
9
-
10
- current_directory = os.path.dirname(os.path.abspath(__file__))
11
- parent_directory = os.path.dirname(current_directory)
12
- data_directory = os.path.join(parent_directory, 'Data')
13
-
14
- year = dt.datetime.now().year
15
- month = dt.datetime.now().month
16
- current_season = year if month in [8,9,10,11,12] else year-1
17
-
18
- def get_pbp_data(get_seasons=[]):
19
- """
20
- Pull data from nflFastR's Github repo.
21
-
22
- """
23
- pbp = nfl.import_pbp_data(get_seasons)
24
- #pbp = pd.read_csv(r"C:\Users\brayd\Downloads\play_by_play_2023.csv")
25
- pbp['TOP_seconds'] = pbp['drive_time_of_possession'].apply(lambda x: int(x.split(':')[0]) * 60 + int(x.split(':')[1]) if pd.notnull(x) else 0)
26
-
27
- return pbp
28
-
29
-
30
- def build_gbg_data(get_seasons=[]):
31
- """
32
- Build a game-by-game dataset to use for prediction models.
33
-
34
- """
35
- print('Loading play-by-play data.')
36
- pbp = get_pbp_data(get_seasons)
37
- game_date_dict = dict(pbp[['game_id','game_date']].values)
38
- teams = list(set(list(pbp['home_team'].unique()) + list(pbp['away_team'].unique())))
39
- seasons = pbp['season'].unique()
40
-
41
- print('Building game-by-game data.')
42
- data = pd.DataFrame()
43
- for season in seasons:
44
- print(season)
45
- for team_name in tqdm(teams):
46
- # create features
47
- team = pbp.loc[((pbp['home_team']==team_name) | (pbp['away_team']==team_name)) & (pbp['season']==season)]
48
- team['GP'] = team['week']
49
- team['W'] = [1 if r>0 and team_name==h else 1 if r<0 and team_name==a else 0 for r,a,h in team[['result','away_team','home_team']].values]
50
- team['L'] = [0 if r>0 and team_name==h else 0 if r<0 and team_name==a else 1 for r,a,h in team[['result','away_team','home_team']].values]
51
- team['W_PCT'] = team['W']/team['GP']
52
- team['TOP'] = [t if team_name==p else 0 for t,p in team[['TOP_seconds','posteam']].values]
53
- team['FGA'] = [1 if team_name==p and f==1 else 0 for p,f in team[['posteam','field_goal_attempt']].values]
54
- team['FGM'] = [1 if team_name==p and f=='made' else 0 for p,f in team[['posteam','field_goal_result']].values]
55
- team['FG_PCT'] = team['FGM']/team['FGA']
56
- team['PassTD'] = np.where((team['posteam'] == team_name) & (team['pass_touchdown'] == 1), 1, 0)
57
- team['RushTD'] = np.where((team['posteam'] == team_name) & (team['rush_touchdown'] == 1), 1, 0)
58
- team['PassTD_Allowed'] = np.where((team['defteam'] == team_name) & (team['pass_touchdown'] == 1), 1, 0)
59
- team['RushTD_Allowed'] = np.where((team['defteam'] == team_name) & (team['rush_touchdown'] == 1), 1, 0)
60
- team['PassYds'] = [y if p==team_name else 0 for p,y in team[['posteam','passing_yards']].values]
61
- team['RushYds'] = [y if p==team_name else 0 for p,y in team[['posteam','rushing_yards']].values]
62
- team['PassYds_Allowed'] = [y if d==team_name else 0 for d,y in team[['defteam','passing_yards']].values]
63
- team['RushYds_Allowed'] = [y if d==team_name else 0 for d,y in team[['defteam','rushing_yards']].values]
64
- team['Fum'] = np.where((team['defteam'] == team_name) & (team['fumble_lost'] == 1), 1, 0)
65
- team['Fum_Allowed'] = np.where((team['posteam'] == team_name) & (team['fumble_lost'] == 1), 1, 0)
66
- team['INT'] = np.where((team['defteam'] == team_name) & (team['interception'] == 1), 1, 0)
67
- team['INT_Allowed'] = np.where((team['posteam'] == team_name) & (team['interception'] == 1), 1, 0)
68
- team['Sacks'] = np.where((team['defteam'] == team_name) & (team['sack'] == 1), 1, 0)
69
- team['Sacks_Allowed'] = np.where((team['posteam'] == team_name) & (team['sack'] == 1), 1, 0)
70
- team['Penalties'] = np.where((team['penalty_team'] == team_name), 1, 0)
71
- team['FirstDowns'] = [1 if team_name==p and f==1 else 0 for p,f in team[['posteam','first_down']].values]
72
- team['3rdDownConverted'] = [1 if p==team_name and t==1 else 0 for p,t in team[['posteam','third_down_converted']].values]
73
- team['3rdDownFailed'] = [1 if p==team_name and t==1 else 0 for p,t in team[['posteam','third_down_failed']].values]
74
- team['3rdDownAllowed'] = [1 if d==team_name and t==1 else 0 for d,t in team[['defteam','third_down_converted']].values]
75
- team['3rdDownDefended'] = [1 if d==team_name and t==1 else 0 for d,t in team[['defteam','third_down_failed']].values]
76
- team['PTS'] = [ap if at==team_name else hp if ht==team_name else None for ht,at,hp,ap in team[['home_team','away_team','home_score','away_score']].values]
77
- team['PointDiff'] = [r if team_name==h else -r if team_name==a else 0 for r,a,h in team[['result','away_team','home_team']].values]
78
-
79
- # aggregate from play-by-play to game-by-game
80
- features = {
81
- 'GP':'mean',
82
- 'W':'mean',
83
- 'L':'mean',
84
- 'W_PCT':'mean',
85
- 'TOP':'sum',
86
- 'FGA':'sum',
87
- 'FGM':'sum',
88
- 'FG_PCT':'mean',
89
- 'PassTD':'sum',
90
- 'RushTD':'sum',
91
- 'PassTD_Allowed':'sum',
92
- 'RushTD_Allowed':'sum',
93
- 'PassYds':'sum',
94
- 'RushYds':'sum',
95
- 'PassYds_Allowed':'sum',
96
- 'RushYds_Allowed':'sum',
97
- 'Fum':'sum',
98
- 'Fum_Allowed':'sum',
99
- 'INT':'sum',
100
- 'INT_Allowed':'sum',
101
- 'Sacks':'sum',
102
- 'Sacks_Allowed':'sum',
103
- 'Penalties':'sum',
104
- 'FirstDowns':'sum',
105
- '3rdDownConverted':'sum',
106
- '3rdDownFailed':'sum',
107
- '3rdDownAllowed':'sum',
108
- '3rdDownDefended':'sum',
109
- 'PTS':'mean',
110
- 'PointDiff':'mean'
111
- }
112
-
113
- game = team.groupby('game_id').agg(features).reset_index().sort_values('GP')
114
- game[['W','L']] = game[['W','L']].expanding().sum()
115
- game[game.columns[4:]] = game[game.columns[4:]].expanding().mean()
116
- if season != current_season:
117
- game[game.columns[1:]] = game[game.columns[1:]].shift()
118
- game['TEAM'] = team_name
119
- game['Season'] = season
120
- else:
121
- game['TEAM'] = team_name
122
- game['Season'] = season
123
-
124
- data = pd.concat([data,game])
125
-
126
- # separate home and away data and merge
127
- data = data.merge(pbp[['game_id','home_team','away_team']].drop_duplicates())
128
- home = data.loc[data['home_team']==data['TEAM']]
129
- away = data.loc[data['away_team']==data['TEAM']]
130
- away.columns = [f'{i}.Away' for i in away.columns]
131
- gbg = home.merge(away,left_on='game_id',right_on='game_id.Away')
132
- gbg.drop(columns=['TEAM','TEAM.Away','home_team.Away','away_team.Away','Season.Away','game_id.Away'], inplace=True)
133
- gbg['game_date'] = gbg['game_id'].map(game_date_dict)
134
-
135
- # save current data
136
- if current_season in get_seasons:
137
- gbg_this_year = gbg.loc[gbg['Season']==current_season]
138
- file_path = os.path.join(data_directory, 'gbg_this_year.csv')
139
- gbg_this_year.to_csv(file_path, index=False)
140
-
141
- # save historical data
142
- if get_seasons != [current_season]:
143
- gbg = gbg.loc[gbg['Season']!=current_season]
144
- file_path = os.path.join(data_directory, 'gbg.csv')
145
- gbg.to_csv(file_path, index=False)
146
-
147
-
148
- def add_odds_data():
149
- """
150
- Get odds from Australian Sports Betting's free online dataset and merge it with game-by-game data.
151
-
152
- """
153
-
154
- # get team abbreviations
155
- team_descriptions = nfl.import_team_desc()
156
- team_abbreviation_dict = dict(team_descriptions[['team_name','team_abbr']].values)
157
-
158
- # get odds
159
- odds = pd.read_excel('https://www.aussportsbetting.com/historical_data/nfl.xlsx')
160
- odds['Home Team'] = odds['Home Team'].str.replace('Washington Redskins','Washington Commanders').str.replace('Washington Football Team','Washington Commanders')
161
- odds['Away Team'] = odds['Away Team'].str.replace('Washington Redskins','Washington Commanders').str.replace('Washington Football Team','Washington Commanders')
162
- odds['Season'] = [i.year if i.month in [8,9,10,11,12] else i.year-1 for i in odds['Date']]
163
- odds['Home Team Abbrev'] = odds['Home Team'].map(team_abbreviation_dict).str.replace('LAR','LA')
164
- odds['Away Team Abbrev'] = odds['Away Team'].map(team_abbreviation_dict).str.replace('LAR','LA')
165
- odds = odds[['Date','Home Score','Away Score','Home Team Abbrev','Away Team Abbrev','Home Odds Close','Away Odds Close','Total Score Close','Home Line Close']]
166
- odds['Key'] = odds['Date'].astype(str) + odds['Home Team Abbrev'] + odds['Away Team Abbrev']
167
- odds = odds.drop(columns=['Date','Home Team Abbrev','Away Team Abbrev']).dropna()
168
- odds['Home Odds'] = [round((i-1)*100) if i>= 2 else round(-100/(i-1)) for i in odds['Home Odds Close']]
169
- odds['Away Odds'] = [round((i-1)*100) if i>= 2 else round(-100/(i-1)) for i in odds['Away Odds Close']]
170
- odds['Home Winnings'] = [ho-1 if h>a else -1 if a>h else 0 for ho,h,a in odds[['Home Odds Close','Home Score','Away Score']].values]
171
- odds['Away Winnings'] = [ao-1 if a>h else -1 if h>a else 0 for ao,h,a in odds[['Away Odds Close','Home Score','Away Score']].values]
172
-
173
- # load gbg data
174
- file_path = os.path.join(data_directory, 'gbg.csv')
175
- gbg = pd.read_csv(file_path)
176
- file_path = os.path.join(data_directory, 'gbg_this_year.csv')
177
- gbg_this_year = pd.read_csv(file_path)
178
-
179
- # merge and save
180
- dataframes = [gbg, gbg_this_year]
181
- for idx in range(2):
182
- i = dataframes[idx]
183
- i['Key'] = i['game_date'].astype(str) + i['home_team'] + i['away_team']
184
- gbg_and_odds = i.merge(odds, left_on='Key', right_on='Key')
185
- gbg_and_odds['Home-Team-Cover'] = [1 if (h-a)>-l else 0 if (h-a)<-l else 2 for h,a,l in gbg_and_odds[['Home Score','Away Score','Home Line Close']].values]
186
- gbg_and_odds['Home-Team-Win'] = (gbg_and_odds['Home Score']>gbg_and_odds['Away Score']).astype(int)
187
- gbg_and_odds['Over'] = ((gbg_and_odds['Home Score'] + gbg_and_odds['Away Score'])>gbg_and_odds['Total Score Close']).astype(int)
188
-
189
- if idx==0:
190
- file_path = os.path.join(data_directory, 'gbg_and_odds.csv')
191
- else:
192
- file_path = os.path.join(data_directory, 'gbg_and_odds_this_year.csv')
193
-
194
- gbg_and_odds.drop_duplicates(subset='game_id').to_csv(file_path, index=False)
195
-
196
-
197
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Source/Build/nfl_data_py DELETED
@@ -1 +0,0 @@
1
- Subproject commit e4988dc303bc441108dd11f4ae93a8200aab10e1
 
 
Source/Build/update.py DELETED
@@ -1,59 +0,0 @@
1
- import nfl_data_py.nfl_data_py as nfl
2
- import build
3
- import datetime as dt
4
- import numpy as np
5
- import pandas as pd
6
- pd.set_option('chained_assignment',None)
7
- pd.set_option('display.max_columns',None)
8
- import os
9
- import pickle as pkl
10
-
11
- current_directory = os.path.dirname(os.path.abspath(__file__))
12
- parent_directory = os.path.dirname(current_directory)
13
- data_directory = os.path.join(parent_directory, 'Data')
14
- pickle_directory = os.path.join(parent_directory, 'Pickles')
15
-
16
- # get team abbreviations
17
- file_path = os.path.join(pickle_directory, 'team_name_to_abbreviation.pkl')
18
- with open(file_path, 'rb') as f:
19
- team_name_to_abbreviation = pkl.load(f)
20
- file_path = os.path.join(pickle_directory, 'team_abbreviation_to_name.pkl')
21
- with open(file_path, 'rb') as f:
22
- team_abbreviation_to_name = pkl.load(f)
23
-
24
- # get current season
25
- year = dt.datetime.now().year
26
- month = dt.datetime.now().month
27
- current_season = year if month in [8,9,10,11,12] else year-1
28
-
29
- # get schedule
30
- print('Getting schedule.\n')
31
- url = 'https://www.nbcsports.com/nfl/schedule'
32
- df = pd.read_html(url)
33
- file_path = os.path.join(pickle_directory, 'schedule.pkl')
34
- with open(file_path, 'wb') as f:
35
- pkl.dump(df, f)
36
-
37
- # update current season
38
- build.build_gbg_data(get_seasons=[current_season])
39
- #build.build_gbg_data(get_seasons=range(2014,2024))
40
- build.add_odds_data()
41
-
42
- # get winners
43
- pbp = build.get_pbp_data([current_season])
44
- pbp = pbp.drop_duplicates(subset='game_id')
45
- pbp[['season','week','away','home']] = pbp['game_id'].str.split('_', expand=True)
46
- games = pbp[['game_id','away_score','home_score','season','week','away','home']]
47
- games[['away_score','home_score','season','week']] = games[['away_score','home_score','season','week']].astype(int)
48
-
49
- games['away_team'] = games['away'].map(team_abbreviation_to_name)
50
- games['home_team'] = games['home'].map(team_abbreviation_to_name)
51
-
52
- games['total'] = games['away_score'] + games['home_score']
53
- games['winner'] = [a if a_s>h_s else h if h_s>a_s else 'Tie' for a,h,a_s,h_s in games[['away_team','home_team','away_score','home_score']].values]
54
-
55
- file_path = os.path.join(data_directory, 'results.csv')
56
- games[['game_id','total','winner']].to_csv(file_path, index=False)
57
-
58
-
59
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Source/Data/gbg.csv DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:4b03612517c6505adabfc11be02fbd51be8ab8c104361f645401c58c128fd2d7
3
- size 1613287
 
 
 
 
Source/Data/gbg_and_odds.csv DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:d6f1a3ea061ed26a13c2398938efe0a60267d07abfde4baaff82db22ec35e79f
3
- size 1663814
 
 
 
 
Source/Data/gbg_and_odds_this_year-Thinkpad.csv DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:ffb812ba82afc8e124ea3186f8bcc04e66a10b15e9507e6fa8e6eba18463c5f7
3
- size 276
 
 
 
 
Source/Data/predictions.csv DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:0c67a5b32fca86661a44a993df5b8001073ab8e99fc0a588d050bfc04bb4f0c3
3
- size 20000
 
 
 
 
Source/Data/record.json CHANGED
@@ -1 +1 @@
1
- {"winners_correct": "74", "winners_incorrect": "38", "winners_tie": "", "winners_return": "66.1% accuracy, -3.0x return", "over_unders_correct": "68", "over_unders_incorrect": "76", "over_unders_push": "-2", "over_unders_return": "46.6% accuracy, -14.1x return", "latest_game": "Monday, 12/25", "over_unders_binom": "72.0% chance of equal or better performance by flipping a coin.", "winners_binom": "<1% chance of equal or better performance by flipping a coin."}
 
1
+ {"winners_correct": "74", "winners_incorrect": "38", "winners_tie": "", "winners_return": "66.1% accuracy, -3.0x return", "over_unders_correct": "68", "over_unders_incorrect": "76", "over_unders_push": "-2", "over_unders_return": "46.6% accuracy, -14.1x return", "latest_game": "Monday, 12/25", "over_unders_binom": "72.0% chance of equal or better performance by flipping a coin.", "winners_binom": "0.0% chance of equal or better performance by flipping a coin."}
Source/Models/__init__.py DELETED
File without changes
Source/Models/xgboost_ATS_no_odds_57.3%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_75.4%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_no_odds_56.8%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_no_odds_60.8%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_no_odds_61.3%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_no_odds_62.3%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_no_odds_63.3%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_no_odds_63.8%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_no_odds_64.3%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_no_odds_64.8%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_no_odds_66.3%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_no_odds_66.8%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_no_odds_68.8%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_no_odds_69.3%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_no_odds_70.4%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_ML_no_odds_71.4%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_OU_59.3%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_OU_no_odds_51.8%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_OU_no_odds_53.3%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_OU_no_odds_55.8%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_OU_no_odds_58.3%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_OU_no_odds_59.8%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Models/xgboost_OU_no_odds_60.8%.json DELETED
The diff for this file is too large to render. See raw diff
 
Source/Predict/.DS_Store DELETED
Binary file (6.15 kB)
 
Source/Predict/__pycache__/predict.cpython-310.pyc DELETED
Binary file (5.54 kB)
 
Source/Predict/__pycache__/predict.cpython-311.pyc DELETED
Binary file (12.4 kB)
 
Source/Predict/__pycache__/predict.cpython-312.pyc DELETED
Binary file (10.1 kB)
 
Source/Predict/__pycache__/predict.cpython-39.pyc DELETED
Binary file (5.65 kB)
 
Source/Predict/predict.py DELETED
@@ -1,156 +0,0 @@
1
- import xgboost as xgb
2
- import numpy as np
3
- import pandas as pd
4
- import pickle as pkl
5
- import os
6
- import requests
7
- from bs4 import BeautifulSoup
8
- import warnings
9
- warnings.filterwarnings("ignore")
10
- from datetime import datetime
11
-
12
- # set dirs for other files
13
- current_directory = os.path.dirname(os.path.abspath(__file__))
14
- parent_directory = os.path.dirname(current_directory)
15
- data_directory = os.path.join(parent_directory, 'Data')
16
- model_directory = os.path.join(parent_directory, 'Models')
17
- pickle_directory = os.path.join(parent_directory, 'Pickles')
18
-
19
- file_path = os.path.join(data_directory, 'gbg_this_year.csv')
20
- gbg = pd.read_csv(file_path, low_memory=False)
21
-
22
- file_path = os.path.join(data_directory, 'results.csv')
23
- results = pd.read_csv(file_path, low_memory=False)
24
-
25
- # get team abbreviations
26
- file_path = os.path.join(pickle_directory, 'team_name_to_abbreviation.pkl')
27
- with open(file_path, 'rb') as f:
28
- team_name_to_abbreviation = pkl.load(f)
29
-
30
- file_path = os.path.join(pickle_directory, 'team_abbreviation_to_name.pkl')
31
- with open(file_path, 'rb') as f:
32
- team_abbreviation_to_name = pkl.load(f)
33
-
34
- # get schedule
35
- file_path = os.path.join(pickle_directory, 'schedule.pkl')
36
- with open(file_path, 'rb') as f:
37
- schedule = pkl.load(f)
38
-
39
- # get current week
40
- file_path = os.path.join(pickle_directory, 'the_week.pkl')
41
- with open(file_path, 'rb') as f:
42
- the_week = pkl.load(f)
43
-
44
- # load models
45
- # moneyline
46
- model = 'xgboost_ML_no_odds_71.4%'
47
- file_path = os.path.join(model_directory, f'{model}.json')
48
- xgb_ml = xgb.Booster()
49
- xgb_ml.load_model(file_path)
50
-
51
- # over/under
52
- model = 'xgboost_OU_no_odds_59.8%'
53
- file_path = os.path.join(model_directory, f'{model}.json')
54
- xgb_ou = xgb.Booster()
55
- xgb_ou.load_model(file_path)
56
-
57
-
58
- def get_week():
59
- week = the_week['week']
60
- year = the_week['year']
61
- return int(week), int(year)
62
-
63
-
64
- def get_games(week):
65
- df = schedule[week-1]
66
- df['Away Team'] = [' '.join(i.split('\xa0')[1:]) for i in df['Away TeamAway Team']]
67
- df['Home Team'] = [' '.join(i.split('\xa0')[1:]) for i in df['Home TeamHome Team']]
68
- df['Date'] = pd.to_datetime(df['Game TimeGame Time'])
69
- df['Date'] = df['Date'].dt.strftime('%A %d/%m %I:%M %p')
70
- df['Date'] = df['Date'].apply(lambda x: f"{x.split()[0]} {int(x.split()[1].split('/')[1])}/{int(x.split()[1].split('/')[0])} {x.split()[2]}".capitalize())
71
- return df[['Away Team','Home Team','Date']]
72
-
73
-
74
- def get_one_week(home,away,season,week):
75
- try:
76
- max_GP_home = gbg.loc[((gbg['home_team'] == home) | (gbg['away_team'] == home)) & (gbg['GP'] < week)]['GP'].max()
77
- max_GP_away = gbg.loc[((gbg['home_team'] == away) | (gbg['away_team'] == away)) & (gbg['GP'] < week)]['GP'].max()
78
-
79
- home_df = gbg.loc[((gbg['away_team']==home) | (gbg['home_team']==home)) & (gbg['Season']==season) & (gbg['GP']==max_GP_home)]
80
- gbg_home_team = home_df['home_team'].item()
81
- home_df.drop(columns=['game_id','home_team','away_team','Season','game_date'], inplace=True)
82
- home_df = home_df[[i for i in home_df.columns if '.Away' not in i] if gbg_home_team==home else [i for i in home_df.columns if '.Away' in i]]
83
- home_df.columns = [i.replace('.Away','') for i in home_df.columns]
84
-
85
- away_df = gbg.loc[((gbg['away_team']==away) | (gbg['home_team']==away)) & (gbg['Season']==season) & (gbg['GP']==max_GP_away)]
86
- gbg_home_team = away_df['home_team'].item()
87
- away_df.drop(columns=['game_id','home_team','away_team','Season','game_date'], inplace=True)
88
- away_df = away_df[[i for i in away_df.columns if '.Away' not in i] if gbg_home_team==away else [i for i in away_df.columns if '.Away' in i]]
89
- away_df.columns = [i.replace('.Away','') + '.Away' for i in away_df.columns]
90
-
91
- df = home_df.reset_index(drop=True).merge(away_df.reset_index(drop=True), left_index=True, right_index=True)
92
- return df
93
- except ValueError:
94
- return pd.DataFrame()
95
-
96
-
97
- def predict(home,away,season,week,total):
98
- global results
99
-
100
- # finish preparing data
101
- if len(home)>4:
102
- home_abbrev = team_name_to_abbreviation[home]
103
- else:
104
- home_abbrev = home
105
-
106
- if len(away)>4:
107
- away_abbrev = team_name_to_abbreviation[away]
108
- else:
109
- away_abbrev = away
110
-
111
- data = get_one_week(home_abbrev,away_abbrev,season,week)
112
- data['Total Score Close'] = total
113
- matrix = xgb.DMatrix(data.astype(float).values)
114
-
115
- # create game id
116
- if week < 10:
117
- game_id = str(season) + '_0' + str(int(week)) + '_' + away_abbrev + '_' + home_abbrev
118
- else:
119
- game_id = str(season) + '_' + str(int(week)) + '_' + away_abbrev + '_' + home_abbrev
120
-
121
- try:
122
- moneyline_result = results.loc[results['game_id']==game_id, 'winner'].item()
123
- except:
124
- moneyline_result = 'N/A'
125
-
126
- try:
127
- ml_predicted_proba = xgb_ml.predict(matrix)[0][1]
128
- winner_proba = max([ml_predicted_proba, 1-ml_predicted_proba]).item()
129
- moneyline = {'Winner': [home if ml_predicted_proba>0.5 else away if ml_predicted_proba<0.5 else 'Toss-Up'],
130
- 'Probabilities':[winner_proba],
131
- 'Result': moneyline_result}
132
- except:
133
- moneyline = {'Winner': 'NA',
134
- 'Probabilities':['N/A'],
135
- 'Result': moneyline_result}
136
-
137
- try:
138
- result = results.loc[results['game_id']==game_id, 'total'].item()
139
- over_under_result = 'Over' if float(result)>float(total) else 'Push' if float(result)==float(total) else 'Under'
140
-
141
- except:
142
- over_under_result = 'N/A'
143
-
144
- try:
145
- ou_predicted_proba = xgb_ou.predict(matrix)[0][1]
146
- ou_proba = max([ou_predicted_proba, 1-ou_predicted_proba]).item()
147
-
148
- over_under = {'Over/Under': ['Over' if ou_predicted_proba>0.5 else 'Under'],
149
- 'Probability': [ou_proba],
150
- 'Result': over_under_result}
151
- except:
152
- over_under = {'Over/Under': 'N/A',
153
- 'Probability': ['N/A'],
154
- 'Result': over_under_result}
155
-
156
- return game_id, moneyline, over_under
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Source/Test/__init__.py DELETED
File without changes
Source/Test/xgboost_ATS.py DELETED
@@ -1,73 +0,0 @@
1
- from cgi import test
2
- import xgboost as xgb
3
- import pandas as pd
4
- import pickle as pkl
5
- import numpy as np
6
- import os
7
-
8
- model = 'xgboost_ATS_no_odds_57.3%'
9
-
10
- current_directory = os.path.dirname(os.path.abspath(__file__))
11
- parent_directory = os.path.dirname(current_directory)
12
- data_directory = os.path.join(parent_directory, 'Data')
13
- model_directory = os.path.join(parent_directory, 'Models')
14
- pickle_directory = os.path.join(parent_directory, 'Pickles')
15
-
16
- file_path = os.path.join(model_directory, f'{model}.json')
17
- xgb_ml = xgb.Booster()
18
- xgb_ml.load_model(file_path)
19
-
20
- file_path = os.path.join(pickle_directory, 'test_games_ATS_no_odds.pkl')
21
- with open(file_path,'rb') as f:
22
- test_games = pkl.load(f).tolist()
23
-
24
- file_path = os.path.join(data_directory, 'gbg_and_odds.csv')
25
- gbg_and_odds = pd.read_csv(file_path)
26
- test_data = gbg_and_odds.loc[gbg_and_odds['game_id'].isin(test_games)]
27
- test_data_matrix = xgb.DMatrix(test_data.drop(columns=['game_id','Home-Team-Win','Home-Team-Cover','Over','Season','home_team','away_team','game_date','Key','Home Score','Away Score','Home Odds Close','Away Odds Close','Home Winnings','Away Winnings','Away Odds','Home Odds']).astype(float).values)
28
-
29
- predicted_probas = xgb_ml.predict(test_data_matrix)
30
- predictions = np.argmax(predicted_probas, axis=1)
31
- test_data['predicted_proba'] = [i[1] for i in predicted_probas]
32
- test_data['prediction'] = predictions
33
- test_data['correct'] = test_data['Home-Team-Cover']==test_data['prediction']
34
- print(test_data['predicted_proba'])
35
- print(test_data['correct'].mean())
36
-
37
- bets = test_data.loc[(test_data['predicted_proba']>0.5) | (test_data['predicted_proba']<0.5)]
38
- bets['winnings'] = [0.91 if c==1 else -1 for c in bets['correct']]
39
-
40
- print('Actual')
41
- print(bets.loc[bets['Home-Team-Cover']==1].shape)
42
- print(bets.loc[bets['Home-Team-Cover']==0].shape)
43
- print(bets.loc[bets['Home-Team-Cover']==2].shape)
44
-
45
- print('Predicted')
46
- print(bets.loc[bets['prediction']==1].shape)
47
- print(bets.loc[bets['prediction']==0].shape)
48
- print(bets.loc[bets['prediction']==2].shape)
49
-
50
-
51
- import matplotlib.pyplot as plt
52
- fig = plt.figure(facecolor='black')
53
- ax = fig.add_subplot(1, 1, 1, facecolor='black')
54
-
55
- # Plot data with line color as RGB(0, 128, 0)
56
- ax.plot(bets['winnings'].cumsum().values*100, linewidth=3, color=(0/255, 128/255, 0/255))
57
-
58
- # Set title and labels
59
- ax.set_title('MARCI 3.0 - Against the Spread', color='white')
60
- ax.set_xlabel('Games Bet On', color='white')
61
- ax.set_ylabel('Return (%)', color='white')
62
-
63
- # Change tick colors to white
64
- ax.tick_params(axis='x', colors='white')
65
- ax.tick_params(axis='y', colors='white')
66
-
67
- # Change axis edge colors
68
- ax.spines['bottom'].set_color('white')
69
- ax.spines['top'].set_color('white')
70
- ax.spines['left'].set_color('white')
71
- ax.spines['right'].set_color('white')
72
-
73
- plt.savefig(f'{model}_dark.png', facecolor='black')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Source/Test/xgboost_ATS_no_odds_55.3%_dark.png DELETED
Binary file (33.2 kB)
 
Source/Test/xgboost_ATS_no_odds_57.3%_dark.png DELETED
Binary file (31.2 kB)
 
Source/Test/xgboost_ML.py DELETED
@@ -1,59 +0,0 @@
1
- import xgboost as xgb
2
- import pandas as pd
3
- import pickle as pkl
4
- import numpy as np
5
- import os
6
-
7
- model = 'xgboost_ML_no_odds_71.4%'
8
-
9
- current_directory = os.path.dirname(os.path.abspath(__file__))
10
- parent_directory = os.path.dirname(current_directory)
11
- data_directory = os.path.join(parent_directory, 'Data')
12
- model_directory = os.path.join(parent_directory, 'Models')
13
- pickle_directory = os.path.join(parent_directory, 'Pickles')
14
-
15
- file_path = os.path.join(model_directory, f'{model}.json')
16
- xgb_ml = xgb.Booster()
17
- xgb_ml.load_model(file_path)
18
-
19
- file_path = os.path.join(pickle_directory, 'test_games_ML_no_odds.pkl')
20
- with open(file_path,'rb') as f:
21
- test_games = pkl.load(f).tolist()
22
-
23
- file_path = os.path.join(data_directory, 'gbg_and_odds.csv')
24
- gbg_and_odds = pd.read_csv(file_path)
25
- test_data = gbg_and_odds.loc[gbg_and_odds['game_id'].isin(test_games)]
26
- test_data_matrix = xgb.DMatrix(test_data.drop(columns=['game_id','Over','Home-Team-Win','Season','home_team','away_team','game_date','Key','Home Score','Away Score','Home Odds Close','Away Odds Close','Home Winnings','Away Winnings','Away Odds','Home Odds']).astype(float).values)
27
-
28
- predicted_probas = xgb_ml.predict(test_data_matrix)
29
- predictions = np.argmax(predicted_probas, axis=1)
30
- test_data['predicted_proba'] = [i[1] for i in predicted_probas]
31
- test_data['prediction'] = (test_data['predicted_proba']>0.5).astype(int)
32
- test_data['correct'] = test_data['Home-Team-Win']==test_data['prediction']
33
-
34
- bets = test_data.loc[(test_data['predicted_proba']>0.6) | (test_data['predicted_proba']<0.4)]
35
- bets['winnings'] = [h if p==1 else a for h,a,p in bets[['Home Winnings','Away Winnings','prediction']].values]
36
-
37
- import matplotlib.pyplot as plt
38
- fig = plt.figure(facecolor='black')
39
- ax = fig.add_subplot(1, 1, 1, facecolor='black')
40
-
41
- # Plot data with line color as RGB(0, 128, 0)
42
- ax.plot(bets['winnings'].cumsum().values*100, linewidth=3, color=(0/255, 128/255, 0/255))
43
-
44
- # Set title and labels
45
- ax.set_title('MARCI 3.0 - MoneyLine w/ 60% Confidence Threshold', color='white')
46
- ax.set_xlabel('Games Bet On', color='white')
47
- ax.set_ylabel('Return (%)', color='white')
48
-
49
- # Change tick colors to white
50
- ax.tick_params(axis='x', colors='white')
51
- ax.tick_params(axis='y', colors='white')
52
-
53
- # Change axis edge colors
54
- ax.spines['bottom'].set_color('white')
55
- ax.spines['top'].set_color('white')
56
- ax.spines['left'].set_color('white')
57
- ax.spines['right'].set_color('white')
58
-
59
- plt.savefig(f'{model}_dark.png', facecolor='black')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Source/Test/xgboost_ML_75.4%.png DELETED
Binary file (35.5 kB)