I’ve been taking a closer look at home your advantage. I’ve updated my model to take into account the relative strength of the home and away teams, and I’m starting to notice an interesting trend: A team’s home court advantage doesn’t really change year-over-year.
For example: Here’s the home court advantage for New Orleans since 2021. It’s pretty consistent around the league average (2.5).
What’s most surprising though is that this also holds true for Golden State, who changed arena’s from Oracle to the Chase center.
This makes me wonder why CBS claims: It took two seasons, but the Warriors finally have a home-court advantage at Chase Center. I’m curious what their model for Home Court Advantage looks like.
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. Here's my Stan model.
This is a fairly straightforward model where home team advantage for each team is hierarchically modeled.
// Model for home team advantage: yearly and by team
data {
int<lower=0> teams;
int<lower=0> years;
int<lower = 0> n_games;
int year_int[n_games];
int home_team_int[n_games];
int away_team_int[n_games];
int home_team_advantage[n_games];
}
parameters {
matrix [teams, years] theta;
vector [teams] theta_team_bar;
real<lower=0> sigma_team_bar;
real theta_bar;
real<lower=0> sigma_bar;
real<lower=0> sigma;
matrix [teams, years] team_strength;
}
model {
theta_bar ~ normal(0, 10);
sigma_bar ~ cauchy(0, 5);
sigma_team_bar ~ cauchy(0, 5);
sigma ~ cauchy(0, 5);
to_vector(team_strength) ~ normal(0, 10);
// Hierarchical Priors
for(team in 1:teams) {
theta_team_bar[team] ~ normal(theta_bar, sigma_bar);
for(year in 1:years) {
theta[team, year] ~ normal(theta_team_bar[team], sigma_team_bar); // Prior
}
}
for(game in 1:n_games) {
home_team_advantage[game] ~ normal(theta[home_team_int[game], year_int[game]] +
team_strength[home_team_int[game], year_int[game]] -
team_strength[away_team_int[game], year_int[game]],
sigma);
}
}