Corner threes are hot. But are left corner threes and right corner threes created equally?
We developed a model to predict how well a player shoots 3s from the left and right corners.
The full model is at the bottom of the post. But at a high level, the model assumes there’s no difference between a player’s ability to shoot in the left vs right corner unless there is sufficient evidence that they shoot differentially (i.e. the model ignores small sample size theatre). And as always, we get confidence intervals on everything we predict, so we can inspect the model to determine if there is truly a difference between left and right corner 3 shooting for each player.
It turns out most players shoot similarly from the left and right corners. Here’s what the model predicts for a sampling of 15 players.
However, not all players shoot similarly from the left and right corners. Some players shoot better in the left corner.
And some players shoot better from the right corner.
There are some really extreme examples. Take Robert Covington. Our model predicts he’ll shoot 40% from the right corner, but almost 30% from the left corner. Or Georges Niang who shoots 45% from the left corner, and only 35% from the right corner.
Then the question becomes: who’s shooting in the wrong corner?
Gerald Green is a great example of a player shooting from the wrong corner. He takes two-thirds of his corner threes from the left corner. But our model predicts he will only shoot 37% from the left corner. That’s respectable, but our model says he should instead spend his time in the right corner, where he’ll shoot almost 45%.
On the other hand, Thaddeus Young is getting it right. He shoots two-thirds of his corner threes from the left corner, where our model predicts he’ll make them at 37% (compared to only 29% from the right corner, where he tends to avoid).
Looking Ahead
I keep a running doc of all the models I want to make. For every newsletter I send out about 3 or 4 models get added to the list. Some require a lot of engineering, some require a lot of model evaluation, and some are just small tweaks to models I’ve already spent a lot of time on. Next week, I think I’ll go back to a team performance model I’ve already discussed and use it to generate Bayesian Power Rankings. This is an idea I thought of while falling off to sleep: power rankings with credible intervals. Since power rankings are mostly a joke, there’s lots of leeway in where I can take it, but it’s going to be a lot of fun.
Stan Model
You can stop reading. This section is only for people curious about the underlying probability model. Either because they want to understand the details or they want to expand on it themselves.
I had a lot of fun trying different variations on this model. One important thing I learned is that you can put multiple priors on the same parameter if it makes sense. What I mean in this specific case is you can put a prior on both the players’ ability to shoot in each corner and a prior on the players’ difference between corners. This is a really great blog post and discussion on the concept of putting priors on parameters while simultaneously putting priors on combinations of parameters.
So in this case, the quantity of interest is the difference in shooting between left and right corners, which I directly put a prior on.
// A binomial regression model.
// Models the total free throw rate over recent years
// Using their Three Point Percentage
data {
int<lower=0> players;
int<lower=0> n_left_attempts[players];
int<lower=0> n_left_successes[players];
int<lower=0> n_right_attempts[players];
int<lower=0> n_right_successes[players];
}
parameters {
// Parameters of interests: 3PT shooting left and right
real theta_left [players];
real theta_right [players];
}
transformed parameters {
real theta_diff [players];
for (player in 1:players) {
theta_diff[player] = theta_left[player] - theta_right[player];
}
}
model {
// Prior on the difference between left and right corner shooting
theta_diff ~ normal(0, 0.3);
// Binomial Model
for (player in 1:players) {
n_left_successes[player] ~ binomial_logit(n_left_attempts[player], theta_left[player]);
n_right_successes[player] ~ binomial_logit(n_right_attempts[player], theta_right[player]);
}
}
generated quantities {
real<lower=0, upper=1>theta_left_ [players];
real<lower=0, upper=1>theta_right_ [players];
for (player in 1:players) {
theta_left_[player] = inv_logit(theta_left[player]);
theta_right_[player] = inv_logit(theta_right[player]);
}
}