Blog image

Published 13 June 2026 | Updated 29 October 2026

AI/ML

How to Build a Content-Based Recommendation System: A Practical Guide With Python Code

What Is a Content-Based Recommendation System?

A content-based recommendation system recommends items whose features are similar to items a user has already shown interest in. If a reader finishes three articles about electric cars, it suggests other articles about electric cars and batteries; if a shopper views running shoes with a certain cushioning and price, it suggests shoes with similar attributes. The system only needs to understand the items and one user's own history, not the behaviour of other users.

If you'd rather have one built into your product, our AI integration services team can add recommendations to your existing app or website.

Quick answer

A content-based recommendation system suggests items that are similar to what a user already liked, by comparing the items' own attributes, such as text, category, tags, price or images. You build one in five steps: collect item data, turn each item into a numeric vector (with TF-IDF or modern text embeddings), build a profile of each user from the items they interacted with, score candidate items by similarity (usually cosine similarity) and rank, filter and serve the top results. Content-based systems work from day one for new items and need no data about other users, which makes them the best starting point for most catalogues, content sites and job or property platforms. This guide explains how they work, compares them with collaborative and hybrid systems, and walks through working Python code, evaluation and scaling to millions of items with vector search.

Table of Contents

Share Article

  • Content-based filtering recommends items similar to a user's past likes, using item features rather than other users' behaviour.
  • It solves the new-item cold start problem and is easy to explain (“because you read…”), but it can become repetitive.
  • In 2026, sentence embeddings and multimodal embeddings beat TF-IDF on most text and product catalogues; TF-IDF is still a strong, cheap baseline.
  • Vector databases such as pgvector, Qdrant, Milvus or OpenSearch make similarity search fast at millions of items.
  • Most production systems end up hybrid: content-based for new items and users, collaborative filtering once interaction data grows, and a re-ranking step for business rules.

Content-Based vs Collaborative vs Hybrid Recommendations

ComparisonContent-based filteringCollaborative filteringHybrid
What it usesItem features (text, tags, category, price, images) and the user's own historyInteractions of many users (views, purchases, ratings)Both, plus context and business rules
New itemsRecommended immediatelyCan't be recommended until people interact with themHandled by the content part
New usersNeed a few interactions or stated interestsNeed interactionsUse popularity or onboarding choices first
Discovery of new interestsLow: tends to suggest more of the sameHigh: finds what similar people likedHigh
ExplainabilityEasy (“similar to X”)HarderMedium
Data neededGood item metadataLarge volumes of interaction dataBoth
Best forNews, blogs, jobs, real estate, new catalogues, B2BLarge marketplaces, streaming, social appsMost mature products

How a Content-Based Recommender Works

  1. 1. Represent Each Item. Turn each item's content into a vector: TF-IDF weights for words, embeddings from a language or image model, plus encoded categories, tags and numeric attributes.
  2. 2. Build a User Profile. Combine the vectors of items the user viewed, saved or bought, weighting stronger signals (purchase over view) and recent actions more heavily.
  3. 3. Measure Similarity. Compare the user profile, or the item being viewed, with all candidate items, usually with cosine similarity.
  4. 4. Rank and Filter. Take the top matches, remove items already seen or out of stock, and apply rules such as availability, region or price range.
  5. 5. Serve and Learn. Show recommendations, log clicks and conversions, and use that feedback to tune weights or move to a hybrid model.

Item-to-Item vs User-Profile Recommendations

TypeQuestion it answersExample
Item-to-item (“similar items”)What else is like this item?“More like this” on a product or article page
User profile (“for you”)What will this person like next?A personalised home feed or weekly email
Query-basedWhat matches what the user just described?“Show me laptops like this but lighter” in an AI shopping assistant

Build a Content-Based Recommender in Python, Step by Step

The example below recommends products, but the same code works for articles, jobs, courses or properties. It uses pandas and scikit-learn (pip install pandas scikit-learn).

  1. Step 1: Prepare Item Data. Put one row per item with an ID and the fields that describe it: title, category, tags and description. Clean the text (remove HTML, fix duplicates) and fill missing values; poor metadata is the most common reason content-based recommendations look random.
  2. Step 2: Turn Items Into Vectors. Combine the text fields and convert them to TF-IDF vectors, which weight words that are frequent in one item but rare across the catalogue.
  3. Step 3: Find Similar Items. Compare one item's vector with all others using cosine similarity and return the closest matches.
  4. Step 4: Build User Profiles. Average the vectors of items a user interacted with, giving stronger actions such as purchases more weight than views.
  5. Step 5: Rank, Filter and Serve. Remove items the user already has, apply business rules and return the top results through an API.
import numpy as np
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

# 1. Item data: one row per item
items = pd.DataFrame({
    "item_id": [1, 2, 3, 4, 5],
    "title": ["Trail running shoes", "Road running shoes", "Waterproof hiking boots",
              "Lightweight running jacket", "Yoga mat"],
    "category": ["shoes", "shoes", "boots", "apparel", "fitness"],
    "description": [
        "Grippy trail shoes with rock plate for off-road running",
        "Cushioned road shoes for daily running and marathons",
        "Leather hiking boots, waterproof, ankle support for trails",
        "Breathable, packable jacket for running in wind and rain",
        "Non-slip mat for yoga and home workouts",
    ],
})

# 2. Turn each item into a vector (title + category + description)
items["text"] = items["title"] + " " + items["category"] + " " + items["description"]
vectorizer = TfidfVectorizer(stop_words="english", ngram_range=(1, 2))
item_vectors = vectorizer.fit_transform(items["text"])

# 3. "More like this": items similar to one item
def similar_items(item_id, top_n=3):
    idx = items.index[items["item_id"] == item_id][0]
    scores = cosine_similarity(item_vectors[idx], item_vectors).ravel()
    scores[idx] = -1  # don't recommend the item itself
    best = np.argsort(scores)[::-1][:top_n]
    return items.iloc[best][["item_id", "title"]].assign(score=scores[best].round(3))

# 4 and 5. "For you": a weighted user profile, then rank and filter
def recommend_for_user(interactions, top_n=3):
    # interactions: {item_id: weight}, e.g. view=1, add to cart=3, purchase=5
    idx = [items.index[items["item_id"] == i][0] for i in interactions]
    weights = np.array(list(interactions.values()), dtype=float)
    profile = np.asarray(item_vectors[idx].T.dot(weights) / weights.sum()).reshape(1, -1)
    scores = cosine_similarity(profile, item_vectors).ravel()
    scores[idx] = -1  # hide items the user already has
    best = np.argsort(scores)[::-1][:top_n]
    return items.iloc[best][["item_id", "title"]].assign(score=scores[best].round(3))

print(similar_items(1))                  # road running shoes ranks first
print(recommend_for_user({1: 5, 4: 1}))  # bought trail shoes, viewed a jacket

TF-IDF only matches exact words, so “trail” and “trails” or “sneakers” and “running shoes” look unrelated. That is why most teams now move to embeddings.

Upgrade to Embeddings for Better Results

Text embeddings place items with similar meaning close together even when they use different words, and multimodal models such as CLIP can compare product images too. Swap the TF-IDF step for an embedding model (pip install sentence-transformers):

from sentence_transformers import SentenceTransformer

model = SentenceTransformer("all-MiniLM-L6-v2")  # small, fast, runs on CPU
item_vectors = model.encode(items["text"].tolist(), normalize_embeddings=True)

# With normalised vectors, cosine similarity is a dot product
scores = item_vectors @ item_vectors[0]  # similarity to item 1

For large catalogues, store the vectors in a vector index and query the nearest neighbours instead of comparing every item. With PostgreSQL and pgvector:

CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE items (id bigint PRIMARY KEY, title text, embedding vector(384));
CREATE INDEX ON items USING hnsw (embedding vector_cosine_ops);

-- 10 items most similar to item 42
SELECT id, title, 1 - (embedding <=> (SELECT embedding FROM items WHERE id = 42)) AS score
FROM items
WHERE id <> 42
ORDER BY embedding <=> (SELECT embedding FROM items WHERE id = 42)
LIMIT 10;

Choosing How to Represent Items

MethodBest forProsCons
TF-IDF or BM25Small catalogues, keyword-heavy text, a quick baselineFast, cheap, explainableMisses synonyms and meaning
Structured features (one-hot categories, scaled price, tags)Products, jobs, property listingsPrecise control over what mattersNeeds good metadata and feature weighting
Sentence embeddings (open-source or API)Articles, products, courses, support contentUnderstands meaning across different wording and languagesNeeds a model and vector storage
Multimodal embeddings (text plus image)Fashion, furniture, art, real estate photosMatches visual styleMore compute and storage
Combined vectorMost real cataloguesText meaning plus hard attributesRequires tuning weights

How to Evaluate Your Recommender

MetricWhat it tells youWhen to use it
Precision@K and Recall@KHow many of the top K suggestions the user actually engaged withOffline tests on historical data
NDCG@KWhether the best items appear near the topOffline ranking quality
CoverageShare of the catalogue that ever gets recommendedSpotting a system that only promotes a few items
Diversity and noveltyHow different recommendations are from each other and from what the user has seenAvoiding repetitive feeds
Click-through and conversion rateReal user behaviourOnline A/B tests
Revenue or watch time per sessionBusiness impactFinal decision on a new model

Test offline first by hiding each user's most recent interactions and checking whether the system recommends them, then confirm with an A/B test against your current experience (for example “most popular”).

Common Problems and How to Fix Them

Recommendations Are Too Similar

Add diversity re-ranking such as maximal marginal relevance, mix in popular or trending items, and limit how many items come from one category or brand.

New Users Have No History

Ask for interests during onboarding, use the current session or search query, and fall back to popular items in the user's region.

Poor Item Metadata

Enrich listings with consistent categories and tags; an LLM can generate structured attributes and summaries from messy descriptions.

Some Features Matter More Than Others

Weight fields separately (for example title higher than description) or learn the weights from click data.

Stale or Unavailable Items

Filter by stock, date, location and eligibility at query time, not when vectors are built.

Slow Responses at Scale

Precompute item-to-item neighbours, use approximate nearest-neighbour indexes and cache results for popular items.

Scaling to Millions of Items

ScaleRecommended setup
Up to about 100,000 itemsEmbeddings in memory or PostgreSQL with pgvector; nightly batch updates
100,000 to 10 million itemsA vector database (Qdrant, Milvus, Weaviate, OpenSearch or Elasticsearch k-NN) with HNSW indexes, streaming updates for new items
Very large or real-timeTwo stages: fast candidate retrieval from the vector index, then a learning-to-rank model that adds user, context and business signals

Adding LLMs to Content-Based Recommendations

Better item understanding

use an LLM to extract attributes, tags and summaries from long descriptions before embedding them.

Natural-language requests

let users ask for “a waterproof jacket like this but cheaper” and turn the request into a vector search plus filters.

Explanations

generate short, honest reasons such as “because you read three articles on EV batteries”.

Keep the LLM out of the hot path

for speed and cost, use it offline or for re-ranking a short list, not for scoring the whole catalogue.

Where Content-Based Recommendations Work Best

IndustryExample
Media and publishingRelated articles, newsletters and podcast episodes based on topics and entities
Ecommerce“Similar products” and visually similar items for new or long-tail catalogues
Jobs and recruitmentMatching candidates and jobs by skills, seniority and location
Real estateProperties similar in location, price, size and amenities
EducationCourses and lessons matched to a learner's goals and level
B2B and SaaSHelp articles, templates and integrations based on what a customer uses
TravelHotels and experiences similar in style, area and price

How Much Does It Cost to Build a Recommendation System?

ScopeWhat's includedCostTimeline
Content-based MVPItem vectors, similar items and “for you” API, basic filters, offline evaluation$10,000–$25,0003–6 weeks
Production recommenderEmbeddings, vector database, real-time updates, A/B testing, dashboards, diversity and business rules$25,000–$70,0002–4 months
Hybrid personalisation platformContent plus collaborative models, learning-to-rank, real-time events, LLM features, multiple surfaces (web, app, email)$70,000–$200,000+4–8 months

Running costs are usually modest: embedding a catalogue of 100,000 items with an open-source model costs little more than a few hours of compute, and a managed vector database typically costs from $50 to a few hundred dollars a month at that size.

Frequently Asked Questions

Quick answers related to this article from PerfectionGeeks.

1. What is a content-based recommendation system?

A system that recommends items similar to those a user already liked, by comparing item features such as text, category, tags, price or images, rather than the behaviour of other users.

2. How is content-based filtering different from collaborative filtering?

Content-based filtering uses item attributes and one user's history. Collaborative filtering uses patterns across many users, such as “people who bought this also bought that”.

3. What are the advantages of content-based filtering?

It recommends new items immediately, needs no data from other users, is easy to explain and works well for niche catalogues.

4. What are the limitations?

It tends to recommend items too similar to past ones, depends on good item metadata and still needs a few interactions to understand a brand-new user.

5. Which similarity measure should I use?

Cosine similarity is the standard for text and embedding vectors. For numeric attributes such as price or size, scale them first or use a weighted distance.

6. Should I use TF-IDF or embeddings?

Start with TF-IDF as a quick baseline; move to sentence or multimodal embeddings when you need to match meaning, synonyms, multiple languages or images.

7. How do I solve the cold start problem?

For new items, content-based filtering already works. For new users, ask for interests at sign-up, use the current session and show popular items until you have a few interactions.

8. Which Python libraries are used?

pandas and scikit-learn for TF-IDF and similarity, sentence-transformers for embeddings, FAISS or a vector database for search, and frameworks such as LightFM or TensorFlow Recommenders for hybrid models.

9. How do I evaluate recommendations?

Offline with precision@K, recall@K, NDCG, coverage and diversity on held-out interactions, then online with A/B tests on click-through, conversion or engagement.

10. Can a content-based system work with millions of items?

Yes. Store embeddings in a vector index (HNSW) such as pgvector, Qdrant, Milvus or OpenSearch and retrieve nearest neighbours in milliseconds.

11. When should I move to a hybrid system?

When you have enough interaction data that collaborative signals add value, typically thousands of active users with regular engagement, and when you need more discovery than “more of the same”.

12. How much does it cost to build a recommendation system?

A content-based MVP costs $10,000–$25,000, a production system with embeddings, vector search and A/B testing $25,000–$70,000, and a hybrid personalisation platform $70,000 or more.

Conclusion

Need a Recommendation Engine for Your Product?

PerfectionGeeks builds recommendation systems for ecommerce, media, jobs, education and SaaS products, from a content-based MVP to hybrid personalisation with vector search and LLMs. Share your catalogue size, data and goals, and within 2 business days we'll recommend an approach, a cost range and a timeline, under an NDA.

Get a Free Recommendation Engine Estimate

blog-author

Written By Shrey Bhardwaj

Director & Founder

Shrey Bhardwaj is the Director & Founder of PerfectionGeeks Technologies, bringing extensive experience in software development and digital innovation. His expertise spans mobile app development, custom software solutions, UI/UX design, and emerging technologies such as Artificial Intelligence and Blockchain. Known for delivering scalable, secure, and high-performance digital products, Shrey helps startups and enterprises achieve sustainable growth. His strategic leadership and client-centric approach empower businesses to streamline operations, enhance user experience, and maximize long-term ROI through technology-driven solutions.