MSB
All posts

ShopRec: A Recommendation API for When the Data Is Thin

A recommendation service built to handle the awkward cases a notebook never has to, reviewed honestly for what synthetic data can and can't prove.

Why build another recommender

Recommendation models are easy to prototype and surprisingly awkward to run as a service. A notebook can show that matrix factorization finds patterns in purchase history, but it never has to answer what to show a brand-new user, what happens when the model isn't loaded, or why a particular product was suggested.

ShopRec was my attempt at the service version: a backend that recommends products from purchase history and treats those awkward questions as part of the design rather than afterthoughts.

How it works

It combines two ways of guessing what someone might want. Collaborative filtering looks at behaviour: it learns hidden patterns from which users bought which products, so you're recommended things that people with similar histories bought. Content-based filtering looks at the products themselves, recommending items similar to ones you already like, which helps with new products that nobody has bought yet.

A hybrid mode blends the two, weighting behaviour at 70% and product similarity at 30% by default, and falls back to collaborative filtering alone if product information isn't available. New users with no history get popular items instead of an error. When asked, the service also explains a recommendation by returning the individual scores and weights behind it.

Around the model sit the things that make it a service: a small FastAPI interface, versioned model files, structured logging, typed errors, Docker packaging, and a 47-test suite spanning unit, integration, and end-to-end tests.

What worked

  • Designing the edge cases first. Cold starts, missing models, and sparse data all have defined behaviour instead of surprising failures.
  • Explainable scores. Being able to see how much of a recommendation came from behaviour versus similarity makes the system much easier to reason about and debug.
  • Graceful fallbacks. The hybrid mode degrading to collaborative filtering keeps the service useful when part of its input is missing.
  • Treating it like production software, with tests at every level and a model that can be retrained without rebuilding the service.

What it can't prove

The honest caveat is the data. ShopRec is trained on generated purchases, 50 users, 100 products, and a thousand transactions, and its product descriptions are simulated. That's enough to exercise every part of the system, but it says nothing about whether these recommendations would be good for real shoppers.

The same goes for anything that looks like tuning. The 70/30 blend is a sensible default, not a weighting learned from real behaviour, and any speed numbers only reflect a dataset this small. The project demonstrates the engineering around a recommender; it doesn't demonstrate recommendation quality.

What would make it real

The next steps are the ones synthetic data can't stand in for: real product information for the content side, a feedback loop so recommendations learn from what people actually click and buy, and A/B testing to find out whether the hybrid blend beats either method on its own.

Key takeaways

  • The model is a small part of a recommender; cold starts, fallbacks, and explanations are the service.
  • Explainable scores turn a black-box ranking into something you can debug.
  • Be explicit about synthetic data so the work is judged on what it actually shows.