Pages

Thursday, June 5, 2014

2014 NBA Playoffs Finals Preview

jQuery UI Accordion - Default functionality We're adding smaller and smaller sample sizes as the playoffs progress, so my overall results won't change much.  I am now 28-21 overall after going 3-2 in the Conference Finals:

SAS 5 times: 3-2-0

I will now proceed to provide a similar analysis of the Finals.  As with before, there will be new minutes allocations and updated RPM numbers from ESPN.  Similar to before, all of the computation was done in R and the script I ran will be included.

Series Previews:

San Antonio vs. Miami

Model Vegas*
Game 1 Probability SAS: 71% / MIA: 29% SAS: -200 / MIA: +170
Game 1 Spread SAS: -6.3 / MIA: +6.3 SAS: -5 (-105) / MIA: +5 (-115)
Series Probability SAS: 76% / MIA: 24% SAS: -135 / MIA: +115

Given that this finals matchup is a rematch of last year’s, it’s natural to compare each team to last year’s version, but such an exercise doesn’t necessarily mean much as we still don’t know what last year’s expected outcome should have been (that the two teams essentially played to a draw doesn’t mean they were actually evenly matched because seven games is still a very small sample size).  Nevertheless, it is worth pointing out that the Spurs are unquestionably better this year, since Ginobili is healthy and the bench is significantly improved, and the Heat are probably at around last year’s level, since the replacement of Mike Miller and 2013 Shane Battier with Rashard Lewis and 2014 Shane Battier (as well as the marginal aging of almost all of their core players) counteracts Wade’s improved health.  Based on this information alone and the reversal of home court advantage, it would appear that the Spurs should be a sizeable favorite.

Regular season RAPM numbers support this notion.  Using minutes estimates based loosely on the numbers from both the 2013 Finals and the two conference finals (useful, because in terms of size, athleticism, and distribution of talent, Miami’s roster is similar to Oklahoma City’s and San Antonio’s is similar to Indiana’s), my model estimates that the Spurs are a 6 point favorite at home, a coin flip on the road, and a 76% favorite in the series.  While Miami would appear to be of the same mold as Oklahoma City in terms of possessing the type of athleticism that forces San Antonio’s non-creators to dribble and pass, they are in many ways a more moderate and thus manageable version of the Thunder.  Each of the Heat’s big three is slightly less long/athletic than his Thunder counterpart, and the Heat will offer better potential hiding spots for Parker on defense.  Furthermore, Diaw can passably defend LeBron in a way that he couldn’t Durant, and lesser defenders have a better chance against Wade than they did against Westbrook (while Wade is still an effective offensive player, his effectiveness isn’t as dependent on the athleticism discrepancy between him and his defender as Westbrook’s), which frees up more minutes for Green and Leonard to rest; against Oklahoma City, the Spurs had essentially no other effective option against either Durant or Westbrook since there is a cap on the amount of energy Ginobili can expend, which presented issues in cases of foul trouble.  Overall, I don't see any significant matchup issues in either direction and believe that my model's estimate is fair.

There are enough uncertainties in this series, however, to lower my confidence in a Spurs bet.  In last year's series, the Spurs played both Wade and James as if they were pre 2013 Rondo-esque shooters, but will they continue to do so or will they anticipate tactical adjustments and attempt to preemptively adjust themselves and save that defense as an option for later in the series?  How will Parker (with his injury), Ginobili (with his old age), and Mills (with his sometimes questionable decision making) fair against the aggressive Heat traps?  How aggressively will the Heat trap?  Will Diaw's floor spacing, passing, and tertiary offensive creation skills be as effective against the Heat's aggressive helps as they were against the Thunder's?  According to Haralabos Voulgaris, the Spurs originally opened at a much more favorable line for Spurs backers, and I would have much more confidence betting Spurs -4 for Game 1 and Spurs -115 for the series.  However, given the current lines, I would abstain for now.

*All Vegas numbers from Bovada


List of minutes estimates and xRAPM ratings:

Show/Hide

     Spurs:
player minutes orpm drpm rpm onet dnet net
Boris Diaw 28 0.46 1.06 1.52 0.27 0.62 0.89
Cory Joseph 5 -0.76 -2.81 -3.57 -0.08 -0.29 -0.37
Danny Green 28 0.92 2.89 3.81 0.54 1.69 2.22
Kawhi Leonard 35 0.82 1.84 2.66 0.60 1.34 1.94
Manu Ginobili 27 4.75 0.04 4.79 2.67 0.02 2.69
Marco Belinelli 13 0.77 -3.43 -2.66 0.21 -0.93 -0.72
Matt Bonner 10 2.04 0.69 2.73 0.43 0.14 0.57
Patty Mills 20 3.17 0.56 3.73 1.32 0.23 1.55
Tiago Splitter 10 -1.13 4.60 3.47 -0.24 0.96 0.72
Tim Duncan 33 -0.06 5.34 5.28 -0.04 3.67 3.63
Tony Parker 31 3.03 -0.16 2.87 1.96 -0.10 1.85

     Heat:
player minutes orpm drpm rpm onet dnet net
Chris Andersen 14 0.46 3.78 4.24 0.13 1.10 1.24
Chris Bosh 36 0.39 3.34 3.73 0.29 2.51 2.80
Dwyane Wade 36 1.26 0.78 2.04 0.95 0.59 1.53
Greg Oden 0 -3.69 -0.57 -4.26 0.00 0.00 0.00
James Jones 2 -1.15 0.65 -0.50 -0.05 0.03 -0.02
LeBron James 42 8.87 0.32 9.19 7.76 0.28 8.04
Mario Chalmers 28 0.45 0.90 1.35 0.26 0.53 0.79
Michael Beasley 0 -2.97 -2.88 -5.85 0.00 0.00 0.00
Norris Cole 19 -1.57 -1.79 -3.36 -0.62 -0.71 -1.33
Rashard Lewis 19 -1.93 0.01 -1.92 -0.76 0.00 -0.76
Ray Allen 24 2.57 -2.91 -0.34 1.29 -1.46 -0.17
Shane Battier 12 -0.28 1.28 1.00 -0.07 0.32 0.25
Toney Douglas 2 0.22 -1.73 -1.51 0.01 -0.07 -0.06
Udonis Haslem 6 -4.74 1.09 -3.65 -0.59 0.14 -0.46


R Script:

Show/Hide


library(XML)
library(RCurl)
v.pages <- 1:11            #change if increase in number of pages on http://espn.go.com/nba/statistics/rpm/_/page/1/sort/RPM
v.column.names <- c("player","team","orpm","drpm","rpm")
v.teams.home <- c("sas")
v.teams.away <- c("mia")
v.teams <- c("sas","mia")
hca <- 3.2                #difference between neutral court and home court; this is total hca adjustment, not the adjustment for each team
avg_eff <- 104            #average league points per 100 possessions
df.rpm.3 <- data.frame(player=character(0),team=character(0),orpm=numeric(0),drpm=numeric(0),rpm=numeric(0))
for(page in v.pages)
{
    v.url.rpm <- paste("http://espn.go.com/nba/statistics/rpm/_/page/",page,"/sort/RPM",sep="")
    table <- readHTMLTable(v.url.rpm)[[1]]
    table <- table[as.character((table[,2]))!="NAME",]
    table2 <- cbind(as.data.frame(matrix(unlist(strsplit(as.character(table[,2]),", ")),ncol=2,byrow=TRUE),stringsAsFactors=FALSE)[,1], as.data.frame(matrix(unlist(table[,3]),ncol=1,byrow=TRUE),stringsAsFactors=FALSE), as.data.frame(matrix(unlist(table[,6]),ncol=1,byrow=TRUE),stringsAsFactors=FALSE),as.data.frame(matrix(unlist(table[,7]),ncol=1,byrow=TRUE),stringsAsFactors=FALSE),as.data.frame(matrix(unlist(table[,8]),ncol=1,byrow=TRUE),stringsAsFactors=FALSE))
    table2[,3] <- as.numeric(table2[,3])
    table2[,4] <- as.numeric(table2[,4])
    table2[,5] <- as.numeric(table2[,5])
    colnames(table2) <- v.column.names
    df.rpm.3 <- rbind(df.rpm.3,table2)
}
#minutes distributions and individual xrapm:
df.sas.r4 <- data.frame(player=c("Tony Parker","Tim Duncan","Kawhi Leonard","Marco Belinelli","Boris Diaw","Danny Green","Manu Ginobili","Tiago Splitter","Patty Mills","Cory Joseph","Matt Bonner"),minutes=c(31,33,35,13,28,28,27,10,20,5,10))
df.sas.r4 <- merge(df.sas.r4, df.rpm.3[,c(1,3,4,5)], by="player", all.x=TRUE)
df.mia.r4 <- data.frame(player=c("LeBron James","Dwyane Wade","Chris Bosh","Mario Chalmers","Ray Allen","Norris Cole","Shane Battier","Chris Andersen","Rashard Lewis","Toney Douglas","Michael Beasley","Udonis Haslem","James Jones","Greg Oden"),minutes=c(42,36,36,28,24,19,12,14,19,2,0,6,2,0))
df.mia.r4 <- merge(df.mia.r4, df.rpm.3[,c(1,3,4,5)], by="player", all.x=TRUE)
df.sas.r4$onet <- df.sas.r4$minutes * df.sas.r4$orpm / 48
df.mia.r4$onet <- df.mia.r4$minutes * df.mia.r4$orpm / 48
df.sas.r4$dnet <- df.sas.r4$minutes * df.sas.r4$drpm / 48
df.mia.r4$dnet <- df.mia.r4$minutes * df.mia.r4$drpm / 48
df.sas.r4$net <- df.sas.r4$minutes * df.sas.r4$rpm / 48
df.mia.r4$net <- df.mia.r4$minutes * df.mia.r4$rpm / 48
#team-level xrapm
df.all.r4 <- data.frame(team=v.teams)
df.all.r4$onet <- as.vector(t(data.frame(sas=sum(df.sas.r4$onet),mia=sum(df.mia.r4$onet))))
df.all.r4$dnet <- as.vector(t(data.frame(sas=sum(df.sas.r4$dnet),mia=sum(df.mia.r4$dnet))))
df.all.r4$net <- as.vector(t(data.frame(sas=sum(df.sas.r4$net),mia=sum(df.mia.r4$net))))
df.all.r4$home_perc <- (avg_eff+df.all.r4$onet+hca/4)^14/((avg_eff+df.all.r4$onet+hca/4)^14+(avg_eff-df.all.r4$dnet-hca/4)^14)
df.all.r4$away_perc <- (avg_eff+df.all.r4$onet-hca/4)^14/((avg_eff+df.all.r4$onet-hca/4)^14+(avg_eff-df.all.r4$dnet+hca/4)^14)
#specific round 4 matchups
df.r4.matchups.1 <- data.frame(team=v.teams.home, opponent=v.teams.away, stringsAsFactors = FALSE)
df.r4.matchups.1$team_home_perc <- merge(data.frame(team=df.r4.matchups.1$team),df.all.r4[,c(1,5)], by="team", all.x=TRUE, sort=FALSE)[,2]
df.r4.matchups.1$team_away_perc <- merge(data.frame(team=df.r4.matchups.1$team),df.all.r4[,c(1,6)], by="team", all.x=TRUE, sort=FALSE)[,2]
df.r4.matchups.1$opponent_home_perc <- merge(data.frame(team=df.r4.matchups.1$opponent),df.all.r4[,c(1,5)], by="team", all.x=TRUE, sort=FALSE)[,2]
df.r4.matchups.1$opponent_away_perc <- merge(data.frame(team=df.r4.matchups.1$opponent),df.all.r4[,c(1,6)], by="team", all.x=TRUE, sort=FALSE)[,2]
df.r4.matchups.1$team_matchup_home_perc <- (df.r4.matchups.1$team_home_perc - (df.r4.matchups.1$team_home_perc*df.r4.matchups.1$opponent_away_perc))/(df.r4.matchups.1$team_home_perc + df.r4.matchups.1$opponent_away_perc - (2*df.r4.matchups.1$team_home_perc*df.r4.matchups.1$opponent_away_perc))
df.r4.matchups.1$team_matchup_away_perc <- (df.r4.matchups.1$team_away_perc - (df.r4.matchups.1$team_away_perc*df.r4.matchups.1$opponent_home_perc))/(df.r4.matchups.1$team_away_perc + df.r4.matchups.1$opponent_home_perc - (2*df.r4.matchups.1$team_away_perc*df.r4.matchups.1$opponent_home_perc))
df.r4.matchups.1$series_perc <- df.r4.matchups.1$team_matchup_home_perc^4 + 4*df.r4.matchups.1$team_matchup_home_perc^3*(1-df.r4.matchups.1$team_matchup_home_perc)*(1-(1-df.r4.matchups.1$team_matchup_away_perc)^3) + 6*df.r4.matchups.1$team_matchup_home_perc^2*(1-df.r4.matchups.1$team_matchup_home_perc)^2*((3*df.r4.matchups.1$team_matchup_away_perc^2*(1-df.r4.matchups.1$team_matchup_away_perc))+df.r4.matchups.1$team_matchup_away_perc^3)+4*
df.r4.matchups.1$team_matchup_home_perc*(1-df.r4.matchups.1$team_matchup_home_perc)^3*df.r4.matchups.1$team_matchup_away_perc^3
df.r4.matchups.2 <- df.r4.matchups.1[,c(2,1)]
colnames(df.r4.matchups.2) <- c("team","opponent")
df.r4.matchups.2$team_home_perc <- df.r4.matchups.1$opponent_home_perc
df.r4.matchups.2$team_away_perc <- df.r4.matchups.1$opponent_away_perc
df.r4.matchups.2$opponent_home_perc <- df.r4.matchups.1$team_home_perc
df.r4.matchups.2$opponent_away_perc <- df.r4.matchups.1$team_away_perc
df.r4.matchups.2$team_matchup_home_perc <- 1-df.r4.matchups.1$team_matchup_away_perc
df.r4.matchups.2$team_matchup_away_perc <- 1-df.r4.matchups.1$team_matchup_home_perc
df.r4.matchups.2$series_perc <- 1-df.r4.matchups.1$series_perc
df.r4.matchups <- rbind(df.r4.matchups.1,df.r4.matchups.2)
df.r4.matchups <- df.r4.matchups[order(df.r4.matchups$series_perc, decreasing=TRUE),]

#print results
df.r4.matchups
df.all.r4[order(df.all.r4$net,decreasing=TRUE),c(1:4)]
df.sas.r4
df.mia.r4

4 comments:

  1. Vegas Game 2 lines for 6/8:
    SAS -3.5 (-115) / MIA +3.5 (-105)
    SAS -160 / MIA +140

    I can't make too much out of Game 1 given how the conditions affected everyone. Obviously, they prevented LeBron from playing the end of the game, but they also affected players on both sides before that. Given the line is 1.5 points in the Heat's favor after their loss, I would still abstain from this game.

    ReplyDelete
  2. Vegas Game 3 lines for 6/10:
    SAS +4.5 (-115) / MIA -4.5 (-105)
    SAS +165 / MIA -190

    Other than the actual result of the game, Game 2 was positive for the Spurs. It required an extremely out of the ordinary outside shooting game from LeBron, and Miami pulled the switching defense out of their bag already. It appears that Vegas has adjusted for homecourt advantage a lot more than I would have, especially coming off a Heat win, so as a result, I would bet the Spurs.

    ReplyDelete
  3. Vegas Game 4 lines for 6/12:
    SAS +5 (-105) / MIA -5 (-115)
    SAS +205 / MIA -245

    I'm always wary of betting against the Heat after a loss as anecdotally, their effort improves significantly, especially defensively, more so than a 0.5 point adjustment in their favor would suggest. However, until I actually this is actually proven, I would still bet San Antonio.

    ReplyDelete
  4. Vegas Game 5 lines for 6/15:
    SAS -5 / MIA +5
    SAS -190 / MIA +160

    Starting Allen for Chalmers (instead of for Lewis) allows LeBron to defend Parker without having Wade defend Diaw, which for the Heat might hopefully discourage the Spurs' ball movement. However, the Heat's defensive effort has just not been there the entire series, and the Spurs have been able to get whatever they want offensively. The only real chance for the Heat would be to try to score even more efficiently, but with how the Spurs play Wade on the other end, it's extremely unlikely that would happen. Sure, there should be extra desperation from the Heat, but at this point, I'm doubtful it would make a difference at this point. I would still bet the Spurs.

    ReplyDelete