Skip to content
Saed Sayad

Naive Bayes

Naive Bayes classification with Bayes' rule, worked on the Play Golf dataset: likelihood tables, posterior calculation, and Laplace smoothing.

6 min read · Updated August 8, 2026

The Naive Bayes classifier applies Bayes’ theorem with one bold simplification: it assumes every predictor is independent of every other predictor, given the class. That assumption is rarely true, yet the resulting model is fast to train, needs little data, and often outperforms far more sophisticated methods — especially on large datasets.

Where ZeroR uses no predictor and OneR picks the single best one, Naive Bayes uses all predictors at once, combining their evidence through probability.

Bayes’ rule

Bayes’ theorem computes the posterior probability of a class cc given the evidence xx from three ingredients: the prior P(c)P(c), the likelihood P(xc)P(x \mid c), and the evidence probability P(x)P(x):

P(cx)=P(xc)P(c)P(x)P(c \mid x) = \frac{P(x \mid c)\, P(c)}{P(x)}

  • P(cx)P(c \mid x) — posterior: probability of the class given the predictors
  • P(c)P(c) — prior: probability of the class before seeing any evidence
  • P(xc)P(x \mid c) — likelihood: probability of observing the predictors within that class
  • P(x)P(x) — marginal probability of the evidence (a normalizing constant)

With several predictors x1,x2,,xnx_1, x_2, \dots, x_n, the naive assumption of class-conditional independence lets the joint likelihood factor into a product:

P(x1,,xnc)=i=1nP(xic)P(x_1, \dots, x_n \mid c) = \prod_{i=1}^{n} P(x_i \mid c)

The classifier then predicts the class with the highest posterior:

c^=argmaxc  P(c)i=1nP(xic)\hat{c} = \arg\max_{c} \; P(c) \prod_{i=1}^{n} P(x_i \mid c)

Because P(x)P(x) is the same for every class, you can compare the unnormalized scores P(c)iP(xic)P(c)\prod_i P(x_i \mid c) and normalize at the end.

Worked example: Play Golf

We use the same 14-row weather dataset as the decision tree page. The target is Play Golf (9 Yes, 5 No), so the priors are P(Yes)=9/14P(\text{Yes}) = 9/14 and P(No)=5/14P(\text{No}) = 5/14.

#OutlookTempHumidityWindyPlay Golf
1RainyHotHighFalseNo
2RainyHotHighTrueNo
3OvercastHotHighFalseYes
4SunnyMildHighFalseYes
5SunnyCoolNormalFalseYes
6SunnyCoolNormalTrueNo
7OvercastCoolNormalTrueYes
8RainyMildHighFalseNo
9RainyCoolNormalFalseYes
10SunnyMildNormalFalseYes
11RainyMildNormalTrueYes
12OvercastMildHighTrueYes
13OvercastHotNormalFalseYes
14SunnyMildHighTrueNo

Step 1 — frequency tables

Count each attribute value against the target:

OutlookYesNoTempYesNo
Sunny32Hot22
Overcast40Mild42
Rainy23Cool31
HumidityYesNoWindyYesNo
High34False62
Normal61True33

Step 2 — likelihood tables

Divide by the class counts (9 Yes, 5 No) to get P(xic)P(x_i \mid c):

OutlookP(·|Yes)P(·|No)TempP(·|Yes)P(·|No)
Sunny3/92/5Hot2/92/5
Overcast4/90/5Mild4/92/5
Rainy2/93/5Cool3/91/5
HumidityP(·|Yes)P(·|No)WindyP(·|Yes)P(·|No)
High3/94/5False6/92/5
Normal6/91/5True3/93/5

Step 3 — predict a new day

Should you play when Outlook = Sunny, Temp = Cool, Humidity = High, Windy = True? Multiply the matching likelihoods by each prior:

P(Yesx)914×39×39×39×39=0.0079P(\text{Yes} \mid x) \propto \tfrac{9}{14} \times \tfrac{3}{9} \times \tfrac{3}{9} \times \tfrac{3}{9} \times \tfrac{3}{9} = 0.0079

P(Nox)514×25×15×45×35=0.0137P(\text{No} \mid x) \propto \tfrac{5}{14} \times \tfrac{2}{5} \times \tfrac{1}{5} \times \tfrac{4}{5} \times \tfrac{3}{5} = 0.0137

Normalizing both scores (0.0079+0.0137=0.02160.0079 + 0.0137 = 0.0216):

P(Yesx)=0.00790.0216=0.37P(Nox)=0.01370.0216=0.63P(\text{Yes} \mid x) = \frac{0.0079}{0.0216} = 0.37 \qquad P(\text{No} \mid x) = \frac{0.0137}{0.0216} = 0.63

No has the higher posterior — the prediction is don’t play.

Interactive calculator: toggle the evidence attributes and watch the posterior for each class update. Static result for the default evidence (Outlook = Sunny, Temp = Cool, Humidity = High, Windy = True):

ClassUnnormalized scorePosterior
Yes0.00790.37
No0.01370.63 ← prediction

The zero-frequency problem

The fix is Laplace smoothing — add 1 to every count before dividing:

P(OvercastNo)=0+15+3=18P(\text{Overcast} \mid \text{No}) = \frac{0 + 1}{5 + 3} = \frac{1}{8}

where 3 is the number of Outlook values. Every probability stays positive, and no class is ever silently eliminated.

Numerical predictors

Categorical frequency tables don’t apply directly to numbers. One option is binning the variable into categories first. The other is to assume a distribution — typically Gaussian — and use its density as the likelihood:

f(x)=12πσe(xμ)22σ2f(x) = \frac{1}{\sqrt{2\pi}\,\sigma}\, e^{-\frac{(x - \mu)^2}{2\sigma^2}}

For example, if Humidity were numeric with mean 79.1 and standard deviation 10.2 for Yes days versus 86.2 and 9.7 for No days, the likelihood of Humidity = 80 is f(80Yes)0.039f(80 \mid \text{Yes}) \approx 0.039 and f(80No)0.034f(80 \mid \text{No}) \approx 0.034.

In practice

sklearn.naive_bayes offers GaussianNB for numeric features, MultinomialNB for counts (the classic spam-filter workhorse), and BernoulliNB for binary features. Naive Bayes trains in a single pass over the data, so it remains a strong baseline for text classification and a useful real-time model when data arrives continuously. Its posterior rankings are usually reliable even when the calibrated probabilities are not — for calibrated outputs, pair it with CalibratedClassifierCV.

Common pitfalls

  • Correlated predictors double-count evidence. Two nearly identical features each multiply the score, inflating confidence. Remove redundant features first.
  • Forgetting Laplace smoothing. Without it, one unseen attribute value zeroes out a class.
  • Trusting the probabilities absolutely. The independence assumption biases posteriors toward 0 and 1; treat them as scores, not calibrated risks.
  • Applying Gaussian NB to skewed data. If a numeric feature is far from normal, bin it or transform it instead.

Summary

Naive Bayes combines the prior probability of each class with per-attribute likelihoods through Bayes’ rule, assuming predictors are independent given the class. Training is just counting: build frequency tables, convert them to likelihood tables, and multiply. Add Laplace smoothing to survive unseen values, and use Gaussian densities or binning for numeric predictors.