Bradley–Terry Model¶
Summary¶
The Bradley–Terry model is a probability model for predicting the outcome of pairwise comparisons between items, teams, or objects. Given two items i and j with positive strength parameters p_i and p_j, it estimates the probability that i beats j as:
P(i > j) = p_i / (p_i + p_j)
The model was presented by Ralph A. Bradley and Milton E. Terry in 1952, though it had been studied earlier by Ernst Zermelo in the 1920s. Applications include sports rankings, chess ratings, consumer preference surveys, dominance hierarchies, and — notably — it is foundational to Elo (which is a specific scaled case of Bradley–Terry with a scale of 400 and logistic function).
The model can be used in two directions: to predict outcomes given strength parameters, or — more commonly — to infer the strength parameters from observed outcomes via maximum likelihood estimation.
Key Concepts¶
- Strength parameter (p_i): Positive real number representing item quality/strength. Higher = more likely to win. Not directly comparable across different datasets.
- Logit formulation: Often written as log(p_i/p_j) = α_i - α_j, which is equivalent to logistic regression
- Elo connection: With a scale factor of 400 and base 10, Bradley–Terry is equivalent to the Elo rating system
- Maximum likelihood estimation: Parameters are estimated by maximizing the likelihood of observed outcomes. The Zermelo iteration (and faster MM algorithm) are used for convergence.
- Plackett–Luce model: Generalization of Bradley–Terry to rankings of more than 2 items
Formulas¶
Core Bradley–Terry probability:
$$P(i > j) = \frac{p_i}{p_i + p_j}$$
Logit form:
$$\log\frac{P(i > j)}{P(j > i)} = \log(p_i) - \log(p_j) = \alpha_i - \alpha_j$$
Log-likelihood for observed outcomes:
$$\ell(p) = \sum_{i,j} w_{ij} [ \log(p_i) - \log(p_i + p_j) ]$$
Where w_ij = number of times i beat j.
Zermelo iteration (parameter update):
$$p_i^{(new)} = \frac{w_i}{\sum_{j} \frac{w_{ij} + w_{ji}}{p_i + p_j}}$$
Faster MM algorithm iteration:
$$p_i^{(new)} = \frac{\sum_j w_{ij}}{\sum_j \frac{w_{ij} + w_{ji}}{p_i + p_j}}$$
Then normalize by geometric mean.
Python Implementation¶
import numpy as np
from scipy.optimize import minimize
def bradley_terry_mle(outcomes):
"""
outcomes: dict of {(team_i, team_j): wins_ij} — times i beat j
Returns: dict of {team: strength parameter}
"""
teams = set()
for (i, j) in outcomes.keys():
teams.add(i)
teams.add(j)
teams = sorted(teams)
n = len(teams)
def neg_log_likelihood(log_p):
p = np.exp(log_p)
ll = 0
for (i, j), w_ij in outcomes.items():
w_ji = outcomes.get((j, i), 0)
ll += w_ij * (np.log(p[i]) - np.log(p[i] + p[j]))
ll += w_ji * (np.log(p[j]) - np.log(p[i] + p[j]))
return -ll
result = minimize(neg_log_likelihood, np.zeros(n), method='L-BFGS-B')
p = np.exp(result.x)
# Normalize
p = p / np.mean(p)
return {t: p[i] for i, t in enumerate(teams)}
# Example: Team A beat B 2 times, B beat A 3 times; A beat C 1 time, C beat A 0; B beat C 5 times, C beat B 0
outcomes = {
('A', 'B'): 2, ('B', 'A'): 3,
('A', 'C'): 1, ('C', 'A'): 0,
('B', 'C'): 5, ('C', 'B'): 0
}
strengths = bradley_terry_mle(outcomes)
# P(A > B) = strengths['A'] / (strengths['A'] + strengths['B'])
Notes¶
- Bradley–Terry is the theoretical foundation of Elo — Elo is a specific parameterized version
- The model assumes transitivity (if A > B and B > C, then A > C) which may not hold in real sports
- Works well for head-to-head sports (tennis, chess) but less directly applicable to team sports with multiple opponents per game
- For soccer/football, more common to use Poisson-based models rather than Bradley–Terry, but BT can provide team strength estimates as input to Poisson
- The MM algorithm for MLE converges slowly but reliably; the faster variant (equation 5 in Wikipedia) is preferred
- Covariates can be added (covariate-adjusted Bradley–Terry) to incorporate home advantage, player availability, etc.