Bayesian statistics explained with Python posterior updating examples

September 2, 2026
Facebook logo.
Twitter logo.
LinkedIn logo.
Newsletter issue count indicatorNewsletter total issues indicator
Bayesian statistics explained with Python posterior updating examples

Bayesian statistics explained with Python posterior updating examples

Bayesian statistics gives you a formal way to update what you believe as new data arrives. Instead of treating probability as the long-run frequency of an event (the classical approach), Bayesian methods treat probability as how strongly you believe a claim, given the information you have right now. You start with an initial belief. Then you observe new evidence and use a formula called Bayes' theorem to revise that belief. This makes Bayesian statistics especially practical in finance, where conditions change and new information arrives constantly. For a deeper comparison of Bayesian and classical approaches with trading code, see our guide to Bayesian vs. frequentist methods in Python. Bayesian thinking also underpins many machine learning techniques used in finance.

This article explains the core idea and then shows a complete Python example you can run yourself. By the end you'll know how to estimate an unknown probability from data and watch your estimate sharpen as more observations come in.

How Bayesian Statistics Updates Beliefs

The central formula is Bayes' theorem. In plain English, it tells you how to revise a belief after you see new evidence. You start with what you believed before, weigh how well the new data fits that belief, and then scale the result so the probabilities add up properly.

Here is the formula.

P(hypothesis | data) = P(data | hypothesis) * P(hypothesis) / P(data)

Each term in the formula has a specific meaning. P(hypothesis) is your prior, meaning what you believed before seeing any data. A hypothesis here is just your claim about the unknown value, such as "the probability of heads is 0.6." P(data | hypothesis) is the likelihood, meaning how probable the observed data would be if that claim were true.

P(hypothesis | data) is the posterior, meaning your updated belief after seeing the data. P(data) is a scaling factor that makes the updated probabilities add up to 1. Without it, the numbers wouldn't represent valid probabilities.

That's the basic framework. After that, the work comes down to choosing a prior and calculating how likely your data would be under different values of the unknown quantity.

Why This Matters for Working Professionals

In classical hypothesis testing, the result often gets framed as a decision about whether the evidence is strong enough to reject a claim. Classical methods also produce confidence intervals and point estimates, but the hypothesis-test output is usually a yes-or-no verdict. Bayesian statistics gives you a full distribution of plausible values instead.

This matters when you need to make decisions under uncertainty. Suppose you want to estimate how often a trading strategy produces a winning trade. You don't want a binary answer. You want a range of probabilities you can use to decide how much capital to allocate. Bayesian methods give you that kind of output.

Bayesian updating also helps when data is scarce. With only 30 days of data on a new asset, any method will carry a lot of uncertainty. Bayesian methods let you combine that limited data with prior assumptions in a transparent way, which stabilizes your estimates until more observations accumulate.

Bayesian Statistics in Practice: Estimating a Coin's Bias

Suppose you have a coin and you want to figure out the probability it lands heads. You don't know if it's fair. This is a toy problem, but the update rule works the same way if you model a trading strategy's daily outcome as a simple win or loss, and you assume each day behaves like a repeated draw from the same unknown probability.

Choose the Prior

We'll use a Beta distribution as our prior. The Beta distribution is a continuous probability distribution defined between 0 and 1. It's useful here because probabilities must stay between 0 and 1, so the Beta distribution naturally describes possible values for an unknown probability.

It has two parameters, often called a and b. When both equal 1, the distribution is flat, meaning every probability from 0 to 1 is equally likely. This represents total ignorance about the coin's bias.

Update the Model With Data

Every time we observe a flip, we update the Beta distribution. If we see heads, we add 1 to a. If we see tails, we add 1 to b. The posterior formula is simple.

posterior = Beta(a + heads, b + tails)

The prior parameters a and b act like starting pseudo-observations, which means they influence the estimate before much real data arrives. With a flat prior of Beta(1, 1), you're effectively saying "I've seen one imaginary heads and one imaginary tails." As real data piles up, those starting values matter less and less.

The peak of the posterior shifts toward the observed proportion of heads. More data reduces uncertainty, so the plausible range for the true probability shrinks with each new observation.

This example is useful because you can calculate the updated distribution directly, with no approximation. In more complex problems you'd use a computational method called Markov Chain Monte Carlo (MCMC), which draws random samples from the posterior when no clean formula exists. Our guide to Markov models covers related probabilistic modeling.

Full Python Implementation of Bayesian Statistics

The code below simulates coin flips from a biased coin (true probability of heads = 0.7) and then plots how the Bayesian posterior evolves as data accumulates.

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import beta

# True probability of heads (unknown to our model)
true_p = 0.7
np.random.seed(42)

# Simulate 200 coin flips
n_flips = 200
flips = np.random.binomial(1, true_p, size=n_flips)  # 1 = heads, 0 = tails

# Prior parameters (flat prior: Beta(1, 1))
a_prior = 1
b_prior = 1

# We'll snapshot the posterior at these observation counts
checkpoints = [0, 5, 20, 50, 200]

x = np.linspace(0, 1, 500)

fig, ax = plt.subplots(figsize=(10, 6))

for cp in checkpoints:
    heads = flips[:cp].sum()
    tails = cp - heads
    a_post = a_prior + heads
    b_post = b_prior + tails
    y = beta.pdf(x, a_post, b_post)
    ax.plot(x, y, label=f"After {cp} flips (a={a_post}, b={b_post})")

ax.axvline(true_p, color="black", linestyle="--", label=f"True p = {true_p}")
ax.set_xlabel("Probability of Heads")
ax.set_ylabel("Density")
ax.set_title("Bayesian Posterior Update for Coin Bias")
ax.legend()
plt.tight_layout()
plt.show()

What the Code Does Step by Step

The script generates 200 random coin flips where the true chance of heads is 70%. It then computes the Beta posterior at five checkpoints.

At 0 flips, the updated distribution is flat because the model has no data. After 5 flips, it starts to lean toward the observed outcomes, but the curve remains wide because uncertainty is still high. By 50 flips, most of the probability mass sits near 0.7. After 200 flips, the range of plausible values is much narrower.

That narrowing is the core payoff of Bayesian statistics. You get a full picture of your uncertainty, and that picture sharpens automatically as evidence accumulates.

Extract Useful Numbers From the Posterior

A distribution is informative, but sometimes you need a single number or a range.

from scipy.stats import beta

# After all 200 flips
heads = flips.sum()
tails = n_flips - heads
a_post = a_prior + heads
b_post = b_prior + tails

# Point estimate: mean of the posterior
posterior_mean = a_post / (a_post + b_post)
print(f"Posterior mean: {posterior_mean:.4f}")

# 95% credible interval
lower, upper = beta.ppf([0.025, 0.975], a_post, b_post)
print(f"95% credible interval: [{lower:.4f}, {upper:.4f}]")

The posterior mean gives you a single best estimate, which in this case will land near 0.70. The 95% credible interval (the Bayesian equivalent of a confidence interval) tells you the range where the true probability sits. Under this model, given your prior assumptions and the data you observed, there is a 95% probability that the true value lies in that range. That direct interpretation is one reason people prefer Bayesian statistics over classical confidence intervals, which require a more roundabout reading.

When to Use Bayesian Statistics in Practice

Bayesian methods are useful when new data arrives over time, or when you want your result to show a full range of plausible values instead of a single estimate. They also help when you have prior knowledge that you want to include explicitly.

In finance, you might use Bayesian methods to estimate how often a strategy wins. You can also use them to track changes in market behavior, such as when a market shifts from calm trading to large swings. Another use is stock-price models that keep track of uncertainty in the model's inputs.

The main tradeoff is computational cost. Simple problems like the coin example have exact solutions. Real-world problems with many parameters require MCMC sampling, which can be slow. Libraries like PyMC handle this for you, but you should understand the basics before reaching for them.

How to Choose a Prior

People often focus on the prior because it reflects assumptions you make before you see the data. Critics argue it introduces subjectivity. In practice, you have a few options.

One option is a flat prior such as Beta(1,1), which gives equal weight to all probabilities between 0 and 1. Another option is a prior that reflects real knowledge, such as a belief that most coins are close to fair. You can also choose a middle ground that avoids extreme estimates when you have little data, but still leaves room for the data to move the result.

For a concrete example, suppose you believe most trading strategies win between 45% and 55% of the time. You could choose a Beta(45, 55) prior, which places most of its weight in that range. With enough data, the posterior will move away from that starting point if the evidence disagrees. For most applied work, a middle-ground prior is a good default. It prevents absurd estimates when data is scarce and fades into irrelevance once you have enough observations.

Watch the Assumptions

The coin-flip example assumes each flip is independent and that the true probability stays fixed. In markets, both assumptions often fail. Daily returns can depend on what happened yesterday, and the probability of a winning trade can shift as market conditions change. Real applications need models that account for those complications, such as stochastic process models, which allow the unknown probability to change over time.

Next Steps

The coin-flip example covers the essential mechanics of Bayesian updating. For a quick experiment, try changing the prior from Beta(1,1) to Beta(5,5) and compare how fast the estimate moves toward the true value. A stronger prior resists the data more at first, which you'll see clearly in the plot.

To apply these ideas to real market data, you'll need to work with more complex likelihood functions and possibly MCMC sampling. The free Data Analysis With Python guides cover the tooling in more depth, which will help you prepare real datasets for Bayesian modeling.