Learning Guides
Email Spam Filtering Using NLTK and Naive Bayes
Quick answer: Learn how to build a spam email classifier in Python using NLTK for text preprocessing and the Naive Bayes algorithm, with complete example code.
The Problem: Classifying Emails as Spam or Not Spam
Spam filtering is a text classification problem: given the content of an email, predict whether it is spam or legitimate, commonly called ham. It remains a classic, well understood introduction to NLP classification.
Step 1: Text Preprocessing
import nltk
import re
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer
nltk.download('stopwords')
stop_words = set(stopwords.words('english'))
stemmer = PorterStemmer()
def preprocess(text):
text = text.lower()
text = re.sub(r'[^a-z\s]', '', text) # remove punctuation and numbers
words = text.split()
words = [stemmer.stem(w) for w in words if w not in stop_words]
return ' '.join(words)
sample = "Congratulations! You have WON a FREE prize, click now!!!"
print(preprocess(sample))
Lowercasing, removing punctuation, stripping common stopwords like "the" and "and", and stemming words to their root form all reduce noise so the model can focus on genuinely informative words.
Step 2: Converting Text to Numeric Features
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(cleaned_emails) # a bag-of-words matrix
CountVectorizer converts text into a matrix of word counts, since Machine Learning algorithms need numeric input, not raw text.
Step 3: Training a Naive Bayes Classifier
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score, classification_report
X_train, X_test, y_train, y_test = train_test_split(X, labels, test_size=0.2, random_state=42)
model = MultinomialNB()
model.fit(X_train, y_train)
predictions = model.predict(X_test)
print(accuracy_score(y_test, predictions))
print(classification_report(y_test, predictions))
Why Naive Bayes Works Well for Spam Filtering
Naive Bayes assumes each word contributes independently to the probability of an email being spam, an assumption that is not literally true in language, but works surprisingly well in practice for text classification, and trains extremely fast even on large vocabularies.
Why Accuracy Alone Is Not Enough
Spam datasets are often imbalanced, with far more legitimate email than spam. A model predicting "not spam" for everything can still score high accuracy while being completely useless. Precision and recall specifically for the spam class matter more here, since missing genuine spam and blocking a legitimate email carry very different costs.
Classifying a New Email
new_email = ["Limited time offer, claim your reward now"]
cleaned = [preprocess(e) for e in new_email]
vectorized = vectorizer.transform(cleaned)
print(model.predict(vectorized)) # e.g. ['spam']
Common Interview Questions
Why does Naive Bayes work well for text classification despite its "naive" independence assumption?
Even though words are not truly independent in real language, the assumption simplifies computation dramatically, and in practice the relative probability rankings it produces are often accurate enough for reliable classification.
Why is accuracy a poor metric for a spam filter?
Spam datasets are typically imbalanced, so a model can achieve high accuracy simply by predicting the majority class for everything, while completely failing at the actual task of catching spam.
FAQ
Frequently Asked Questions
Why is Naive Bayes commonly used for spam filtering?
It handles text classification efficiently despite its simplifying independence assumption between words, and trains extremely fast even on large vocabularies, making it a reliable, practical baseline.
What text preprocessing steps are typically used before spam classification?
Lowercasing, removing punctuation and numbers, removing common stopwords, and stemming words to their root form, all reducing noise before the text is converted to numeric features.
Why is accuracy a poor metric for evaluating a spam filter?
Spam datasets are usually imbalanced, so a model can score high accuracy by predicting the majority class for everything while completely failing to catch actual spam.
Keep Reading
Related Articles
Learning Guides
INNER JOIN in SQL with Examples: Complete Beginner's Guide
Learn INNER JOIN in SQL with practical examples, syntax, interview questions, and real-world use cases. A complete beginner-friendly SQL JOI
Learning Guides
OUTER JOIN in SQL: Complete Guide with Examples for Beginners
Master OUTER JOIN in SQL with practical examples and real-world scenarios. Learn LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN, syntax, use cases,
Learning Guides
Multi-Row Functions in SQL: Complete Guide with Examples
Learn multi-row (aggregate) functions in SQL including SUM, AVG, COUNT, MIN, MAX, GROUP BY and HAVING, with practical examples, NULL handlin