Freedom Sale
Independence Day Special — Unlock the AI Path 70% off our most popular AI course · Limited time offer
--Days
--Hrs
--Min
--Sec
Claim Your Discount
✦ Intermediate ⏱ 35 min

📄 Build a Document Classifier with scikit-learn

🎯 What You'll Build

A document classifier that sorts news articles into topics — sports, technology, politics, health — using TF-IDF features and Naive Bayes, built into scikit-learn.

📋 What You'll Need

1

Load and explore the 20 Newsgroups dataset

scikit-learn includes 20,000 news articles across 20 categories — built in, no download.

from sklearn.datasets import fetch_20newsgroups

# Use a subset of 4 categories for clarity
categories = [
    'sci.space',
    'comp.graphics',
    'rec.sport.hockey',
    'talk.politics.guns',
]

train = fetch_20newsgroups(subset='train', categories=categories, remove=('headers','footers','quotes'))
test  = fetch_20newsgroups(subset='test',  categories=categories, remove=('headers','footers','quotes'))

print(f"Training: {len(train.data)} articles")
print(f"Testing:  {len(test.data)} articles")
print(f"Classes:  {train.target_names}")

# Preview one article
print("\n--- Sample Article ---")
print(train.data[0][:400])
print(f"Category: {train.target_names[train.target[0]]}")
2

Train a TF-IDF + Naive Bayes classifier

TF-IDF converts text to numerical features. Naive Bayes classifies based on word frequency.

from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import classification_report

pipeline = Pipeline([
    ('tfidf', TfidfVectorizer(max_features=10000, stop_words='english', ngram_range=(1,2))),
    ('clf',   MultinomialNB(alpha=0.1)),
])

pipeline.fit(train.data, train.target)

y_pred = pipeline.predict(test.data)
target_names = [c.split('.')[-1] for c in test.target_names]
print(classification_report(test.target, y_pred, target_names=target_names))
precision    recall  f1-score   support
       space       0.97      0.96      0.97       394
    graphics       0.93      0.94      0.93       389
      hockey       0.99      0.98      0.98       399
        guns        0.95      0.96      0.95       364
    accuracy                           0.96      1546
3

Classify new articles and find top keywords

Predict the category of any new text and show which words drove the decision.

import numpy as np

def classify_and_explain(text, top_n=10):
    probs     = pipeline.predict_proba([text])[0]
    pred_idx  = np.argmax(probs)
    pred_cat  = train.target_names[pred_idx]

    print(f"Predicted category: {pred_cat.split('.')[-1]}  ({probs[pred_idx]:.1%} confidence)")
    print(f"\nAll probabilities:")
    for i, p in enumerate(probs):
        print(f"  {train.target_names[i].split('.')[-1]:12} {p:.2%}")

    # Top keywords
    tfidf    = pipeline.named_steps['tfidf']
    clf      = pipeline.named_steps['clf']
    features = tfidf.transform([text]).toarray()[0]
    feat_names = np.array(tfidf.get_feature_names_out())
    top_idx  = features.argsort()[-top_n:][::-1]
    print(f"\nTop keywords: {list(feat_names[top_idx])}")

new_article = """
The team scored three goals in the second period to win the championship.
The goalie made 42 saves in a historic performance. Playoffs start next week.
"""
classify_and_explain(new_article)
💡 Tip: TF-IDF stands for Term Frequency - Inverse Document Frequency. It upweights words that are common in a document but rare across the whole corpus — so "puck" scores high in a hockey article but "the" does not.

🎉 You Did It!

96% accuracy with zero neural networks — just TF-IDF and Naive Bayes. For many text classification tasks, this simple pipeline outperforms complex deep learning models and runs in milliseconds. Use it for email routing, ticket triage, and content moderation.

Found something wrong?

Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.