Naive Bayes Classifier
Naive Bayes is a probabilistic classifier based on applying Bayes’ Theorem with a strong (naive) conditional-independence assumption between features given the class.
Naive Bayes in Simple Words
Naive Bayes looks at clues, checks how often those clues appeared with each class in the past, and chooses the class with the strongest probability score. A simple example is email spam detection.
Past Emails
Learn from examples labelled Spam or Not Spam.
Look at Clues
Words such as free, prize, meeting or report.
Compare Scores
How strongly do the clues support each class?
Choose a Class
Predict the class with the larger score.
Tiny Example — One New Email
New email contains
free · prize · click
Past data suggests
These words occur more often in spam.
Prediction
Spam
The model does not understand the meaning of “free” like a human does. It uses probabilities learned from labelled examples.
What is Naive Bayes?
Naive Bayes is a supervised machine learning algorithm used mainly for classification problems. It predicts the probability that a data point belongs to a particular class based on Bayes' Theorem combined with a Feature Independence Assumption.
Common Uses:
- Spam Detection: Filtering out junk emails.
- Sentiment Analysis: Understanding positive/negative product reviews.
- Document Classification: Organizing news articles into categories.
- Medical Data Classification: Supporting carefully validated research or decision-support tasks.
* Naive Bayes is especially famous in Natural Language Processing (NLP) because it works efficiently with high-dimensional text data.
Simple Example: Spam Detection
Suppose an email contains words like: FREE, WINNER, MONEY, CLICK
Naive Bayes calculates two things:
- 1. Probability (Spam | Email)
- 2. Probability (Not Spam | Email)
It then predicts the class with the higher probability.
Why is it Called "Naive"?
The “naive” assumption is more specific than saying that features are always unrelated. Naive Bayes treats the features as conditionally independent once the class is known.
Spam example: suppose an email contains both FREE and MONEY.
When scoring the class Spam, the simple Naive Bayes idea is:
In real language, words can clearly be related. The assumption is therefore a simplification, not a statement that the real world is independent. Even so, this approximation can work well for many classification tasks, especially text.
Bayes’ Theorem Formulas
Naive Bayes is built directly on Bayes’ Theorem. Bayes’ Theorem helps calculate conditional probability — the probability of an event given another event has occurred.
Bayes' Formula
P(A | B) = [ P(B | A) × P(A) ] / P(B)Posterior = (Likelihood × Prior) / Evidence
Terminology
- P(A|B) Posterior: Updated probability of class A after observing evidence B.
- P(B|A) Likelihood: Probability of observing evidence B when class A is true.
- P(A) Prior: Probability of class A before observing the new evidence.
- P(B) Evidence: Overall probability of observing evidence B.
A Tiny Bayes Calculation
Suppose past email data tells us:
| Given value | Meaning |
|---|---|
| P(Spam) = 0.40 | 40% of emails are spam. |
| P(Free | Spam) = 0.75 | 75% of spam emails contain “free”. |
| P(Free) = 0.36 | 36% of all emails contain “free”. |
Step 1 — Multiply
0.75 × 0.40 = 0.30
Likelihood × prior
Step 2 — Divide
0.30 ÷ 0.36 ≈ 0.833
Divide by the evidence
Result
P(Spam | Free) ≈ 83.3%
For these made-up teaching numbers.
Real-Life Analogy: A common probability example is medical testing: if a condition is rare but a test is positive, Bayes’ theorem updates the probability after observing that result. In real healthcare, diagnosis requires validated clinical evidence and cannot be reduced to one toy calculation.
Worked Numerical Example
Let's predict whether a day is suitable for playing golf based on the weather outlook.
| Outlook (Feature) | Play Golf (Target) |
|---|---|
| Sunny | Yes |
| Rainy | No |
| Sunny | Yes |
| Overcast | Yes |
| Rainy | No |
Step-by-Step Probability Calculation
- Step 1: Calculate Priors
Total rows = 5
P(Yes) = 3/5 = 0.6
P(No) = 2/5 = 0.4
- Step 2: Calculate Likelihoods
Looking at "Sunny":
P(Sunny | Yes) = 2/3 ≈ 0.666
- Step 3: Calculate the Evidence
Sunny appears 2 times out of 5 rows.
P(Sunny) = 2/5 = 0.4
- Step 4: Calculate the Posterior
P(Yes | Sunny) = [(2/3) × (3/5)] ÷ (2/5)
= 0.4 ÷ 0.4 = 1.0
In this tiny dataset, every Sunny example is labelled Yes, so the posterior becomes 100%. Real datasets are larger and less perfect.
Types of Naive Bayes
Naive Bayes is not a single algorithm — it is a family of classifiers, each designed for a different statistical distribution of features. The appropriate variant depends mainly on how the input features are represented and what probability distribution the model assumes for them.
Choose the variant from the feature type
Gaussian NB
Continuous numbers
Height, temperature
Multinomial NB
Counts / frequencies
Word counts
Bernoulli NB
Binary 0/1 features
Word present?
Complement NB
Count-like text features
Often useful with imbalance
Categorical NB
Categorical features
Weather type, colour
1. Gaussian Naive Bayes
For continuous, real-valued features
Gaussian NB is used when your features are continuous numerical values — things like temperature, salary, height, or age. It assumes that within each class, the values of each feature follow a normal (Gaussian / bell-curve) distribution. During training, it estimates the mean (μ) and variance (σ²) of each feature for each class.
How it works:
- For each class, calculate the mean and variance of every feature
- For a new sample, compute how likely each feature value is under that class's Gaussian curve
- Multiply all likelihoods together (naïve assumption) and pick the class with highest probability
Real-world use cases:
- Medical diagnosis (blood pressure, glucose levels)
- Fraud detection (transaction amounts, timing)
- Weather classification (temperature, humidity)
- Iris flower species classification
Gaussian Distribution per class — each class has its own μ and σ
from sklearn.naive_bayes import GaussianNB
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# Load dataset (continuous features: sepal/petal length & width)
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Train Gaussian NB — automatically estimates μ and σ per class per feature
model = GaussianNB()
model.fit(X_train, y_train)
# Class-conditional means learned during training:
print(model.theta_) # shape: [n_classes, n_features] → mean per class
print(model.var_) # shape: [n_classes, n_features] → variance per class
predictions = model.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, predictions):.2%}")
# Output with this split: Accuracy: 100.00%2. Multinomial Naive Bayes
For count data — the NLP workhorse
Multinomial NB works with discrete count or frequency data — most commonly word counts in text classification tasks. It models the probability of observing a particular word count given the class. For example: if the word "free" appears 50 times in spam emails and only 3 times in legitimate emails, Multinomial NB captures this frequency ratio as evidence.
How it works:
- Convert text into a word frequency matrix (Bag of Words / TF-IDF)
- For each class, estimate the probability of each word appearing
- For new text, combine the word evidence with the class prior and choose the class with the larger score
Real-world use cases:
- Email spam classification (most common use)
- Sentiment analysis of reviews
- News article categorisation
- Language identification
Example — Word frequency evidence for spam classification
| Word | Spam freq | Ham freq | More common in |
|---|---|---|---|
| "free" | 142 | 8 | Spam |
| "money" | 98 | 12 | Spam |
| "click" | 87 | 5 | Spam |
| "meeting" | 4 | 156 | Ham |
| "report" | 6 | 134 | Ham |
3. Bernoulli Naive Bayes
For binary presence/absence features
Bernoulli NB is designed for binary feature vectors — each feature is either 0 (absent) or 1 (present). The key distinction from Multinomial NB is that Bernoulli NB cares only about whether a word appeared, not how many times it did. It also explicitly penalises the absence of words that are important to a class, which can make it useful for presence/absence data and some short-text tasks.
Multinomial vs Bernoulli — key difference:
| Aspect | Multinomial | Bernoulli |
|---|---|---|
| Feature value | Word count (0,1,2,...) | Word present? (0 or 1) |
| Email "free free free" | free = 3 | free = 1 |
| Absent word impact | No penalty | Explicitly penalised |
| Typical representation | Counts / frequencies | Presence / absence |
Use cases:
- Short text / tweet classification
- Document presence/absence features
- Medical symptom checkers (symptom present or not)
- Click-stream data (did user click? Y/N)
from sklearn.naive_bayes import BernoulliNB
from sklearn.feature_extraction.text import CountVectorizer
import numpy as np
emails = [
"win free money now", # spam
"click here for prize", # spam
"meeting tomorrow at 10", # ham
"quarterly report attached", # ham
]
labels = [1, 1, 0, 0] # 1=spam, 0=ham
# binary=True converts word counts to 0/1 presence flags
vectorizer = CountVectorizer(binary=True)
X = vectorizer.fit_transform(emails)
# Each row: [0,1,0,0,1,...] — word present (1) or absent (0)
model = BernoulliNB()
model.fit(X, labels)
new_email = vectorizer.transform(["free prize click"])
print(model.predict(new_email)) # [1] → classified as SPAM
print(np.round(model.predict_proba(new_email), 3))
# [[0.053 0.947]] → about 94.7% spam in this tiny example4. Complement Naive Bayes
For imbalanced datasets — a Multinomial NB improvement
Complement NB is an adaptation of Multinomial NB that is particularly suited to imbalanced datasets. It builds its weights using statistics from the complement of each class — the samples that are not in that class. It is especially associated with text classification and can be worth comparing with Multinomial NB when classes are uneven.
Why Complement? The imbalance problem:
If 90% of the training documents are "Not Spam" and 10% are "Spam", the class counts are strongly imbalanced. Complement NB uses statistics from the other classes when building its weights, which can make its estimates more stable for this kind of text problem. You should still compare models using suitable validation metrics.
from sklearn.naive_bayes import ComplementNB
from sklearn.feature_extraction.text import TfidfVectorizer
# Complement NB is a drop-in replacement for MultinomialNB
# Best for: imbalanced text classification tasks
vectorizer = TfidfVectorizer()
X_train_tfidf = vectorizer.fit_transform(X_train_text)
X_test_tfidf = vectorizer.transform(X_test_text)
model = ComplementNB(alpha=1.0) # alpha = Laplace smoothing
model.fit(X_train_tfidf, y_train)
print(f"Accuracy: {model.score(X_test_tfidf, y_test):.2%}")5. Categorical Naive Bayes
For features that are categories
Categorical NB is designed for features such as Weather = Sunny/Rainy or Colour = Red/Blue/Green. Each feature is treated as having its own categorical distribution within each class. In scikit-learn, the categories are represented with integer codes such as 0, 1, 2.
→ 0
→ 1
→ 2
These numbers are category codes, not measurements — “2” is not twice “1”.
Quick-Reference: Which Naive Bayes to Use?
| Variant | Feature Type | Best For | sklearn Class |
|---|---|---|---|
| Gaussian NB | Continuous (real numbers) | Continuous numeric features | GaussianNB() |
| Multinomial NB | Counts / non-negative frequencies | Text counts; TF-IDF can also work | MultinomialNB() |
| Bernoulli NB | Binary (0/1) | Presence / absence features | BernoulliNB() |
| Complement NB | Count / TF-IDF-like non-negative features | Text data, especially with imbalance | ComplementNB() |
| Categorical NB | Encoded categorical values | Discrete categories per feature | CategoricalNB() |
The Zero Probability Problem
In count-based variants such as Multinomial Naive Bayes, a word that never appeared in a class can receive an estimated probability of 0. Multiplying by zero can wipe out that class score. Additive smoothing prevents this problem.
Solution: Additive Smoothing
Add a small value α to the counts. When α = 1, this is commonly called Laplace smoothing.
Tiny smoothing example
Suppose “offer” appeared 0 times in a class, there are 10 total word counts, and our vocabulary has 5 words.
0 + 1 = 1
add α = 1
10 + (1 × 5) = 15
adjust denominator
1 ÷ 15 ≈ 0.067
small, but not zero
Python Implementations
Python Code: Multinomial NB (Text Data)
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import CountVectorizer
texts = ["win free money", "hello friend", "claim prize free"]
y = ["spam", "ham", "spam"]
# Convert text to frequency counts
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(texts)
# Train Model
model = MultinomialNB()
model.fit(X, y)
# Predict a new email
test_email = ["free money now"]
test_vector = vectorizer.transform(test_email)
prediction = model.predict(test_vector)
print(f"Prediction for '{test_email[0]}': {prediction[0]}")$ python nb_classifier.py
Prediction for 'free money now': spam
Advantages vs Disadvantages
Advantages
- Fast: Training and prediction can be very efficient compared with many more complex models.
- Useful for Text: Count-based variants are classic baselines for document and spam classification.
- Parameter Efficient: It can estimate the needed class-conditional statistics from relatively modest amounts of data.
- Multi-Class: Naturally compares scores across multiple classes.
Disadvantages
- Strong Assumption: Conditional independence can be unrealistic when features strongly depend on one another.
- Unseen Counts: Count-based variants need additive smoothing to avoid zero-probability problems.
- Probability Calibration: Predicted probabilities may be poorly calibrated even when class predictions are useful.
Common Questions
Is Naive Bayes only for text?
No. Text is a famous use case, but Gaussian NB can handle continuous numerical features and Categorical NB can model categorical features.
Does Naive Bayes require the features to be truly independent?
No real dataset has to be perfectly independent. Conditional independence is the model's simplifying assumption; validation tells you whether that approximation works well enough for your task.
Naive Bayes or Logistic Regression?
Both can be strong classification baselines. Compare them using validation data and a metric that matches the problem instead of assuming one is always better.
Continue Learning
Final Summary
Naive Bayes is a classic probabilistic classification method built on Bayes' theorem. It combines a class prior with feature likelihoods to score possible classes for a new observation.
Its conditional-independence assumption is deliberately simple, yet Naive Bayes can still be a strong and very fast baseline in suitable problems, especially text classification.
Most Important Insight to Remember:
"Naive Bayes makes a strong conditional-independence assumption. The assumption is simple, so always validate the model — but the method can still work very well for suitable classification tasks."