Building a Product Recommendation Engine with InputLayer

Building a Product Recommendation Engine with InputLayer

A customer buys a Canon EOS R5 camera. Your recommendation engine suggests a Nikon lens, a Sony memory card holder, and a generic phone case. The customer clicks through, orders the Nikon lens, discovers it doesn't fit, returns it, and writes a one-star review about how your site "doesn't even know what goes with what." Meanwhile, the Canon-compatible lens was in stock the whole time. Your model just couldn't see the logical relationship between a camera and its compatible accessories, because those items look nothing alike when you compare their descriptions numerically.

This is the gap between similarity by description and actual product logic. A camera and a camera bag aren't similar. One is an electronic device and the other is a fabric container. But one is an accessory for the other, and your customers expect you to know that. The same gap shows up when inventory changes faster than your model retrains: recommending out-of-stock items, suggesting products in categories the customer has never shown interest in, or missing the obvious cross-sell because the connection is structural, not textual.

In this tutorial, we'll build a recommendation engine that combines four signals: collaborative filtering, category affinity, similarity by meaning, and explicit accessory relationships. Each signal is a readable rule. The engine combines them automatically and keeps recommendations fresh as inventory and purchase history change. No model retraining, no index rebuilding.

What we're building

By the end of this tutorial, you'll have a recommendation engine with four distinct signals:

Recommendation Engine
Collaborative Filtering
Category Affinity
Similarity by Meaning
Accessory Relationships

Results are combined, de-duplicated, and filtered: already purchased items are excluded, out-of-stock items are excluded, and discontinued items are removed automatically.

Each signal is expressed as a simple, readable rule. The engine combines them automatically. And because this runs on a knowledge graph with incremental computation, the recommendations stay fresh without model retraining or index rebuilding.

Step 1: Model your product catalog

Everything starts with your product data. In InputLayer, this means storing structured facts about products, their categories, and how categories relate to each other.

You store each product with its name and direct category. Then you describe the category hierarchy. Running shoes fall under athletic footwear, which falls under footwear, which falls under apparel. This hierarchy is the backbone for one of our recommendation signals.

You also store numerical descriptions for each product, generated by converting product text into numbers the engine can compare. These power the similarity-by-meaning signal.

Sports
Athletic
Footwear: Running Shoes, Trail Shoes
Accessories: Socks, Hydration Pack
Electronics: GPS Watch

Step 2: Feed in user behavior

Next, purchase history and browsing data. Who bought what, and what have they been looking at recently. In production, you'd ingest this from your transaction database as events happen.

Purchases
user_1: Running Shoes, Socks
user_2: Running Shoes, Hydration Pack
user_3: Trail Shoes, GPS Watch
Browsing
user_1: Trail Shoes, GPS Watch

The important thing: these aren't just rows in a table. They're facts in a knowledge graph that the reasoning engine can combine with other facts through rules. That's the key difference from a static lookup table.

Step 3: Define recommendation rules

This is where the approach diverges from traditional ML recommendations. Instead of training a model, we express recommendation logic as rules. Each rule captures a different signal, and each rule is readable in plain English.

Rule 1 - Collaborative filtering: "If two users bought the same product, the other products each user bought become recommendations for the other." This is the classic "customers who bought X also bought Y" pattern. But it's expressed as a rule, not a statistical model, which means you can read it, debug it, and explain exactly why a recommendation appeared. When a customer asks "why was I shown this?", the answer traces back to specific purchases by specific users, not an opaque number the model learned.

What this looks like in practice for user_1:

user_1
Running Shoes
user_2
Hydration Pack

Rule 2 - Category affinity (recursive): "If a user bought something in one category, recommend products from related categories." This rule is recursive. It follows the category hierarchy to find related categories at any depth.

Running Shoes
Footwear --under-> Athletic
Athletic
Accessories
Electronics

Buying running shoes surfaces recommendations not just from footwear, but from accessories and electronics too, because they share a parent category. And this works no matter how deep or wide your category tree goes.

Rule 3 - Similarity by meaning: Products whose descriptions mean similar things become recommendations. This catches relationships that the category hierarchy misses. Two products from completely different categories that people tend to use together.

Rule 4 - Accessory relationships: "When a customer buys a product, recommend its accessories, but only if they haven't already bought them and they're in stock." This is the explicit knowledge that a camera bag goes with a camera, expressed directly rather than inferred statistically.

Step 4: Combine and query

Now you ask: "What should we recommend to user_1?"

The engine evaluates all four rules, combines their results, filters out products user_1 has already bought, checks stock availability, and returns the final list:

Signals for user_1
Collaborative: Hydration Pack
Category: Hydration Pack, GPS Watch, Trail Shoes
Similar meaning: Trail Shoes (0.92)
Accessory: none
1

Trail Shoes: category + similar meaning

strongest signal

2

Hydration Pack: collaborative + category

two signals

3

GPS Watch: category only

single signal

Each recommendation carries its reasoning trail. You can explain to the user why each item was recommended, and you can explain to your product team which signals are driving the most engagement. The explanations are deterministic rule chains, not after-the-fact guesses bolted on top of a black box.

Step 5: Watch it stay fresh

Here's where the knowledge graph approach really shines compared to model-based recommenders.

A new purchase comes in. User_1 buys a GPS Watch. You add that fact. All recommendations update instantly. GPS Watch drops out of user_1's recommendations (already purchased), and any collaborative filtering signals that involve GPS Watch recalculate. No model retraining needed.

A product goes out of stock. You update the stock status for Trail Shoes. Every recommendation that included Trail Shoes disappears from results automatically. When it's back in stock, the recommendations come back. No index rebuild needed.

A product is discontinued. You retract it from the catalog entirely. InputLayer's correct retraction mechanism removes it from every recommendation result, every collaborative filtering signal, every category association, automatically and immediately. No stale suggestions pointing customers to a product page that returns a 404.

Batch ML recommender
Retrain (hours)
Rebuild index
Deploy
InputLayer
Retract fact
Updated (ms)

Where to take this next

What we've built is the foundation. Here are the layers you'd add for production:

Inventory-aware filtering. Only recommend products that are actually in stock and available in the customer's region. This is one more condition on the recommendation rule.

Time decay. Weight recent purchases more heavily than old ones. A customer who bought running shoes yesterday is more likely to need accessories than a customer who bought them two years ago.

Price affinity. Recommend products in the customer's typical price range. If they buy premium products, don't recommend budget options.

Seasonal rules. Boost winter gear in November, swimwear in May. Express seasonality as a rule rather than baking it into a training set.

Each of these is just another rule in the knowledge graph. The engine handles the interactions between all rules automatically. You don't need to worry about how time decay interacts with category affinity, or how inventory filtering affects collaborative signals. Define the rules, and the engine composes them.

Check out the data modeling guide for patterns that work well at scale, and the Python SDK for integrating this into your e-commerce platform.

Ready to get started?

InputLayer is open-source. Pull the Docker image and start building.