Spaces:
Running
Running
| from __future__ import annotations | |
| def estimate_win_probability( | |
| score_diff: int, | |
| inning: int, | |
| outs: int, | |
| runner_on_1b: bool, | |
| runner_on_2b: bool, | |
| runner_on_3b: bool, | |
| batting_team_is_home: bool, | |
| ) -> tuple[float, float]: | |
| """ | |
| Simple explainable baseline win probability model. | |
| Returns away_wp, home_wp. | |
| """ | |
| base = 0.50 | |
| # score differential is from away team perspective | |
| base += score_diff * 0.08 | |
| # later innings matter more | |
| leverage = min(0.18, max(0.0, (inning - 1) * 0.02)) | |
| if score_diff > 0: | |
| base += leverage | |
| elif score_diff < 0: | |
| base -= leverage | |
| # base/out pressure | |
| runner_pressure = 0.0 | |
| runner_pressure += 0.03 if runner_on_1b else 0.0 | |
| runner_pressure += 0.05 if runner_on_2b else 0.0 | |
| runner_pressure += 0.07 if runner_on_3b else 0.0 | |
| out_penalty = outs * 0.03 | |
| if batting_team_is_home: | |
| base -= runner_pressure | |
| base += out_penalty * 0.3 | |
| else: | |
| base += runner_pressure | |
| base -= out_penalty * 0.3 | |
| away_wp = max(0.01, min(0.99, base)) | |
| home_wp = max(0.01, min(0.99, 1.0 - away_wp)) | |
| return away_wp, home_wp |