datarekha

Bayes' theorem in plain English

A formula for updating your beliefs when new evidence arrives. Powers spam filters, A/B testing, and a chunk of modern AI.

7 min read Intermediate Math for ML Lesson 21 of 37

What you'll learn

  • Prior, likelihood, posterior — what each term actually means
  • The spam-filter intuition for P(class | evidence)
  • Why "the evidence updates the belief" is the key idea
  • Where Bayes hides in naive Bayes, A/B testing, and RL

Before you start

The last lesson left a sharp edge: we flipped a conditional — turned “given the segment, how likely is a click?” into “given a click, how likely the segment?” — and warned that doing it carelessly springs the base-rate trap. Here is the formula that flips it correctly, every time. Its one-sentence story is far simpler than its reputation: you believe something, new information arrives, and you update what you believe. That is the whole of Bayes’ theorem — the math is merely how to do that update precisely, base rate and all.

The formula, said plainly

P(hyp | ev)=P(ev | hyp) · P(hyp)P(ev)posteriorlikelihoodpriormarginal (normalizer)
Bayes’ theorem — how evidence updates belief.

In words:

  • P(hypothesis) — your prior (what you believed before seeing the evidence).
  • P(evidence | hypothesis) — the likelihood (how probable the evidence is if the hypothesis is true).
  • P(evidence) — the marginal (how probable the evidence is across all hypotheses; just a normalizing constant).
  • P(hypothesis | evidence) — the posterior (your updated belief after seeing the evidence).

Why does the formula flip the conditional from P(evidence | hypothesis) to P(hypothesis | evidence)? Because what you can measure from data is how often each hypothesis would produce this kind of evidence; Bayes rescales those measurements by the prior and turns them into the thing you actually want — a probability over hypotheses. The denominator just ensures everything still sums to 1.

See the update happen

Before any numbers, build the intuition by hand. Below is a coin of unknown bias θ. Your belief about θ starts as a prior (the faint dashed curve), and every flip is evidence that reshapes it into a posterior (the bold curve). Watch how heads pull the belief right, tails pull it left, and more data makes the curve narrow and confident.

Trybayesian updating

Flip a coin of unknown bias — watch belief sharpen

Your belief about the coin’s bias θ is a Beta(α, β). Each flip updates it: posterior = Beta(α + H, β + T).

Prior
priorposterior
0.00.20.40.60.81.0θ (coin bias)
Data
0H / 0T
no flips yet
Posterior mean
0.500
(α+H)/(α+β+H+T)
MAP
0.500
most likely θ
95% interval
[0.09, 0.91]
central credible

Try No idea vs Believe fair, then flip ~50 times — with enough evidence the two posteriors converge. The prior fades; the data wins.

Notice two things. The posterior always sits between your prior and the observed head-rate — it’s a compromise. And the more you flip, the less your starting prior matters: set “No idea” and “Believe fair,” flip fifty times each, and both arrive at nearly the same answer. That convergence is why Bayesians and frequentists usually agree once the data is plentiful.

Worked example: the spam filter

You’re building an email classifier. From your training data:

  • 30% of emails are spam: P(spam) = 0.3
  • The word “free” appears in 60% of spam emails: P("free" | spam) = 0.6
  • The word “free” appears in 5% of legitimate emails: P("free" | not spam) = 0.05

A new email arrives containing the word “free.” What’s the probability it’s spam?

# Bayes for the spam filter, written line by line.

# Priors (what we knew before seeing the email)
p_spam     = 0.30
p_not_spam = 0.70

# Likelihoods -- how 'free' behaves in each class
p_free_given_spam     = 0.60
p_free_given_not_spam = 0.05

# Marginal -- total probability of seeing 'free' across all emails
# = P(free | spam)*P(spam) + P(free | not spam)*P(not spam)
p_free = p_free_given_spam * p_spam + p_free_given_not_spam * p_not_spam

# Bayes' theorem
p_spam_given_free = (p_free_given_spam * p_spam) / p_free

print(f"Prior belief it's spam:       {p_spam:.2%}")
print(f"After seeing 'free':          {p_spam_given_free:.2%}")
print(f"That's a {p_spam_given_free/p_spam:.2f}x update.")
Prior belief it's spam:       30.00%
After seeing 'free':          83.72%
That's a 2.79x update.

Before seeing “free,” you’d have called it spam 30% of the time. After seeing “free,” you’d call it spam ~84% of the time. The word “free” is strong evidence — it’s much more common in spam than in normal mail — and Bayes turns that evidence into an updated probability.

Crucially: a 60% likelihood does not mean “60% chance it’s spam.” Likelihood and posterior are different things. The prior matters too.

What happens when the prior changes

Same email, same word, but suppose only 5% of your mail is spam (lucky you).

def bayes_spam(p_spam, p_free_given_spam=0.6, p_free_given_not_spam=0.05):
    p_not_spam = 1 - p_spam
    p_free = p_free_given_spam * p_spam + p_free_given_not_spam * p_not_spam
    return (p_free_given_spam * p_spam) / p_free

for prior in [0.05, 0.30, 0.50, 0.80]:
    posterior = bayes_spam(prior)
    print(f"P(spam) prior = {prior:.0%}   →   P(spam | 'free') = {posterior:.2%}")
P(spam) prior = 5%   →   P(spam | 'free') = 38.71%
P(spam) prior = 30%   →   P(spam | 'free') = 83.72%
P(spam) prior = 50%   →   P(spam | 'free') = 92.31%
P(spam) prior = 80%   →   P(spam | 'free') = 97.96%

Same evidence, very different conclusions. With a 5% prior, even after seeing “free” you’re only 39% sure it’s spam. With an 80% prior, you’re 98% sure. The same evidence updates different starting beliefs differently. That’s the heart of Bayesian thinking.

This is also why base rates matter so much in medicine: a 99%-accurate test for a rare disease still produces mostly false positives, because the prior P(disease) is so low that even a small P(positive | healthy) dominates.

TryBayes on people

Why a 99%-accurate test still mostly catches healthy people

Each cell is one person. Drag the sliders — watch how false positives (healthy but tested positive) can outnumber true positives when the disease is rare.

Sick + positive (TP)Sick + negative (FN)Healthy + positive (FP)Healthy + negative (TN)
P(sick | positive)50%
True positives5
False positives5
Total positives10
P(sick | positive)=5 TP5 TP + 5 FP=0.50

Updating with more evidence

If you see two words — say “free” and “winner” — and you assume they’re conditionally independent given the class, the math just multiplies the likelihoods. That assumption is exactly what makes the algorithm “naive Bayes”:

# Naive Bayes for two words
p_spam = 0.30

# Likelihoods (probabilities of each word given the class)
p_free_spam,   p_free_ham   = 0.60, 0.05
p_winner_spam, p_winner_ham = 0.40, 0.01

# Combined likelihood under each class (naive: multiply word probs)
lik_spam = p_free_spam * p_winner_spam * p_spam
lik_ham  = p_free_ham  * p_winner_ham  * (1 - p_spam)

# Normalize to a posterior
posterior_spam = lik_spam / (lik_spam + lik_ham)
print(f"After 'free' AND 'winner':   P(spam | ev) = {posterior_spam:.4%}")
After 'free' AND 'winner':   P(spam | ev) = 99.5162%

Two suggestive words together drive the posterior to 99.5% — far past either word alone — because the naive step multiplies their likelihoods. “Naive” because the independence assumption is rarely true — words co-occur. But it’s surprisingly hard to beat for text classification, which is why naive Bayes was the workhorse spam filter for a couple of decades.

Where else Bayes shows up

  • A/B testing (Bayesian flavor) — instead of a p-value, you maintain a posterior over each variant’s conversion rate and ask “what’s the probability B is better than A?”
  • Recommendation and search — many ranking signals are P(click | features), Bayes-updated as new clicks arrive.
  • Reinforcement learning — Bayesian RL agents maintain a posterior over which actions are best and use it to balance exploration vs exploitation.
  • LLMs — autoregressive next-token prediction is literally P(next_token | previous_tokens). Sampling from that posterior is what generation is.

In one breath

Bayes’ theorem flips a conditional the right way: P(hyp|ev) = P(ev|hyp)·P(hyp) / P(ev) — the posterior is the likelihood times the prior, over the marginal (a normaliser). It is a recipe for updating belief: start with a prior, multiply in how well each hypothesis explains the evidence, renormalise. The prior is load-bearing — the same word “free” makes spam 39% likely under a 5% prior but 98% under an 80% one, and a 99%-accurate test for a 1-in-1000 disease still leaves a positive only ~9% likely, because the base rate dominates. Stack independent evidence by multiplying likelihoods (the “naive” in naive Bayes), and the very same update sits under spam filters, Bayesian A/B tests, RL exploration, and an LLM’s P(next token | previous).

Practice

Quick check

0/3
Q1A disease affects 1 in 1000 people. A test for it is 99% accurate (99% true positive rate, 1% false positive rate). You test positive. What's roughly the chance you have the disease?
Q2What does the 'naive' in naive Bayes refer to?
Q3Your prior is P(model A is better) = 0.5. You run an A/B test and the evidence strongly favors A. What happens to the posterior?

A question to carry forward

Every Bayesian update here ran on a handful of single numbers — P(spam) = 0.3, a likelihood of 0.6. But look again at the coin demo: your belief about the bias θ was never a number, it was a whole curve — a prior shaped like one bell, reshaped by data into a narrower posterior. Even the spam filter’s “60% of spam contains free” is a summary of a whole distribution of words. Probabilities, it turns out, usually arrive as shapes.

So here is the thread onward: what are the handful of named distributions — the bell, the count, the waiting-time, the single coin-flip — that priors, likelihoods, and raw data actually take in practice? Which real situation does each one model, what is the difference between a discrete PMF and a continuous PDF (and how can a density be greater than 1?), and how do you sample any of them in one line of NumPy so you can simulate the systems you cannot solve by hand?

Sign in to track your progress

Completed lessons, your XP, level, and streak save to your account — it's free and takes a few seconds.

Practice this in an interview

All questions
Walk me through Bayes' theorem with a disease-screening base-rate example.

Bayes' theorem updates a prior probability with new evidence: P(H|E) = P(E|H) P(H) / P(E). In disease testing, ignoring the low base rate (prior) makes a positive test look far more alarming than it really is — most positives are false positives when the disease is rare.

How does MLE differ from MAP estimation, and what is the frequentist vs Bayesian divide?

MLE maximises the likelihood of the data alone; MAP (Maximum A Posteriori) adds a prior over parameters and maximises the posterior, making it equivalent to regularised MLE. Frequentists treat parameters as fixed unknowns; Bayesians treat them as random variables with a prior distribution.

State the law of total probability and give a concrete example of when you'd apply it.

The law of total probability decomposes P(A) over a mutually exclusive, exhaustive partition of the sample space: P(A) = Σ P(A|Bᵢ)·P(Bᵢ). It is the engine behind the Bayes denominator and any calculation where you want an overall rate built from segment-level rates.

How does Naive Bayes work, and why is it called 'naive'?

Naive Bayes applies Bayes' theorem to classify by computing the posterior probability of each class given the features. It is naive because it assumes all features are conditionally independent given the class label — an assumption that is almost never true in practice, yet the classifier still works surprisingly well for text and other sparse data.

Related lessons

Explore further

Skip to content