diff --git a/ipynb/WWW.ipynb b/ipynb/WWW.ipynb
index b222814..f1a6ccd 100644
--- a/ipynb/WWW.ipynb
+++ b/ipynb/WWW.ipynb
@@ -4,136 +4,205 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# WWW: Will the Warriors Win?\n",
+ "# WWW: Who Will Win?\n",
"\n",
- "## 18 April 2016\n",
+ "## 12 April, 2018\n",
"\n",
- "The Golden State Warriors have had a historic basketball season, winning more games than any other team ever has. But will they top that off by winning the championship? There are 15 other teams in contention, including one, the Spurs, that has had a historic season as the best second-best team ever. The web site fivethirtyeight, using a complicated scoring system, [gives](http://projects.fivethirtyeight.com/2016-nba-picks/) the Warriors a 44% chance of winning, with the Spurs at 28%. Basketball-reference [has](http://www.basketball-reference.com/friv/playoff_prob.cgi) the Warriors at 41% and Spurs at 32.5%, while a [betting site](http://www.oddsshark.com/nba/nba-futures) had the Warriors at 54% and Spurs at 18%. But what's a good way to make a prediction? There are several choices:\n",
+ "\"It's tough to make predictions, especially [about](https://en.wikiquote.org/wiki/Yogi_Berra) [the](https://en.wikiquote.org/wiki/Niels_Bohr) future.\" That's true for the **NBA basketball playoffs**, where the Rockets are the favorites, with a 44% chance of winning the title according to [538](https://fivethirtyeight.com/features/the-nba-playoffs-sleepers-favorites-and-best-first-round-matchups/), and 35% according to the Las Vegas oddsmakers, a relatively small difference of opinion. But there are some big discrepancies: the Warriors are tied with the Rockets at 35% according to Vegas, but stand at only 4% according to 538. That 9-fold difference underscores that rational people can use different models with different assumptions and come to different conclusions. Here are some models you might choose:\n",
"\n",
- "- Subjective impression of a team's strength? Or a statistical model?\n",
- "- Predictions based on:\n",
- " - Holistic impression of entire postseason (e.g. \"I think the Warriors have a 50% chance of winning it all\")\n",
- " - Series by series (e.g. \"I think the Warriors have a 95% chance of beating the Rockets in the first round, then ...\")\n",
- " - Game by game (e.g. \"I think the Warriors have a 83% chance of beating the Rockets in Game 1, then ...\")\n",
- " - Possession by possession (e.g. simulate games basket by basket, based on past stats)\n",
- " \n",
- "Here are the top four teams with their Won-Loss percentage and [SRS](http://www.basketball-reference.com/blog/?p=39) (Simple rating system: average margin of victory, adjusted for strength of opponents):\n",
+ "1. **Holistic**: \"I just feel that the Rockets have about a 1/3 chance of winning it all.\"\n",
+ "2. **Game by Game**: \"I think the Rockets have an 75% chance of winning each game in the first round, then 70% in the next round, then 60%; from that I'll calculate their overall chance.\"\n",
+ "3. **Point by Point**: \"The Rockets have a per-game average point differential of 8.2; I'll compare that to the other teams and caclulate their overall chance.\"\n",
"\n",
- " TEAM PCT SRS\n",
- " Warriors .890 10.38\n",
- " Spurs .817 10.28\n",
- " Thunder .671 7.09\n",
- " Cavaliers .695 5.45\n",
+ "# Point by Point Model\n",
"\n",
- "I decided to go with a subjective impression of one team beating another in a single game. For example, I might think that the Warriors have a 58% chance of beating the Cavaliers in any one game, and from that compute the odds of winning a series:"
+ "The [Simple Rating System](https://www.sportingcharts.com/dictionary/nba/simple-rating-system-statistics.aspx) (SRS) records the average point differential of a team over the season, with a slight adjustment for strength of schedule. We can look up the winning percentage and SRS of the top contending teams [here](https://www.basketball-reference.com/leagues/NBA_2018.html): \n",
+ "\n",
+ " TEAM PCT SRS\n",
+ " Rockets .793 8.2\n",
+ " Raptors .720 7.3\n",
+ " Warriors .707 5.8\n",
+ " Sixers .634 4.3\n",
+ " \n",
+ "\n",
+ "The Point-by-Point model of a game is: a game is decided by a random sample from the distribution of point differentials, which is a normal (Gaussian) distribution centered around the recorded differences of the two teams. So, if the Raptors play the Sixers, then the\n",
+ "mean of this distribution is 7.3 - 4.3 = 3.0. We also need to know the standard deviation; [Betlabs](https://www.betlabssports.com/blog/a-look-at-nba-team-totals/) says it\n",
+ "is 10.5 points (and they confirm that scores roughly follow a normal distribution). \n",
+ "The function `simulate` does the calculation:"
]
},
{
"cell_type": "code",
"execution_count": 1,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
- "def win_series(p, W=0, L=0):\n",
- " \"Probability of winning best-of-7 series, given a probability p of winning a game.\"\n",
- " return (1 if W == 4 else\n",
- " 0 if L == 4 else\n",
- " p * win_series(p, W + 1, L) +\n",
- " (1 - p) * win_series(p, W, L + 1))"
+ "from statistics import mean\n",
+ "from random import gauss\n",
+ "\n",
+ "def simulate(diff, 𝝈=10.5, n=10000):\n",
+ " \"Given SRS point differential of two teams, return favored team's win probability.\"\n",
+ " return mean(gauss(diff, 𝝈) > 0 for game in range(n))"
]
},
{
"cell_type": "code",
"execution_count": 2,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "0.6705883933696"
- ]
- },
- "execution_count": 2,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
+ "metadata": {},
+ "outputs": [],
"source": [
- "win_series(0.58)"
+ "simulate(7.3 - 4.3) # Raptors win probability vs Sixers"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "In other words, if you have a 58% chance of winning a game, you have a 67% chance of winning the series.\n",
- "\n",
- "Note that I ignore the fact that games aren't strictly independent; I ignore home court advantage; and I ignore the chance of catastrophic injuries. Why? Because all these factors would change the final winning estimate by only a few percentage points, and I already have more uncertainty than that.\n",
- "\n",
- "Note that `win_series` takes optional arguments to say how many games in the sries have been won and lost so far. Here's a table showing your chance of winning a series, given the current tally of games won and lost on the left, and your expected percentage of winning a game at the top:"
+ "The model says the Raptors have a 61% chance of beating the Sixers in a game. We can make a table of point differentials and game win percentages:"
]
},
{
"cell_type": "code",
"execution_count": 3,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "def percents(items, fmt='{:4.0%}'): return ' '.join(fmt.format(item) for item in items)\n",
- "\n",
- "def series_table(pcts=[p/100 for p in range(20, 81, 5)]):\n",
- " print('W-L | Singe Game Win Percentage')\n",
- " print(' | ' + percents(pcts))\n",
- " for W in range(4):\n",
- " print('----+' + '-' * 5 * len(pcts))\n",
- " for L in reversed(range(4)):\n",
- " results = [win_series(p, W, L) for p in pcts]\n",
- " print('{}-{} | {}'.format(W, L, percents(results)))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "W-L | Singe Game Win Percentage\n",
- " | 20% 25% 30% 35% 40% 45% 50% 55% 60% 65% 70% 75% 80%\n",
- "----+-----------------------------------------------------------------\n",
- "0-3 | 0% 0% 1% 2% 3% 4% 6% 9% 13% 18% 24% 32% 41%\n",
- "0-2 | 1% 2% 3% 5% 9% 13% 19% 26% 34% 43% 53% 63% 74%\n",
- "0-1 | 2% 4% 7% 12% 18% 26% 34% 44% 54% 65% 74% 83% 90%\n",
- "0-0 | 3% 7% 13% 20% 29% 39% 50% 61% 71% 80% 87% 93% 97%\n",
- "----+-----------------------------------------------------------------\n",
- "1-3 | 1% 2% 3% 4% 6% 9% 12% 17% 22% 27% 34% 42% 51%\n",
- "1-2 | 3% 5% 8% 13% 18% 24% 31% 39% 48% 56% 65% 74% 82%\n",
- "1-1 | 6% 10% 16% 24% 32% 41% 50% 59% 68% 76% 84% 90% 94%\n",
- "1-0 | 10% 17% 26% 35% 46% 56% 66% 74% 82% 88% 93% 96% 98%\n",
- "----+-----------------------------------------------------------------\n",
- "2-3 | 4% 6% 9% 12% 16% 20% 25% 30% 36% 42% 49% 56% 64%\n",
- "2-2 | 10% 16% 22% 28% 35% 43% 50% 57% 65% 72% 78% 84% 90%\n",
- "2-1 | 18% 26% 35% 44% 52% 61% 69% 76% 82% 87% 92% 95% 97%\n",
- "2-0 | 26% 37% 47% 57% 66% 74% 81% 87% 91% 95% 97% 98% 99%\n",
- "----+-----------------------------------------------------------------\n",
- "3-3 | 20% 25% 30% 35% 40% 45% 50% 55% 60% 65% 70% 75% 80%\n",
- "3-2 | 36% 44% 51% 58% 64% 70% 75% 80% 84% 88% 91% 94% 96%\n",
- "3-1 | 49% 58% 66% 73% 78% 83% 88% 91% 94% 96% 97% 98% 99%\n",
- "3-0 | 59% 68% 76% 82% 87% 91% 94% 96% 97% 98% 99% 100% 100%\n"
+ "0 point differential = 51% win game\n",
+ "1 point differential = 53% win game\n",
+ "2 point differential = 58% win game\n",
+ "3 point differential = 61% win game\n",
+ "4 point differential = 66% win game\n",
+ "5 point differential = 68% win game\n",
+ "6 point differential = 72% win game\n",
+ "7 point differential = 75% win game\n",
+ "8 point differential = 78% win game\n",
+ "9 point differential = 80% win game\n"
]
}
],
"source": [
+ "pct = '{:4.0%}'.format \n",
+ "\n",
+ "for diff in range(10):\n",
+ " print(diff, 'point differential =', pct(simulate(diff)), 'win game')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "This agrees very well with the \"Differential vs. Win Percentage\" [chart](http://a.espncdn.com/combiner/i?img=%2Fphoto%2F2018%2F0408%2F180408_differential.png&w=1140&cquality=40) on [this page](http://www.espn.com/nba/story/_/id/23071005/kevin-pelton-weekly-mailbag-including-nba-all-offensive-teams).\n",
+ "\n",
+ "# Game by Game Model\n",
+ "\n",
+ "The next model says that a playoff series is a sequence of independent and identically distributed game results (where the probability of a single-game win is specified either using point differential, or holistically). The idea here is to be consistent: if you believe that a team's win percentage is 60%, and you believe that games are independent, then you must believe that the team's chance of wining 4 in a row is 0.64 = 0.1296.\n",
+ "\n",
+ "The function `win_series` calculates the probability of winning a series, given the probability of winning a game:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def win_series(p, W=0, L=0):\n",
+ " \"\"\"Probability of winning best-of-7 series, given a probability p of winning a game.\n",
+ " The optional arguments say how many Wins and Losses the team has in the series so far.\"\"\"\n",
+ " return (1 if W == 4 else\n",
+ " 0 if L == 4 else\n",
+ " p * win_series(p, W + 1, L) + (1 - p) * win_series(p, W, L + 1))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can make another table:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "% win game = 50.0% win series\n",
+ "% win game = 60.8% win series\n",
+ "% win game = 71.0% win series\n",
+ "% win game = 80.0% win series\n",
+ "% win game = 87.4% win series\n",
+ "% win game = 92.9% win series\n",
+ "% win game = 96.7% win series\n",
+ "% win game = 98.8% win series\n",
+ "% win game = 99.7% win series\n"
+ ]
+ }
+ ],
+ "source": [
+ "for p in range(50, 95, 5):\n",
+ " print(format('{}% win game = {:5.1%} win series'.format(pct, win_series(p/100))))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "For example, if a team has a 60% chance of winning each game, then it has an 71% chance of winning the series. This model ignores the fact that games aren't strictly independent, and ignores home court advantage. Why? Because these factors would change the final winning estimate by only a few percentage points, and I already have more uncertainty than that. \n",
+ "\n",
+ "What happens if some games in a series have already been played? The following function prints a table where each row tells a team's current win-loss record, each column is the game win percentage, and each entry in the table is the series win percentage."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "W-L | Game Win Percentage\n",
+ " | 20% 25% 30% 35% 40% 45% 50% 55% 60% 65% 70% 75% 80%\n",
+ "----+-----------------------------------------------------------------\n",
+ "0-0 | 3% 7% 13% 20% 29% 39% 50% 61% 71% 80% 87% 93% 97%\n",
+ "0-1 | 2% 4% 7% 12% 18% 26% 34% 44% 54% 65% 74% 83% 90%\n",
+ "0-2 | 1% 2% 3% 5% 9% 13% 19% 26% 34% 43% 53% 63% 74%\n",
+ "0-3 | 0% 0% 1% 2% 3% 4% 6% 9% 13% 18% 24% 32% 41%\n",
+ "----+-----------------------------------------------------------------\n",
+ "1-0 | 10% 17% 26% 35% 46% 56% 66% 74% 82% 88% 93% 96% 98%\n",
+ "1-1 | 6% 10% 16% 24% 32% 41% 50% 59% 68% 76% 84% 90% 94%\n",
+ "1-2 | 3% 5% 8% 13% 18% 24% 31% 39% 48% 56% 65% 74% 82%\n",
+ "1-3 | 1% 2% 3% 4% 6% 9% 12% 17% 22% 27% 34% 42% 51%\n",
+ "----+-----------------------------------------------------------------\n",
+ "2-0 | 26% 37% 47% 57% 66% 74% 81% 87% 91% 95% 97% 98% 99%\n",
+ "2-1 | 18% 26% 35% 44% 52% 61% 69% 76% 82% 87% 92% 95% 97%\n",
+ "2-2 | 10% 16% 22% 28% 35% 43% 50% 57% 65% 72% 78% 84% 90%\n",
+ "2-3 | 4% 6% 9% 12% 16% 20% 25% 30% 36% 42% 49% 56% 64%\n",
+ "----+-----------------------------------------------------------------\n",
+ "3-0 | 59% 68% 76% 82% 87% 91% 94% 96% 97% 98% 99% 100% 100%\n",
+ "3-1 | 49% 58% 66% 73% 78% 83% 88% 91% 94% 96% 97% 98% 99%\n",
+ "3-2 | 36% 44% 51% 58% 64% 70% 75% 80% 84% 88% 91% 94% 96%\n",
+ "3-3 | 20% 25% 30% 35% 40% 45% 50% 55% 60% 65% 70% 75% 80%\n"
+ ]
+ }
+ ],
+ "source": [
+ "def series_table(pcts=[p/100 for p in range(20, 85, 5)]):\n",
+ " print('W-L | Game Win Percentage')\n",
+ " print(' | ' + ' '.join(map(pct, pcts)))\n",
+ " for W in range(4):\n",
+ " print('----+' + '-' * 5 * len(pcts))\n",
+ " for L in range(4):\n",
+ " results = [win_series(p, W, L) for p in pcts]\n",
+ " print('{}-{} | {}'.format(W, L, ' '.join(map(pct, results))))\n",
+ "\n",
"series_table()"
]
},
@@ -141,121 +210,243 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "And here's a function to tabulate the chances of winning each series on the way to a title:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def playoffs(name, rounds):\n",
- " \"Print probability for team winning each series.\"\n",
- " overall = (1, 1, 1) # (lo, med, hi) probabilities of winning it all\n",
- " for (opponent, probs) in rounds:\n",
- " this_round = [win_series(p) for p in probs]\n",
- " overall = [overall[i] * this_round[i] for i in range(len(probs))]\n",
- " print('{} vs {:8} win this round: {}; win through here: {}'.format(\n",
- " name, opponent, percents(this_round), percents(overall)))"
+ "For example, if our team with a 60% win percentage loses the first game of the series, then check the \"0-1\" row and the \"60%\" column to see that it still has a 54% chance of winning the series. You also have the option of updating your prior probability. Suppose after seeing our 60% team lose the first game you decide \"perhaps I was wrong about them; perhaps they're actually a 55% team\". Then you would look at the 55% column of the 0-1 row and find that their chances have slipped to 44%."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "Now I enter my subjective probability estimates (low, medium, and high), and likely opponents for each round, for the three top contenders:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Warriors vs Rockets win this round: 93% 98% 99%; win through here: 93% 98% 99%\n",
- "Warriors vs Clippers win this round: 83% 91% 97%; win through here: 77% 89% 95%\n",
- "Warriors vs Spurs win this round: 39% 67% 87%; win through here: 30% 60% 83%\n",
- "Warriors vs Cavs win this round: 71% 83% 93%; win through here: 22% 50% 78%\n"
- ]
- }
- ],
- "source": [
- "playoffs('Warriors',\n",
- " [('Rockets', (0.75, 0.83, 0.85)),\n",
- " ('Clippers', (0.67, 0.73, 0.80)),\n",
- " ('Spurs', (0.45, 0.58, 0.70)),\n",
- " ('Cavs', (0.60, 0.67, 0.75))])"
+ "# Series by Series Model\n",
+ "\n",
+ "Here's a function to tabulate a team's chance of winning each series on the way to a title. The first argument is the team's name, and the second, `rounds` is a list of playoff round entries, where each entry is a tuple of the (expected) opponent team name, the game win percentage against this team, and optionally the wins and losses in the series so far:"
]
},
{
"cell_type": "code",
"execution_count": 7,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Spurs vs Memphis win this round: 93% 98% 99%; win through here: 93% 98% 99%\n",
- "Spurs vs Thunder win this round: 39% 75% 87%; win through here: 36% 73% 86%\n",
- "Spurs vs Warriors win this round: 13% 33% 61%; win through here: 5% 24% 53%\n",
- "Spurs vs Cavs win this round: 71% 83% 93%; win through here: 3% 20% 49%\n"
- ]
- }
- ],
+ "metadata": {},
+ "outputs": [],
"source": [
- "playoffs('Spurs',\n",
- " [('Memphis', (0.75, 0.83, 0.85)),\n",
- " ('Thunder', (0.45, 0.62, 0.70)),\n",
- " ('Warriors', (0.30, 0.42, 0.55)),\n",
- " ('Cavs', (0.60, 0.67, 0.75))])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Cavs vs Pistons win this round: 93% 98% 99%; win through here: 93% 98% 99%\n",
- "Cavs vs Hawks win this round: 39% 71% 93%; win through here: 36% 70% 92%\n",
- "Cavs vs Raptors win this round: 29% 61% 80%; win through here: 11% 42% 73%\n",
- "Cavs vs GSW/SAS win this round: 7% 17% 29%; win through here: 1% 7% 21%\n"
- ]
- }
- ],
- "source": [
- "playoffs('Cavs',\n",
- " [('Pistons', (0.75, 0.83, 0.85)),\n",
- " ('Hawks', (0.45, 0.60, 0.75)),\n",
- " ('Raptors', (0.40, 0.55, 0.65)),\n",
- " ('GSW/SAS', (0.25, 0.33, 0.40))])"
+ "def playoffs(name, rounds):\n",
+ " \"Print probability for team winning each series.\"\n",
+ " overall = 1.0 \n",
+ " for (opponent, p, *WL) in rounds:\n",
+ " this_round = win_series(p, *WL)\n",
+ " overall *= this_round\n",
+ " print('{} vs {:8} {}; through here: {}'\n",
+ " .format(name, opponent, pct(this_round), pct(overall)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "I have the Warriors at 50% (for the medium estimate of winning it all) and the Spurs at 20%, so I'm more of a Warriors fan than fivethirtyeight and basketball-reference, but I have very wide margins between my low and high estimate: 22% to 78% for the Warriors; 3% to 49% for the Spurs; 1% to 21% for the Cavs. Interestingly, while fivethirtyeight does not think this year's Warriors are better than the 1995 Bulls, they [do think](http://fivethirtyeight.com/features/the-warriors-still-arent-the-best-team-ever/) the Spurs, Thunder, and Cavs are the best ever second-, third-, and fourth-best teams in a season.\n",
+ "Here my holistic game estimates are turned into overall predictions:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Rockets vs Wolves 93%; through here: 93%\n",
+ "Rockets vs Jazz 87%; through here: 81%\n",
+ "Rockets vs Warriors 71%; through here: 58%\n",
+ "Rockets vs Raptors 71%; through here: 41%\n"
+ ]
+ }
+ ],
+ "source": [
+ "playoffs('Rockets',\n",
+ " [('Wolves', 0.75),\n",
+ " ('Jazz', 0.70),\n",
+ " ('Warriors', 0.60),\n",
+ " ('Raptors', 0.60)])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "So I'm in good agreement with [538](https://fivethirtyeight.com/features/the-nba-playoffs-sleepers-favorites-and-best-first-round-matchups/): I have the Rockets at 58% winning the conference and 41% winning the title, while 538 had them at 57% and 44%.\n",
+ "\n",
+ "What if I went by point differential?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Rockets vs Wolves 88%; through here: 88%\n",
+ "Rockets vs Jazz 79%; through here: 69%\n",
+ "Rockets vs Warriors 70%; through here: 49%\n",
+ "Rockets vs Raptors 58%; through here: 28%\n"
+ ]
+ }
+ ],
+ "source": [
+ "playoffs('Rockets',\n",
+ " [('Wolves', simulate(8.2 - 2.3)),\n",
+ " ('Jazz', simulate(8.2 - 4.5)),\n",
+ " ('Warriors', simulate(8.2 - 5.8)),\n",
+ " ('Raptors', simulate(8.2 - 7.3))])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "This puts the Rockets at 48% and 28%, which is closer to the Vegas odds of 44% and 35%. How do I reconcile this discrepancy? I guess I would say that I don't have much faith in the point differential model, because it places too much emphasis on meaningless scores: for example, in the Warriors' final game, it was to their strategic advantage to lose, and they did—by 40 points, which dropped their average differential for the entire year by 0.5 points.\n",
+ "\n",
+ "Here are my projections for the hometown Warriors:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Warriors vs Spurs 87%; through here: 87%\n",
+ "Warriors vs Portland 80%; through here: 70%\n",
+ "Warriors vs Rockets 29%; through here: 20%\n",
+ "Warriors vs Raptors 61%; through here: 12%\n"
+ ]
+ }
+ ],
+ "source": [
+ "playoffs('Warriors',\n",
+ " [('Spurs', 0.70),\n",
+ " ('Portland', 0.65),\n",
+ " ('Rockets', 0.40),\n",
+ " ('Raptors', 0.55)])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "So I'm splitting the difference between 538's low estimate and Vegas's high estimate of the Warriors chances.\n",
+ "\n",
+ "---"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 2016 NBA Playoffs\n",
"\n",
"\n",
+ "An historical record of the 2016 playoffs.\n",
"\n",
- "What's better--a holistic guess at the outcome, or a reductionist model like this one? I can't say that one is better than the other in every case, but it can be instructive to examine the cases where the reductionist model differs from your holistic impressions. For example, look at the low end of my prediction for the Spurs. I feel like it is crazy to say the Spurs only have a 3% chance of winning the title, but I don't feel that any of the individual game win probabilities (75%, 45%, 30%, and 60%, respectively) are crazy. So now I know that at least one of my intutions is wrong. But I'm not sure how to reconcile the mismatch..."
+ "## 18 April 2016\n",
+ "\n",
+ "The Golden State Warriors have had a historic basketball season, winning more games than any other team ever has. But will they top that off by winning the championship? There are 15 other teams in contention, including one, the Spurs, that has had a historic season as the best second-best team ever. The web site fivethirtyeight, using a complicated scoring system, [gives](http://projects.fivethirtyeight.com/2016-nba-picks/) the Warriors a 44% chance of winning, with the Spurs at 28%. Basketball-reference [has](http://www.basketball-reference.com/friv/playoff_prob.cgi) the Warriors at 41% and Spurs at 32.5%, while a [betting site](http://www.oddsshark.com/nba/nba-futures) had the Warriors at 54% and Spurs at 18%. \n",
+ " \n",
+ "Here are the top four teams with their stats:\n",
+ "\n",
+ " TEAM PCT SRS\n",
+ " Warriors .890 10.38\n",
+ " Spurs .817 10.28\n",
+ " Thunder .671 7.09\n",
+ " Cavaliers .695 5.45\n",
+ "\n",
+ "I came up with my own subjective game winning percentages, informed by SRS calculations, plus injury status, etc."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Warriors vs Rockets 98%; through here: 98%\n",
+ "Warriors vs Clippers 91%; through here: 89%\n",
+ "Warriors vs Spurs 67%; through here: 60%\n",
+ "Warriors vs Cavs 83%; through here: 50%\n"
+ ]
+ }
+ ],
+ "source": [
+ "playoffs('Warriors',\n",
+ " [('Rockets', 0.83),\n",
+ " ('Clippers', 0.73),\n",
+ " ('Spurs', 0.58),\n",
+ " ('Cavs', 0.67)])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Spurs vs Memphis 98%; through here: 98%\n",
+ "Spurs vs Thunder 75%; through here: 73%\n",
+ "Spurs vs Warriors 33%; through here: 24%\n",
+ "Spurs vs Cavs 83%; through here: 20%\n"
+ ]
+ }
+ ],
+ "source": [
+ "playoffs('Spurs',\n",
+ " [('Memphis', 0.83),\n",
+ " ('Thunder', 0.62),\n",
+ " ('Warriors', 0.42),\n",
+ " ('Cavs', 0.67)])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Cavs vs Pistons 98%; through here: 98%\n",
+ "Cavs vs Hawks 71%; through here: 70%\n",
+ "Cavs vs Raptors 61%; through here: 42%\n",
+ "Cavs vs GSW/SAS 17%; through here: 7%\n"
+ ]
+ }
+ ],
+ "source": [
+ "playoffs('Cavs',\n",
+ " [('Pistons', 0.83),\n",
+ " ('Hawks', 0.60),\n",
+ " ('Raptors', 0.55),\n",
+ " ('GSW/SAS', 0.33)])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "I have the Warriors at 50% (for the estimate of winning it all) and the Spurs at 20%, so I'm more of a Warriors fan than fivethirtyeight and basketball-reference. Interestingly, while fivethirtyeight does not think this year's Warriors are better than the 1995 Bulls, they [do think](http://fivethirtyeight.com/features/the-warriors-still-arent-the-best-team-ever/) the Spurs, Thunder, and Cavs are the best ever second-, third-, and fourth-best teams in a season."
]
},
{
@@ -268,58 +459,31 @@
"\n",
"The Playoff picture has changed! \n",
"\n",
- "We have some results for first-round series, and there have been key injuries to players including Steph Curry, Avery Bradley, Chris Paul, and Blake Griffin. To update, first I make a small alteration to allow the current state of a series in terms of wins/loses to be specified as part of the input to `playoffs`:"
+ "We have some results for first-round series, and there have been key injuries to players including Steph Curry, Avery Bradley, Chris Paul, and Blake Griffin. We don't know for sure how long Curry will be out, but here are my updated odds for the Warriors, under the assumption that Curry misses the second round, and comes back in time for the Western Conference Finals at a mildly reduced capacity:"
]
},
{
"cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def playoffs(name, rounds):\n",
- " \"Print probability for team winning each series.\"\n",
- " overall = (1, 1, 1) # (lo, med, hi) probabilities of winning it all\n",
- " for (opponent, probs, *args) in rounds:\n",
- " this_round = [win_series(p, *args) for p in probs]\n",
- " overall = [overall[i] * this_round[i] for i in range(len(probs))]\n",
- " print('{} vs {:8} win this round: ({}) win through here: ({})'.format(\n",
- " name, opponent, percents(this_round), percents(overall)))"
- ]
- },
- {
- "cell_type": "markdown",
+ "execution_count": 14,
"metadata": {},
- "source": [
- "We don't know for sure how long Curry will be out, but here are my updated odds for the Warriors, with the middle probability value representing the assumption that Curry misses the second round, and comes back in time for the Western Conference Finals at a mildly reduced capacity; the low and high probability values represent more and less severe injuries:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "collapsed": false
- },
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Warriors vs Rockets win this round: ( 88% 97% 99%) win through here: ( 88% 97% 99%)\n",
- "Warriors vs Blazers win this round: ( 39% 61% 83%) win through here: ( 34% 59% 83%)\n",
- "Warriors vs Spurs win this round: ( 13% 61% 83%) win through here: ( 4% 36% 69%)\n",
- "Warriors vs Cavs win this round: ( 29% 71% 87%) win through here: ( 1% 26% 60%)\n"
+ "Warriors vs Rockets 97%; through here: 97%\n",
+ "Warriors vs Blazers 61%; through here: 59%\n",
+ "Warriors vs Spurs 61%; through here: 36%\n",
+ "Warriors vs Cavs 71%; through here: 26%\n"
]
}
],
"source": [
"playoffs('Warriors',\n",
- " [('Rockets', (0.50, 0.70, 0.80), 3, 1),\n",
- " ('Blazers', (0.45, 0.55, 0.67)),\n",
- " ('Spurs', (0.30, 0.55, 0.67)),\n",
- " ('Cavs', (0.40, 0.60, 0.70))])"
+ " [('Rockets', 0.70, 3, 1),\n",
+ " ('Blazers', 0.55),\n",
+ " ('Spurs', 0.55),\n",
+ " ('Cavs', 0.60)])"
]
},
{
@@ -331,54 +495,50 @@
},
{
"cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": false
- },
+ "execution_count": 15,
+ "metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Spurs vs Memphis win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Spurs vs Thunder win this round: ( 39% 75% 87%) win through here: ( 39% 75% 87%)\n",
- "Spurs vs Warriors win this round: ( 17% 39% 87%) win through here: ( 7% 29% 76%)\n",
- "Spurs vs Cavs win this round: ( 71% 83% 93%) win through here: ( 5% 24% 71%)\n"
+ "Spurs vs Memphis 100%; through here: 100%\n",
+ "Spurs vs Thunder 75%; through here: 75%\n",
+ "Spurs vs Warriors 39%; through here: 29%\n",
+ "Spurs vs Cavs 83%; through here: 24%\n"
]
}
],
"source": [
"playoffs('Spurs',\n",
- " [('Memphis', (0.75, 0.83, 0.85), 4, 0),\n",
- " ('Thunder', (0.45, 0.62, 0.70)),\n",
- " ('Warriors', (0.33, 0.45, 0.70)),\n",
- " ('Cavs', (0.60, 0.67, 0.75))])"
+ " [('Memphis', 0.83, 4, 0),\n",
+ " ('Thunder', 0.62),\n",
+ " ('Warriors', 0.45),\n",
+ " ('Cavs', 0.67)])"
]
},
{
"cell_type": "code",
- "execution_count": 12,
- "metadata": {
- "collapsed": false
- },
+ "execution_count": 16,
+ "metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Cavs vs Pistons win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Cavs vs Hawks win this round: ( 39% 71% 93%) win through here: ( 39% 71% 93%)\n",
- "Cavs vs Raptors win this round: ( 29% 61% 80%) win through here: ( 11% 43% 74%)\n",
- "Cavs vs GSW/SAS win this round: ( 13% 29% 71%) win through here: ( 1% 13% 53%)\n"
+ "Cavs vs Pistons 100%; through here: 100%\n",
+ "Cavs vs Hawks 71%; through here: 71%\n",
+ "Cavs vs Raptors 61%; through here: 43%\n",
+ "Cavs vs GSW/SAS 29%; through here: 13%\n"
]
}
],
"source": [
"playoffs('Cavs',\n",
- " [('Pistons', (0.75, 0.83, 0.85), 4, 0),\n",
- " ('Hawks', (0.45, 0.60, 0.75)),\n",
- " ('Raptors', (0.40, 0.55, 0.65)),\n",
- " ('GSW/SAS', (0.30, 0.40, 0.60))])"
+ " [('Pistons', 0.83, 4, 0),\n",
+ " ('Hawks', 0.60),\n",
+ " ('Raptors', 0.55),\n",
+ " ('GSW/SAS', 0.40)])"
]
},
{
@@ -402,106 +562,98 @@
},
{
"cell_type": "code",
- "execution_count": 13,
- "metadata": {
- "collapsed": false
- },
+ "execution_count": 17,
+ "metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Warriors vs Rockets win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Warriors vs Blazers win this round: ( 91% 96% 98%) win through here: ( 91% 96% 98%)\n",
- "Warriors vs Spurs win this round: ( 39% 71% 83%) win through here: ( 36% 68% 82%)\n",
- "Warriors vs Cavs win this round: ( 29% 61% 83%) win through here: ( 10% 42% 68%)\n"
+ "Warriors vs Rockets 100%; through here: 100%\n",
+ "Warriors vs Blazers 96%; through here: 96%\n",
+ "Warriors vs Spurs 71%; through here: 68%\n",
+ "Warriors vs Cavs 61%; through here: 42%\n"
]
}
],
"source": [
"playoffs('Warriors',\n",
- " [('Rockets', (0.50, 0.70, 0.80), 4, 1),\n",
- " ('Blazers', (0.55, 0.67, 0.75), 3, 1),\n",
- " ('Spurs', (0.45, 0.60, 0.67)),\n",
- " ('Cavs', (0.40, 0.55, 0.67))])"
+ " [('Rockets', 0.70, 4, 1),\n",
+ " ('Blazers', 0.67, 3, 1),\n",
+ " ('Spurs', 0.60),\n",
+ " ('Cavs', 0.55)])"
]
},
{
"cell_type": "code",
- "execution_count": 14,
- "metadata": {
- "collapsed": false
- },
+ "execution_count": 18,
+ "metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Spurs vs Memphis win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Spurs vs Thunder win this round: ( 16% 36% 49%) win through here: ( 16% 36% 49%)\n",
- "Spurs vs Warriors win this round: ( 17% 29% 61%) win through here: ( 3% 10% 30%)\n",
- "Spurs vs Cavs win this round: ( 29% 50% 87%) win through here: ( 1% 5% 26%)\n"
+ "Spurs vs Memphis 100%; through here: 100%\n",
+ "Spurs vs Thunder 36%; through here: 36%\n",
+ "Spurs vs Warriors 29%; through here: 10%\n",
+ "Spurs vs Cavs 50%; through here: 5%\n"
]
}
],
"source": [
"playoffs('Spurs',\n",
- " [('Memphis', (0.75, 0.83, 0.85), 4, 0),\n",
- " ('Thunder', (0.40, 0.60, 0.70), 2, 3),\n",
- " ('Warriors', (0.33, 0.40, 0.55)),\n",
- " ('Cavs', (0.40, 0.50, 0.70))])"
+ " [('Memphis', 0.83, 4, 0),\n",
+ " ('Thunder', 0.60, 2, 3),\n",
+ " ('Warriors', 0.40),\n",
+ " ('Cavs', 0.50)])"
]
},
{
"cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "collapsed": false
- },
+ "execution_count": 19,
+ "metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Thunder vs Dallas win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Thunder vs Spurs win this round: ( 51% 64% 84%) win through here: ( 51% 64% 84%)\n",
- "Thunder vs Warriors win this round: ( 17% 29% 61%) win through here: ( 9% 19% 51%)\n",
- "Thunder vs Cavs win this round: ( 20% 39% 71%) win through here: ( 2% 7% 36%)\n"
+ "Thunder vs Dallas 100%; through here: 100%\n",
+ "Thunder vs Spurs 64%; through here: 64%\n",
+ "Thunder vs Warriors 29%; through here: 19%\n",
+ "Thunder vs Cavs 39%; through here: 7%\n"
]
}
],
"source": [
"playoffs('Thunder',\n",
- " [('Dallas', (0.75, 0.83, 0.85), 4, 1),\n",
- " ('Spurs', (0.30, 0.40, 0.60), 3, 2),\n",
- " ('Warriors', (0.33, 0.40, 0.55)),\n",
- " ('Cavs', (0.35, 0.45, 0.60))])"
+ " [('Dallas', 0.83, 4, 1),\n",
+ " ('Spurs', 0.40, 3, 2),\n",
+ " ('Warriors', 0.40),\n",
+ " ('Cavs', 0.45)])"
]
},
{
"cell_type": "code",
- "execution_count": 16,
- "metadata": {
- "collapsed": false
- },
+ "execution_count": 20,
+ "metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Cavs vs Pistons win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Cavs vs Hawks win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Cavs vs Raptors win this round: ( 50% 80% 93%) win through here: ( 50% 80% 93%)\n",
- "Cavs vs GS/SA/OK win this round: ( 17% 39% 61%) win through here: ( 8% 31% 57%)\n"
+ "Cavs vs Pistons 100%; through here: 100%\n",
+ "Cavs vs Hawks 100%; through here: 100%\n",
+ "Cavs vs Raptors 80%; through here: 80%\n",
+ "Cavs vs GS/SA/OK 39%; through here: 31%\n"
]
}
],
"source": [
"playoffs('Cavs',\n",
- " [('Pistons', (0.75, 0.83, 0.85), 4, 0),\n",
- " ('Hawks', (0.45, 0.60, 0.75), 4, 0),\n",
- " ('Raptors', (0.50, 0.65, 0.75)),\n",
- " ('GS/SA/OK', (0.33, 0.45, 0.55))])"
+ " [('Pistons', 0.83, 4, 0),\n",
+ " ('Hawks', 0.60, 4, 0),\n",
+ " ('Raptors', 0.65),\n",
+ " ('GS/SA/OK', 0.45)])"
]
},
{
@@ -515,104 +667,37 @@
"- **Thunder:** Increased to 7%.\n",
"- **Cavs:** Increased to 31%.\n",
"\n",
- "# Time to Panic?\n",
+ "# Time to Panic Yet?\n",
"\n",
"## 17 May 2016\n",
"\n",
- "The Thunder finished off the Spurs and beat the Warriors in game 1. Are the Thunder, like the Cavs, peaking at just the right time, after an inconsistent regular season? Is it time for Warriors fans to panic?\n",
+ "The Thunder finished off the Spurs and beat the Warriors in game 1. Are the Thunder, like the Cavs, peaking at just the right time, after an inconsistant regular season? Is it time for Warriors fans to panic?\n",
"\n",
"Sure, the Warriors were down a game twice in last year's playoffs and came back to win both times. Sure, the Warriors are still 3-1 against the Thunder this year, and only lost two games all season to elite teams (Spurs, Thunder, Cavs, Clippers, Raptors). But the Thunder are playing at a top level. Here's my update, showing that the loss cost the Warriors 5%:"
]
},
{
"cell_type": "code",
- "execution_count": 17,
- "metadata": {
- "collapsed": false
- },
+ "execution_count": 21,
+ "metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Warriors vs Rockets win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Warriors vs Blazers win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Warriors vs Thunder win this round: ( 26% 61% 74%) win through here: ( 26% 61% 74%)\n",
- "Warriors vs Cavs win this round: ( 29% 61% 80%) win through here: ( 7% 37% 60%)\n"
+ "Warriors vs Rockets 100%; through here: 100%\n",
+ "Warriors vs Blazers 100%; through here: 100%\n",
+ "Warriors vs Thunder 61%; through here: 61%\n",
+ "Warriors vs Cavs 61%; through here: 37%\n"
]
}
],
"source": [
"playoffs('Warriors',\n",
- " [('Rockets', (0.50, 0.70, 0.80), 4, 1),\n",
- " ('Blazers', (0.55, 0.67, 0.75), 4, 1),\n",
- " ('Thunder', (0.45, 0.63, 0.70), 0, 1),\n",
- " ('Cavs', (0.40, 0.55, 0.65))])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "# Not Yet?\n",
- "\n",
- "## 18 May 2016\n",
- "\n",
- "The Warriors won game two of the series, so now they're back up to 45%, with the Cavs at 35%. At this time, [fivethirtyeight](http://projects.fivethirtyeight.com/2016-nba-picks/) has the Warriors at 45%, Cavs at 28% and Thunder at 24%"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Warriors vs Rockets win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Warriors vs Blazers win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Warriors vs Thunder win this round: ( 41% 73% 84%) win through here: ( 41% 73% 84%)\n",
- "Warriors vs Cavs win this round: ( 29% 61% 80%) win through here: ( 12% 45% 67%)\n"
- ]
- }
- ],
- "source": [
- "playoffs('Warriors',\n",
- " [('Rockets', (0.50, 0.70, 0.80), 4, 1),\n",
- " ('Blazers', (0.55, 0.67, 0.75), 4, 1),\n",
- " ('Thunder', (0.45, 0.63, 0.70), 1, 1),\n",
- " ('Cavs', (0.40, 0.55, 0.65))])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Cavs vs Pistons win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Cavs vs Hawks win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Cavs vs Raptors win this round: ( 66% 88% 96%) win through here: ( 66% 88% 96%)\n",
- "Cavs vs GSW win this round: ( 20% 39% 71%) win through here: ( 13% 35% 68%)\n"
- ]
- }
- ],
- "source": [
- "playoffs('Cavs',\n",
- " [('Pistons', (0.75, 0.83, 0.85), 4, 0),\n",
- " ('Hawks', (0.45, 0.60, 0.75), 4, 0),\n",
- " ('Raptors', (0.50, 0.65, 0.75), 1, 0),\n",
- " ('GSW', (0.35, 0.45, 0.60))])"
+ " [('Rockets', 0.70, 4, 1),\n",
+ " ('Blazers', 0.67, 4, 1),\n",
+ " ('Thunder', 0.63, 0, 1),\n",
+ " ('Cavs', 0.55)])"
]
},
{
@@ -628,169 +713,74 @@
},
{
"cell_type": "code",
- "execution_count": 20,
- "metadata": {
- "collapsed": false
- },
+ "execution_count": 22,
+ "metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Warriors vs Rockets win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Warriors vs Blazers win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Warriors vs Thunder win this round: ( 2% 17% 27%) win through here: ( 2% 17% 27%)\n",
- "Warriors vs Cavs win this round: ( 29% 61% 80%) win through here: ( 0% 10% 22%)\n"
+ "Warriors vs Rockets 100%; through here: 100%\n",
+ "Warriors vs Blazers 100%; through here: 100%\n",
+ "Warriors vs Thunder 17%; through here: 17%\n",
+ "Warriors vs Cavs 61%; through here: 10%\n"
]
}
],
"source": [
"playoffs('Warriors',\n",
- " [('Rockets', (0.50, 0.70, 0.80), 4, 1),\n",
- " ('Blazers', (0.55, 0.67, 0.75), 4, 1),\n",
- " ('Thunder', (0.25, 0.55, 0.65), 1, 3),\n",
- " ('Cavs', (0.40, 0.55, 0.65))])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Cavs vs Pistons win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Cavs vs Hawks win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Cavs vs Raptors win this round: ( 50% 57% 78%) win through here: ( 50% 57% 78%)\n",
- "Cavs vs Thunder win this round: ( 20% 39% 71%) win through here: ( 10% 23% 56%)\n"
- ]
- }
- ],
- "source": [
- "playoffs('Cavs',\n",
- " [('Pistons', (0.75, 0.83, 0.85), 4, 0),\n",
- " ('Hawks', (0.45, 0.60, 0.75), 4, 0),\n",
- " ('Raptors', (0.50, 0.55, 0.70), 2, 2),\n",
- " ('Thunder', (0.35, 0.45, 0.60))])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Thunder vs Dallas win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Thunder vs Spurs win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Thunder vs Warriors win this round: ( 73% 83% 98%) win through here: ( 73% 83% 98%)\n",
- "Thunder vs Cavs win this round: ( 29% 61% 80%) win through here: ( 21% 51% 79%)\n"
- ]
- }
- ],
- "source": [
- "playoffs('Thunder',\n",
- " [('Dallas', (0.75, 0.83, 0.85), 4, 1),\n",
- " ('Spurs', (0.30, 0.40, 0.60), 4, 2),\n",
- " ('Warriors', (0.35, 0.45, 0.75), 3, 1),\n",
- " ('Cavs', (0.40, 0.55, 0.65))])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# But Not Done Yet\n",
- "\n",
- "## 26 May 2016\n",
- "\n",
- "The Warriors won game 5, bringing them up from a 10% to an 18% chance of winning it all:"
+ " [('Rockets', 0.70, 4, 1),\n",
+ " ('Blazers', 0.67, 4, 1),\n",
+ " ('Thunder', 0.55, 1, 3),\n",
+ " ('Cavs', 0.55)])"
]
},
{
"cell_type": "code",
"execution_count": 23,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Warriors vs Rockets win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Warriors vs Blazers win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Warriors vs Thunder win this round: ( 12% 30% 42%) win through here: ( 12% 30% 42%)\n",
- "Warriors vs Cavs win this round: ( 29% 61% 80%) win through here: ( 4% 18% 34%)\n"
- ]
- }
- ],
- "source": [
- "playoffs('Warriors',\n",
- " [('Rockets', (0.50, 0.70, 0.80), 4, 1),\n",
- " ('Blazers', (0.55, 0.67, 0.75), 4, 1),\n",
- " ('Thunder', (0.35, 0.55, 0.65), 2, 3),\n",
- " ('Cavs', (0.40, 0.55, 0.65))])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 24,
- "metadata": {
- "collapsed": false
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Cavs vs Pistons win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Cavs vs Hawks win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Cavs vs Raptors win this round: ( 75% 80% 91%) win through here: ( 75% 80% 91%)\n",
- "Cavs vs Thunder win this round: ( 20% 39% 71%) win through here: ( 15% 31% 65%)\n"
+ "Cavs vs Pistons 100%; through here: 100%\n",
+ "Cavs vs Hawks 100%; through here: 100%\n",
+ "Cavs vs Raptors 57%; through here: 57%\n",
+ "Cavs vs Thunder 39%; through here: 23%\n"
]
}
],
"source": [
"playoffs('Cavs',\n",
- " [('Pistons', (0.75, 0.83, 0.85), 4, 0),\n",
- " ('Hawks', (0.45, 0.60, 0.75), 4, 0),\n",
- " ('Raptors', (0.50, 0.55, 0.70), 3, 2),\n",
- " ('Thunder', (0.35, 0.45, 0.60))])"
+ " [('Pistons', 0.83, 4, 0),\n",
+ " ('Hawks', 0.60, 4, 0),\n",
+ " ('Raptors', 0.55, 2, 2),\n",
+ " ('Thunder', 0.45)])"
]
},
{
"cell_type": "code",
- "execution_count": 25,
- "metadata": {
- "collapsed": false
- },
+ "execution_count": 24,
+ "metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Thunder vs Dallas win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Thunder vs Spurs win this round: (100% 100% 100%) win through here: (100% 100% 100%)\n",
- "Thunder vs Warriors win this round: ( 58% 70% 94%) win through here: ( 58% 70% 94%)\n",
- "Thunder vs Cavs win this round: ( 29% 61% 80%) win through here: ( 17% 42% 75%)\n"
+ "Thunder vs Dallas 100%; through here: 100%\n",
+ "Thunder vs Spurs 100%; through here: 100%\n",
+ "Thunder vs Warriors 83%; through here: 83%\n",
+ "Thunder vs Cavs 61%; through here: 51%\n"
]
}
],
"source": [
"playoffs('Thunder',\n",
- " [('Dallas', (0.75, 0.83, 0.85), 4, 1),\n",
- " ('Spurs', (0.30, 0.40, 0.60), 4, 2),\n",
- " ('Warriors', (0.35, 0.45, 0.75), 3, 2),\n",
- " ('Cavs', (0.40, 0.55, 0.65))])"
+ " [('Dallas', 0.83, 4, 1),\n",
+ " ('Spurs', 0.40, 4, 2),\n",
+ " ('Warriors', 0.45, 3, 1),\n",
+ " ('Cavs', 0.55)])"
]
},
{
@@ -799,46 +789,44 @@
"collapsed": true
},
"source": [
- "# The Finals\n",
+ "# The 2016 Finals\n",
"\n",
"## 1 June 2016\n",
"\n",
- "The Warriors completed their comeback against the Thunder, putting them in a great position to win this year (and they are already established as [favorites for next year](http://www.foxsports.com/nba/story/golden-state-warriors-title-favorites-cleveland-cavaliers-odds-2016-17-053016)). Rather than update the odds after each game 0f the finals, I'll just repeat the table (with the note that I think the Warriors are somewhere in the 60% range for each game):\n"
+ "The Warriors completed their comeback against the Thunder, putting them in a great position to win this year (and they are already established as [favorites for next year](http://www.foxsports.com/nba/story/golden-state-warriors-title-favorites-cleveland-cavaliers-odds-2016-17-053016)). Rather than update the odds after each game of the finals, I'll just repeat the table (with the note that I think the Warriors are somewhere in the 60% range for each game and thus about 70% to win the finals):\n"
]
},
{
"cell_type": "code",
- "execution_count": 26,
- "metadata": {
- "collapsed": false
- },
+ "execution_count": 25,
+ "metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "W-L | Singe Game Win Percentage\n",
+ "W-L | Game Win Percentage\n",
" | 20% 25% 30% 35% 40% 45% 50% 55% 60% 65% 70% 75% 80%\n",
"----+-----------------------------------------------------------------\n",
- "0-3 | 0% 0% 1% 2% 3% 4% 6% 9% 13% 18% 24% 32% 41%\n",
- "0-2 | 1% 2% 3% 5% 9% 13% 19% 26% 34% 43% 53% 63% 74%\n",
- "0-1 | 2% 4% 7% 12% 18% 26% 34% 44% 54% 65% 74% 83% 90%\n",
"0-0 | 3% 7% 13% 20% 29% 39% 50% 61% 71% 80% 87% 93% 97%\n",
+ "0-1 | 2% 4% 7% 12% 18% 26% 34% 44% 54% 65% 74% 83% 90%\n",
+ "0-2 | 1% 2% 3% 5% 9% 13% 19% 26% 34% 43% 53% 63% 74%\n",
+ "0-3 | 0% 0% 1% 2% 3% 4% 6% 9% 13% 18% 24% 32% 41%\n",
"----+-----------------------------------------------------------------\n",
- "1-3 | 1% 2% 3% 4% 6% 9% 12% 17% 22% 27% 34% 42% 51%\n",
- "1-2 | 3% 5% 8% 13% 18% 24% 31% 39% 48% 56% 65% 74% 82%\n",
- "1-1 | 6% 10% 16% 24% 32% 41% 50% 59% 68% 76% 84% 90% 94%\n",
"1-0 | 10% 17% 26% 35% 46% 56% 66% 74% 82% 88% 93% 96% 98%\n",
+ "1-1 | 6% 10% 16% 24% 32% 41% 50% 59% 68% 76% 84% 90% 94%\n",
+ "1-2 | 3% 5% 8% 13% 18% 24% 31% 39% 48% 56% 65% 74% 82%\n",
+ "1-3 | 1% 2% 3% 4% 6% 9% 12% 17% 22% 27% 34% 42% 51%\n",
"----+-----------------------------------------------------------------\n",
- "2-3 | 4% 6% 9% 12% 16% 20% 25% 30% 36% 42% 49% 56% 64%\n",
- "2-2 | 10% 16% 22% 28% 35% 43% 50% 57% 65% 72% 78% 84% 90%\n",
- "2-1 | 18% 26% 35% 44% 52% 61% 69% 76% 82% 87% 92% 95% 97%\n",
"2-0 | 26% 37% 47% 57% 66% 74% 81% 87% 91% 95% 97% 98% 99%\n",
+ "2-1 | 18% 26% 35% 44% 52% 61% 69% 76% 82% 87% 92% 95% 97%\n",
+ "2-2 | 10% 16% 22% 28% 35% 43% 50% 57% 65% 72% 78% 84% 90%\n",
+ "2-3 | 4% 6% 9% 12% 16% 20% 25% 30% 36% 42% 49% 56% 64%\n",
"----+-----------------------------------------------------------------\n",
- "3-3 | 20% 25% 30% 35% 40% 45% 50% 55% 60% 65% 70% 75% 80%\n",
- "3-2 | 36% 44% 51% 58% 64% 70% 75% 80% 84% 88% 91% 94% 96%\n",
+ "3-0 | 59% 68% 76% 82% 87% 91% 94% 96% 97% 98% 99% 100% 100%\n",
"3-1 | 49% 58% 66% 73% 78% 83% 88% 91% 94% 96% 97% 98% 99%\n",
- "3-0 | 59% 68% 76% 82% 87% 91% 94% 96% 97% 98% 99% 100% 100%\n"
+ "3-2 | 36% 44% 51% 58% 64% 70% 75% 80% 84% 88% 91% 94% 96%\n",
+ "3-3 | 20% 25% 30% 35% 40% 45% 50% 55% 60% 65% 70% 75% 80%\n"
]
}
],
@@ -863,9 +851,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.5.1"
+ "version": "3.5.3"
}
},
"nbformat": 4,
- "nbformat_minor": 0
+ "nbformat_minor": 1
}