/
minimax_lineup.py
118 lines (112 loc) · 5.09 KB
/
minimax_lineup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import pyfiglet
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style='white')
from collections import defaultdict
import numpy as np
import click
from tabulate import tabulate
import logging
logging.basicConfig()
logging.getLogger().setLevel(logging.INFO)
from nba_matchup import get_league, simulate_h2h, CURRENT_WEEK, hill_climb, visualize_matchup, get_free_agents, simulated_annealing
league = get_league()
def winning_prob(cats, points, scores, num_samples):
unique, nums = np.unique(points, return_counts=True)
counts = defaultdict(int)
counts.update(dict(zip(unique, nums)))
return sum([counts[p] for p in range(5, 10)]) / num_samples
def ev(cats, points, scores, num_samples):
return points.mean()
def print_roster(roster):
print(tabulate([
[position, player.name] for player, position in
roster.positions.items() if position not in {"BN", "IL"}
]))
@click.command()
@click.option('--team1', type=str, default=None)
@click.option('--team2', type=str, default=None)
@click.option('--num_days', type=int, default=14)
@click.option('--num_samples', type=int, default=50000)
@click.option('--week', type=int, default=CURRENT_WEEK)
@click.option('--num_fa', type=int, default=0)
@click.option('--num_minimax', type=int, default=10)
@click.option('--num_iters', type=int, default=100)
@click.option('--ignore_player', type=str, multiple=True)
@click.option('--half_life', type=float, default=14)
@click.option('--metric', type=str, default='winning_probability')
@click.option('--ignore_injured', is_flag=True)
def main(team1, team2, num_days, num_samples, week, num_fa, num_minimax, num_iters,
ignore_player, half_life, metric, ignore_injured):
league = get_league()
decay_rate = np.log(2) / half_life
if team1 is None:
team1 = league.current_team
else:
team1 = league.team_by_owner(team1)
if team2 is None:
team2 = league.get_matchup(team1, week=week)
else:
team2 = league.team_by_owner(team2)
pyfiglet.print_figlet("%s vs. %s" % (team1.manager_name,
team2.manager_name), font='banner',
width=160)
pyfiglet.print_figlet("Week %u" % week, font='big')
if metric == 'ev':
metric_fn = ev
else:
metric_fn = winning_prob
old_team1_roster = team1.roster(week=week)
old_team2_roster = team2.roster(week=week)
def team1_score(roster):
cats, points, scores, _ = simulate_h2h(roster,
team2.roster(week=week),
num_days=num_days, num_samples=num_samples,
week=week, decay_rate=decay_rate)
return metric_fn(cats, points, scores, num_samples)
def team2_score(roster):
cats, points, scores, _ = simulate_h2h(roster,
team1.roster(week=week),
num_days=num_days, num_samples=num_samples,
week=week, decay_rate=decay_rate)
return metric_fn(cats, points, scores, num_samples)
print("%s's roster:" % team1.manager_name, team1_score(old_team1_roster))
print_roster(old_team1_roster)
print("%s's roster:" % team2.manager_name, team2_score(old_team2_roster))
print_roster(old_team2_roster)
print("Adding free agents:")
for agent in get_free_agents(num_fa):
print(agent.name)
old_team1_roster = old_team1_roster.add(agent, "BN")
# old_team2_roster = old_team2_roster.add(agent, "BN")
team1.set_roster(old_team1_roster)
team2.set_roster(old_team2_roster)
print("Ignoring players:", ", ".join(ignore_player))
for i in range(num_minimax):
for team, score_fn in zip([team2, team1], [team2_score, team1_score]):
roster = team.roster(week=week)
print("===========================================")
print("Minimax[%u]: %s" % (i + 1, team.manager_name))
for roster, score in simulated_annealing(roster, score_fn, ignore_players={roster.player_by_name(n) for n in ignore_player},
num_steps=num_iters,
ignore_injured=ignore_injured):
pass
print("%s's optimized roster:" % team.manager_name, score)
print(tabulate([
[position, player.name] for player, position in
roster.positions.items() if position not in {"BN", "IL"}
]))
team.set_roster(roster)
projections = visualize_matchup([team1], team2,
num_days=num_days, num_samples=100000,
week=week, decay_rate=decay_rate,
show_plots=False)
with pd.option_context('display.max_rows', None, 'display.max_columns',
None, 'display.expand_frame_repr', False):
for i, team in enumerate([team1, team2]):
print("===========================================")
print("%s's projections:" % team.manager_name)
print(projections[0][i].round(2))
if __name__ == "__main__":
main()