Who’s the best bettor?
- 7. June 2025
- #statistics
A friend of mine is part of a group that arranges bets at their workplace. Each person proposes bets they believe will come true. The bets have European-style odds \(o\) and are from a betting exchange. The money placed on each bet is always the same, so we arbitrarily take it to be one unit. Each bet leads to an outcome \(y = 1\) (win) or \(y = 0\) (loss).
Given histories of bets for each person, how can we decide who the best bettor is?
For instance, given three people Bob, Alice and Mark with histories:
person odds (o) outcomes (y)
bob (2, 2, 2) (1, 1, 1)
alice (3, 3) (1, 1)
mark (2, 2, 2, 2, 2) (1, 1, 1, 1, 0)
Who is the best bettor? Both Bob and Alice have won all their bets, but Alice took higher risk. Mark placed more bets that came through, but one of his bets was wrong.
In this article we will define the likelihood of an outcome over a sequence of bets. Then we create a latent variable that encodes the skill of a bettor, relative to the probability given by the odds. Given a sequence of bets and outcomes we can then solve for this latent variable, and the best bettor is the person with the greatest value.

The probability of an outcome
A person performs a sequence of \(n\) bets with odds \(o_i\) and attains outcomes \(y_i\) for each bet \(i=1, 2, \ldots, n\). Ignoring the margin of the bookmaker, the odds can be converted to a probabilities by the equation \(p_i = 1 / o_i\). Each bet is independent, so the probability of the joint outcome is
Insight
When a bet will be made. Suppose a person believes the true probability of winning a bet is \(\tilde{p}\). With European-style odds the net gain is \((o-1)\) if a bet is won and \(-1\) if it is lost. A person will only bet if the expected payout is larger than zero, that is, if
Solving for \(\tilde{p}\) we learn that a person will only bet if \(\tilde{p} \geq 1/o = p\). In other words, they will bet if their own personal probability is greater than the one deduced from the odds.
Introducing the latent insight \(\theta\). We will assume that each person has some insight \(\theta\), which is a latent (unobserved) variable representing their additional information. We would like to infer how much insight each person has, and rank their betting ability by their insight. One idea is to set \(\tilde{p} = p + \theta\), but we prefer \(\theta\) to be an unbounded variable and the probabilities \(\tilde{p}\) to be restricted to the domain \([0, 1]\). To accomplish this we use the logistic function (sigmoid or expit) and its inverse the logit. The functions are:
To ensure that \(\tilde{p}\) ends up in the domain \([0, 1]\) we transform the probabilities to logits on \(\mathbb{R}\), add the insight \(\theta\), and transform the result back to \([0, 1]\):
Substituting \(\tilde{p}(\theta, p)\) into the probability of the joint outcome, we obtain the negative log-likelihood function
The likelihood is the probability of observing \((\boldsymbol{p}, \boldsymbol{y})\) given a value of \(\theta\).
Why a prior is needed.
Suppose someone has made three bets with odds \(\boldsymbol{o} = (2, 2, 2)\) and outcomes \(\boldsymbol{y} = (1, 1, 1)\).
Plotting the negative log-likelihood as a function of \(\theta\) we get the following figure.
Minimizing the negative log-likelihood leads to \(\theta \to \infty\).
In a sense, the person is able to claim “I’m great at betting! I knew all along that the true probability was one for all these bets!”
This is analogous to estimating the probability of heads for a sequence of coin tosses as the number of heads divided by the total number of coin tosses. If we get three heads, then the estimated probability is one, and that is unreasonable.
Putting a prior on insight
It’s far-fetched to believe that someone who wins a bet or two really has great insight. To fix this issue of \(\theta\) going to infinity, we put a prior distribution on it. We center a normal distribution around zero, and since the standard deviation is somewhat arbitrary we choose unity. In other words we choose \(\theta \sim \mathcal{N}(1, 0)\) as the prior. A single squared term is added to the negative log-likelihood (now a log-posterior), which becomes
As a result, the negative log-posterior now has a finite minimizer:
We now have a reasonable statistical model.
To summarize, we assumed that each person had some insight \(\theta\) that led them to believe that the true probabilities \(\tilde{p}_i\) are higher than the \(p_i\) deduced from the odds. Then we compute the maximum a posteriori (MAP) estimate of \(\theta\), which is the most probable value of \(\theta\) given the observed sequence of bets. A higher value of \(\theta\) means the person has insight and beats the bookmaker, \(\theta\) around zero means no additional insight is available apart from the one deduced by the odds, and a negative value of \(\theta\) means the person consistently underperforms.
Cases
We will now go through some concrete cases and check if the model is sensible.
Placing more and more bets. Suppose the winning streak is increased by one bet at a time. The table below shows odds, outcomes and MAP estimates of the insight \(\theta\).
case odds (o) outcomes (y) insight (theta)
1 (,) (,) 0.0000
2 (2,) (1,) 0.2223
3 (2, 2) (1, 1) 0.4011
4 (2, 2, 2) (1, 1, 1) 0.5491
5 (2, 2, 2, 2) (1, 1, 1, 1) 0.6748
No bets placed implies zero insight, as there is no reason to believe the bettor is any better than randomly guessing. As the number of consecutive wins increases, the posterior mode moves away from the prior and we believe more and more that the person really has insight and outperforms the bookmaker.
Equal gains. Suppose earlier wins can be used to be more money on the next bets. Here are three bettors who all multiplied their money by \(16\).
case odds (o) outcomes (y) insight (theta)
1 (16,) (1,) 0.4526
2 (4, 4) (1, 1) 0.6179
3 (2, 2, 2, 2) (1, 1, 1, 1) 0.6748
The model assigns the most insight to the person who placed four bets. Suppose each person has some small insight \(\epsilon\). Then the probability \((1/16 + \epsilon) \geq (1/2 + \epsilon)^4 = (1/2)^4 + (1/2)^3 \epsilon + \mathcal{O}(\epsilon^2)\) when \(\epsilon\) is small. The probability that the person who places four bets ends up with four wins is lower, and it is therefore more impressive. In other words, the model favors winning on many smaller bets rather than one big bet, even though the final monetary gain is identical.
Although the amount of money placed on each bet is the same in our setup, the result above makes even more sense if we were betting on a sequence and re-investing our wins. A longer sequence of smaller wins is more beneficial than one large win, since we can re-invest our previous earnings along the way.
A win and a loss. Now consider four bettors who all win one bet and lose one bet.
case odds (o) outcomes (y) insight (theta)
1 (2, 2) (1, 0) 0.0
2 (3, 3) (1, 0) 0.1358
3 (4, 4) (1, 0) 0.2088
4 (5, 5) (1, 0) 0.2559
The model assigns the most insight to the person who took the most risk. This also makes sense.
- Case 1 represents winning once with odds two (doubling the money), then losing one unit of money. This bettor is back to where he started.
- Case 5 represents winning once with odds five (returning five times the original amount of money), then losing one unit of money. This bettor is still up by four units of money.
Some random cases. Below is a table with nine cases, sorted by the inferred insight \(\theta\) of each bettor. These cases are all pretty random, and are shown so the reader can study how different odds and outcomes measure up against each other.
case odds (o) outcomes (y) insight (theta)
1 (2, 2, 2) (0, 0, 1) -0.182
2 (2, 2) (1, 0) 0.0
3 (2, 2, 2) (0, 1, 1) 0.182
4 (2, 2, 2) (1, 0, 1) 0.182
5 (5, 5) (1, 0) 0.2559
6 (8,) (1,) 0.4113
7 (16,) (1,) 0.4526
8 (3, 3) (1, 1) 0.5386
9 (2, 2, 2) (1, 1, 1) 0.5491
Conclusion
To determine who the best bettor is, we modeled a bettor’s insight \(\theta\) as a latent variable. The insight is added to the probability deduced from the odds, and the best bettor is the one with the greatest insight. In order to avoid \(\theta\) becoming very large or very small in small sequences with only wins or losses, we put a prior on it. The skill of a bettor is the maximum a posteriori estimate of \(\theta\).
There might be other interesting ways of solving this problem, but I think this approach works well. It’s conceptually simple, all test cases look good, and it’s simple to implement and compute. Further work that might be interesting includes: making the optimization routine faster, studying the equations in greater depth, or computing the entire posterior distribution instead of finding the value that maximizes it.
Code
Here’s a Python 3.11 code snippet if you want to run the model.
import numpy as np # 1.26.4
import scipy as sp # 1.13.0
import functools
def log_posterior(theta, odds, y):
"""Compute the log-posterior of theta, given `odds` and `y`."""
# Convert from odds to base probabilities
p = 1 / odds
# Convert to logit scale using logit(z) = log(z / (1-z))
logits = sp.special.logit(p)
# Add `theta` (insight) and convet back using expit(z) = 1/(1+exp(-z))
p_tilde = sp.special.expit(logits + theta)
# Compute the log-likelihood
log_likelihood = y * np.log(p_tilde) + (1 - y) * np.log(1 - p_tilde)
# A more numerically stable version as theta -> oo is:
# log_likelihood = -theta * (1 - y) - np.logaddexp(
# np.log(p), -theta + np.log1p(-p))
# Add prior and return the negative log-posterior
return -np.sum(log_likelihood) + theta**2
# Example case
odds = np.array([2, 2, 2])
y = np.array([1, 1, 1])
# Optimize the log-posterior for optimal theta
fun = functools.partial(log_posterior, odds=odds, y=y)
result = sp.optimize.minimize_scalar(fun=fun)
print(result.x) # 0.549107...