Skip to main content

Complementary items

This page covers complementary items queries for recommending items that go well with a set of items. For query fundamentals, see Query Basics.

A complementary items query recommends items that go well with a set of items, typically items in a shopping cart or a viewing session. Use this for "customers also bought" or "goes well with" recommendations.

The key difference from similar items is that complementary items find items that complete or enhance the set rather than items that are similar.

Implementation approach

Complementary items are typically implemented by training a collaborative model on purchase interactions, where a bag of interactions refers to a user session of purchases at a nearby time. You often want to treat the user session as the unique user id rather than just persistent user_id (so that bags don't overlap).

For retrieval, use a combination of rules, collaborative similarity, and content similarity. For scoring, use a model that can score based on an interaction sequence input (e.g., item2vec), then pass the cart_ids as interaction_ids directly into the input of the scoring model. You'll also want to add a filter so that anything in the cart is removed from the candidates.

Complementary items for a cart

Prerequisites

  1. An engine with item data configured
  2. A trained collaborative model on purchase interactions (using session-based user IDs)
  3. A trained sequence-based scoring model (e.g., item2vec)
  4. A set of item IDs in the cart

Query example

This example retrieves candidates using multiple strategies, scores them with a sequence-based model, and filters out cart items:

from shaped import RankQueryBuilder, SimilarItems, Filter

# Example cart item IDs
cart_ids = ["item1", "item2", "item3"]

# Build the complementary items query
query = (
RankQueryBuilder()
.from_entity('item')
.retrieve([
# Get candidates from collaborative filtering
SimilarItems(
item_ids=cart_ids,
model='collaborative',
limit=100
),
# Get candidates from content-based similarity
SimilarItems(
item_ids=cart_ids,
model='content',
limit=100
),
# Get candidates from category-based rules
Filter("category = $category")
.limit(100)
])
.filter(f"item_id NOT IN $cart_ids") # Remove items already in cart
.score(
value_model='sequence_model_score($cart_ids, item_id)',
input_user_id='$user_id',
input_interactions_item_ids='$interaction_item_ids'
)
.limit(10)
.build()
)

# Example usage with client
# response = client.rank(
# query=query,
# parameters={
# 'cart_ids': cart_ids
# }
# )
#
# complementary_items = [item['item_id'] for item in response['items']]

This query:

  1. Retrieves candidates from three sources:
    • Collaborative similarity (items frequently bought together)
    • Content similarity (items with similar attributes)
    • Popular items (fallback for coverage)
  2. Filters out items already in the cart
  3. Scores candidates using item2vec with the cart items as the interaction sequence
  4. Returns the top 10 complementary items

Training considerations

When training the collaborative model for complementary items:

  • Use purchase interactions (not views or clicks)
  • Group interactions by user session (not persistent user_id)
  • A session represents a bag of interactions (purchases at nearby times)
  • This ensures bags don't overlap and the model learns true complementarity