Probability Fundamentals
Sample spaces, Bayes' theorem, conditional probability
An email arrives. Is it spam? You know before opening it that 30% of all email is spam — that is your prior. You open it and find the word "FREE" five times. Words like "FREE" appear five times more often in spam than in legitimate email. How do you combine what you already knew with this new evidence?
The naive move is to just count: look at all emails containing "FREE" in your dataset and compute the fraction that were spam. This ignores the prior and breaks when your dataset is small or skewed. What you actually want is a principled update: start from P(spam) = 0.3, observe the word "FREE," and revise. The mechanism for this is conditional probability. P(spam|FREE) asks: among emails that contain "FREE," what fraction are spam? This is not the same as P(FREE|spam), which asks: among spam emails, what fraction contain "FREE?" Those two quantities are different, and confusing them is the base rate fallacy.
To go from the latter to the former, you need Bayes' theorem: $P(spam|FREE) = P(FREE|spam) \cdot P(spam) / P(FREE)$. The numerator multiplies the likelihood — how often "FREE" appears in spam — by the prior probability of spam. The denominator, $P(FREE)$, normalises so everything sums to 1. It equals $P(FREE|spam) \cdot P(spam) + P(FREE|ham) \cdot P(ham)$: the law of total probability.
This is the mechanism behind every probabilistic ML system. The prior $P(spam) = 0.3$ encodes what you knew before. The likelihood $P(FREE|spam)$ is what your model learns from data. The posterior $P(spam|FREE)$ is what you actually want — your updated belief after seeing evidence.
Concretely: suppose "FREE" appears in 10% of spam emails but only 2% of legitimate ones — a 5x likelihood ratio, matching what you observed. Then $P(FREE) = P(FREE|spam) cdot P(spam) + P(FREE|ham) cdot P(ham) = 0.10 imes 0.3 + 0.02 imes 0.7 = 0.044$, and $P(spam|FREE) = (0.10 imes 0.3) / 0.044 = 0.03 / 0.044 approx 0.68$. A single word moved your belief from a 30% prior to a 68% posterior.
NOT this. Most people think $P(A|B) = P(B|A)$. They do not. A test that correctly identifies 99% of sick patients — $P(positive|disease) = 0.99$ — does not mean a positive result means you are 99% likely to have the disease. Suppose the disease affects only 1 in 1000 people ($P(disease) = 0.001$) and the test also has a 1% false-positive rate ($P(positive|no\ disease) = 0.01$, i.e. 99% specificity). Then $P(positive) = 0.99 \times 0.001 + 0.01 \times 0.999 \approx 0.0110$, so $P(disease|positive) = 0.00099 / 0.0110 \approx 9\%$. The false positive rate, applied to the large healthy population, swamps the true positives. Dropping the prior — treating $P(positive|disease)$ as $P(disease|positive)$ — is the error. The formal rules: conditional probability $P(A|B) = P(A \cap B)/P(B)$. Independence: $P(A \cap B) = P(A)P(B)$. Chain rule: $P(A,B,C) = P(A)P(B|A)P(C|A,B)$.
Key points
- Use it when you know the likelihood but want the posterior. Any time your model gives you $P(data|hypothesis)$ but you need $P(hypothesis|data)$, Bayes' theorem is the exact conversion. In spam filtering: your trained model gives you $P(word|spam)$; Bayes gives you $P(spam|word)$. Without the prior, you cannot make this conversion.
- The production trap: ignoring the base rate. A fraud detection model that catches 99% of actual fraud (99% recall) sounds great. But if only 0.1% of transactions are fraudulent and the model also has a 1% false-positive rate, then out of 10,000 transactions: about 10 are truly fraudulent (0.1% of 10,000), of which the model catches roughly 9.9 (99% recall). But that same 1% false-positive rate applied to the ~9,990 legitimate transactions flags about 100 of them too. So of the ~110 total flagged alerts, only ~9.9 are real fraud — realized precision is about 9%, not 99%. The prior probability of fraud determines whether a high-recall model is operationally useful. Always report precision *at the operating base rate*, not just recall on a balanced test set.
- The diagnostic: check whether your prior and likelihood are on the same scale. If $P(spam) = 0.3$ but your spam filter was trained on a 50/50 balanced dataset, the likelihood ratios are calibrated for a different prior. Recalibrate with Platt scaling or isotonic regression before multiplying priors by likelihoods. Symptoms of miscalibration: model confidence of 90% but actual accuracy of 60% on live traffic.
- Counting orderings: the binomial coefficient. Flip a biased coin three times with $P(H) = 0.7$. "Exactly 2 heads" can happen as HHT, HTH, or THH — three distinct orderings, each with probability $0.7^2 imes 0.3^1 = 0.147$. There are $inom{3}{2} = 3$ such orderings (choose which 2 of the 3 flips are heads), so $P( ext{exactly 2 heads}) = 3 imes 0.147 = 0.441$. This is the binomial PMF: $P(k heads in n flips) = inom{n}{k}p^k(1-p)^{n-k}$ — count the orderings, then multiply by the probability of any single ordering.
Posterior = likelihood × prior / evidence. The prior is not optional — it determines whether a model output is meaningful or misleading.
Recap
- Bayes = the update rule: $P(spam|FREE) = P(FREE|spam)\,P(spam)/P(FREE)$. Prior × likelihood ÷ evidence.
- Posterior ≠ likelihood: $P(A|B) \neq P(B|A)$. Confusing them is the base rate fallacy.
- Rare disease trap: 99% sensitive test, 0.1% prevalence → $P(disease|+) \approx 9\%$. False positives swamp true ones.
- Evidence = law of total probability: $P(FREE) = P(FREE|spam)P(spam) + P(FREE|ham)P(ham)$ normalises to 1.
- Report precision at the real base rate, not on a balanced test set — 99% recall + 1% false-positive rate + 0.1% fraud prevalence → realized precision ≈ 9%, not 99%.
- Recalibrate before multiplying: a 50/50-trained model's likelihoods don't match a 30% prior. Platt/isotonic first.
Check your understanding
Q1. You roll two fair dice. Event A = 'first die shows 6', Event B = 'sum equals 7'. Are A and B independent? Compute P(A), P(B), P(A∩B) and verify your answer.
- A) P(A)=1/6, P(B)=1/6, P(A∩B)=1/36. Check: P(A)·P(B)=1/36=P(A∩B), so A and B ARE independent. This is non-obvious: given first die=6, the only way sum=7 is second die=1, probability 1/6 = P(B), confirming independence via the multiplication rule for two disjoint dice events.
- B) P(A) = 1/6. P(B) = 6/36 = 1/6 (pairs summing to 7: (1,6),(2,5),(3,4),(4,3),(5,2),(6,1)). P(A∩B) = P(first=6, second=1) = 1/36. Check: P(A)·P(B) = 1/36 = P(A∩B). Therefore A and B ARE independent — the second die's uniformity exactly offsets the sum constraint.
- C) P(A)=1/6, P(B)=5/36, P(A∩B)=1/36. Check: P(A)·P(B)=5/216 ≠ 1/36, so A and B are NOT independent. The sum constraint means knowing the first die restricts which second-die outcomes count toward sum=7 — dependence via a shared conditioning variable.
- D) P(A)=1/6, P(B)=1/6, P(A∩B)=1/36, so P(A)·P(B)=1/36=P(A∩B). However A and B are NOT independent because the events share a structural constraint on the same two dice — any linking constraint like this must create dependence regardless of the numerical check.
Q2. You have a biased coin: P(H)=0.7. You flip it 3 times. What is the probability of getting exactly 2 heads, and why does the binomial formula give the right answer?
- A) P(exactly 2H) = C(3,2) × 0.7² × 0.3¹ = 3 × 0.49 × 0.3 = 0.441. The formula works because each flip is independent and identically distributed (P(H)=0.7 always). C(3,2)=3 counts the orderings HHT, HTH, THH, each with probability 0.7²×0.3=0.147; summing the three mutually exclusive orderings gives 3×0.147=0.441.
- B) P(exactly 2H) = 0.7² × 0.3¹ = 0.147. The binomial formula is not needed here — since each flip is independent, you multiply the probabilities of each outcome directly, treating HHT as the only relevant sequence. The C(3,2) factor would overcount by including indistinguishable orderings of the flips, double-counting probability mass.
- C) P(exactly 2H) = C(3,2) × 0.7² × 0.3¹ = 0.441. However, the binomial formula only gives the right answer when P(H)=0.5. For a biased coin with P(H)=0.7, the correct approach is to sum probabilities over all sequences with exactly 2 heads, weighting each differently based on the order.
- D) P(exactly 2H) = C(3,2) × 0.7³ × 0.3¹ = 3 × 0.343 × 0.3 = 0.309. The binomial formula works here because independence and identical distribution both hold across all three flips. We use 0.7³ because there are 3 flips total and, by symmetry with C(3,2), each contributes a full factor of P(H) to the product.
Q3. In a medical test, P(Disease)=0.01, P(+|Disease)=0.95, P(+|No Disease)=0.05. You test positive. Which TWO of the following options correctly compute P(Disease|+) AND correctly interpret what the result implies?
- A) P(+) = 0.95×0.01 + 0.05×0.99 = 0.059. P(D|+) = 0.0095/0.059 ≈ 16.1%. The 95% sensitivity dominates the calculation — a positive result is mostly reliable because sensitivity is high, and once specificity exceeds 90% the false-positive contribution becomes negligible relative to true positives in any prevalence regime.
- B) P(D|+) ≈ 95% because the test has 95% sensitivity, which by definition equals the positive predictive value under Bayes' rule. A positive result directly reflects the sensitivity of the test — if the test is correct 95% of the time, then 95% of positives are true positives. Base rate only matters when sensitivity drops below 50%.
- C) P(+) = 0.95×0.01 + 0.05×0.99 = 0.059. P(D|+) = 0.0095/0.059 ≈ 16.1%. The 5% false-positive rate applied to 99% of healthy people produces far more false positives than true positives, so even an excellent test yields mostly false positives for a rare disease — sequential testing and clinical judgment are needed.
- D) P(+) = P(+|D)P(D) + P(+|no D)P(no D) = 0.95×0.01 + 0.05×0.99 = 0.059. P(D|+) = 0.0095/0.059 ≈ 16.1%. This is base rate neglect: because P(Disease)=0.01 is low, the 5% false-positive rate applied to the large healthy population overwhelms the 95%-sensitive test's true positives. Confirmatory testing is needed.
Try it interactively
ML Systems Lab is a free interview-prep platform for ML engineers — work through the full interactive module, quizzes, and drills.
Open ML Systems Lab →