Naive Bayes Classifier Explained: Python Tutorial (2026)
Naive Bayes is one of the fastest and simplest probabilistic classifiers. Despite the naive assumption of feature independence, it performs surprisingly well for text classification and spam detection — often matching or beating much more complex models.
The Math
Naive Bayes applies Bayes theorem: P(y|x) = P(x|y) * P(y) / P(x). The naive assumption: features are conditionally independent given the class, so P(x|y) = product of individual P(xi|y) terms. We pick the class with the highest numerator — P(x) cancels out.
Three Variants
Gaussian NB: continuous features assumed normally distributed. For numerical data.
Multinomial NB: discrete count features (word counts). Standard for text classification.
Bernoulli NB: binary features (word present/absent). Good for short texts.
Gaussian NB Example
from sklearn.naive_bayes import GaussianNB
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
iris = load_iris()
X, y = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
gnb = GaussianNB()
gnb.fit(X_train, y_train)
y_pred = gnb.predict(X_test)
print(f'Accuracy: {gnb.score(X_test, y_test):.4f}')
print(classification_report(y_test, y_pred, target_names=iris.target_names))
print('Probabilities:', gnb.predict_proba(X_test[:3]).round(3))Text Classification with Multinomial NB
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline
cats = ['sci.space', 'rec.sport.hockey', 'talk.politics.guns', 'comp.graphics']
train = fetch_20newsgroups(subset='train', categories=cats, remove=('headers','footers','quotes'))
test = fetch_20newsgroups(subset='test', categories=cats, remove=('headers','footers','quotes'))
clf = Pipeline([
('tfidf', TfidfVectorizer(max_features=10000, ngram_range=(1,2), min_df=3)),
('nb', MultinomialNB(alpha=0.1))
])
clf.fit(train.data, train.target)
y_pred = clf.predict(test.data)
print(f'Accuracy: {(y_pred == test.target).mean():.4f}')
print(classification_report(test.target, y_pred, target_names=cats))Spam Detection
spam = ['Win a free iPhone now! Click here!!!',
'URGENT: Account compromised. Verify now!',
'Make money fast! $5000/week from home']
ham = ['Call scheduled for tomorrow at 3pm?',
'Please review the Q3 analysis attached',
'Meeting rescheduled to Friday']
texts, labels = spam + ham, [1]*3 + [0]*3
spam_clf = Pipeline([('tfidf', TfidfVectorizer()), ('nb', MultinomialNB())])
spam_clf.fit(texts, labels)
for email in ['Free prize! Click now!', 'Report due Friday']:
pred = spam_clf.predict([email])[0]
print(f"[{'SPAM' if pred else 'HAM'}] {email}")Laplace Smoothing
Without smoothing, a word seen in test but never in training for a class gives P=0, making the entire posterior zero. Laplace smoothing (alpha=1) adds 1 to every count. Always use some smoothing for text classification.
Naive Bayes vs Other Classifiers
Speed: trains and predicts extremely fast — O(n * features). Accuracy: competitive with SVM for text; loses to gradient boosting for numerical data with correlated features. Works well with small training sets.
Conclusion
Naive Bayes is the best text classification algorithm nobody talks about. For spam, topic classification, and sentiment analysis it trains in milliseconds. Always use it as your baseline on text tasks — it is surprisingly hard to beat even with complex models.



