Recommendations Target Function
Making suggestions with confidence
Check This First!This article refers to BaseModel accessed via Docker container. Please refer to Snowflake Native App section if you are using BaseModel as SF GUI application.
This guide explains how to build a recommendation target function that converts behavioral data into a model-ready target (a sketch). It also demonstrates more advanced techniques, e.g. how to steer the function toward acquisition or retention use cases, or how to leverage multiple event tables to mitigate data sparsity.
Common use cases for recommendation task:
- Retailers suggesting products for loyalty reward campaigns
- Streaming platforms recommending content to personalize experiences
- E-commerce sites tailoring homepages with personalized brand sections
- Financial institutions offering credit cards, loans, or investment products
- Travel platforms suggesting relevant destinations, packages, or activities
Overview
A recommendation target function transforms behavioral inputs (historical and future events), optional attributes and context into a sketchβ a compact representation of target item distribution.
Optional operations may include:
- Trimming the history or future inputs using a time window
- Grouping, filtering, or aggregating events
- Emphasizing recency through flexible weighting
- Steering the model toward acquisition or retention via event filtering and optional loss masking
- Adding or multiplying sketches to mitigate data sparsity
Hereβs the general function flow:
def target_fn(_history: Events, future: Events, _entity: Attributes, _ctx: Dict) -> Sketch:
# (optional) trim history or future time windows
# (optional) filter events for acquisition or retention focus
# transform events, (optionally) apply weighting and/or loss masking
# convert into sketch
return sketch(entity_ids, training_weights)
We will not cover inputs or time-window logic here, as these are consistent across all target functions. See:
Below, we focus on recommendation-specific transformations.
Key Transformations
Providing a sketch as model target
What Is a Sketch?
A sketch is BaseModelβs compact, lossless summary of item interactions. It approximates the distribution and frequency of items in behavioral data, enabling scalable modeling of large catalogs.
NoteSketches use proprietary technologies β Cleora (for learning inter-entity interaction graphs) and emde (for grouping similar objects efficiently). These can incorporate additional modalities such as product descriptions or images. See our blog post for details.
When fine-tuning a foundation model for recommendations, sketches allow the model to output the entities that the main entity (e.g., user) is most likely to interact with.
To construct a sketch, you must:
- Select the events representing interactions with the target entity (e.g., product IDs).
- Decide how to weight events depending on when they occurred.
Event Weighting
BaseModel provides two main strategies for assigning temporal weights:
Sequential Decay
The sequential_decay
function applies weights by the order of baskets, ignoring time intervals.
Parameters:
events
: filtered future events for weightinggamma
: multiplier controlling decay speed- 0.0: only first event (basket) counts, all others are multiplied by 0 (default)
- 1.0: equal weights (no decay)
- between 0 and 1: exponential decay, each subsequent event weighs less (e.g., 0.5 β 1, 0.5, 0.25, 0.125β¦)
Usage:
weights = sequential_decay(future_events, gamma=0.5)
Time Decay
The sequential_decay
function applies weights based on elapsed time, ignoring the number of events.
Parameters:
events
: filtered future eventsdaily_decay
: multiplier controlling time-based decay- 0.0: only the first event (basket) counts
- 1.0: equal weights (no decay)
- between 0 and 1: daily decline (e.g., 0.5 β Day 0: 1.0; Day 1: 0.5; Day 2: 0.25β¦)
Usage:
weights = time_decay(events, daily_decay=0.8)
Please noteThe basket is defined as products that have the same timestamp at the time of purchase.
Output: Returing a sketch
To construct a sketch, use the sketch
function passing 2 arguments:
- items:
ModalityEvents
β pointing to column that holds the item entity (product, service, destination, etc.) - weights:
np.array
β numerical weights per event (e.g., prioritizing the next basket, as explained above)
Example: simple recommender for retail campaign
from typing import Dict
from monad.ui.module import RecommendationTask
from monad.ui.target_function import (
Attributes,
Events,
Sketch,
sequential_decay,
sketch
)
def target_fn(_history: Events, future: Events, _entity: Attributes, _ctx: Dict) -> Sketch:
future_transactions = future["transactions"]
sketch_items = future_transactions["article_id"]
sketch_weights = sequential_decay(future_transactions, gamma=0)
transactions_sketch = sketch(sketch_items, sketch_weights)
return transactions_sketch
Optional Transformations
Item Filtering & Loss Masking
By default, recommendations include both new and historical items. Item filtering can be filtering to steer model:
- acquisition mode β new interactions only (exclude historical items)
- retention mode β prioritize known items (only historical items)
You can also apply loss masking, so that filtered-out items do not contribute to the training loss. To enable loss masking:
- import
sketch_filtering_mask
frommonad.ui.target_function
- create a separate masking sketch from the historical items
- return it alongside the main target sketch.
Loss masking should only be applied to
OneHotRecommendationTask
problems, where it is applied to Binary Cross Entropy loss function. This requires the target item to be represented as a categorical variable, either via BaseModelβs built-in heuristics or by being explicitly overridden during foundation model training.
Example: Acquisition-focused target function with loss masking:
from typing import Dict
from monad.ui.module import OneHotRecommendationTask
from monad.ui.target_function import (
Attributes,
Events,
Sketch,
sequential_decay,
sketch,
sketch_filtering_mask
)
def target_acquisition_fn(history: Events, future: Events, _entity: Attributes, _ctx: Dict) -> Sketch:
# Applying item filtering to kick in acquisition mode:
products_in_history = set(history["transactions"].modality_events["PROD_ID"])
future = future["transactions"].filter(by="PROD_ID", condition=lambda x: x not in products_in_history)
# Filtering out users with no future
if future.count() == 0:
return None
# Creating target sketch
sketch_items = future["PROD_ID"]
sketch_weights = sequential_decay(future, gamma=1)
transactions_sketch = sketch(sketch_items, sketch_weights)
# Creating masking sketch
filtering_sketch = sketch_filtering_mask(history["transactions"]["PROD_ID"])
# Returning both sketches
return transactions_sketch, filtering_sketch
Arithmetic operations on sketches
Sketches support addition and multiplication by numeric weights. This is useful e.g. when data is sparse where product purchase transactions are sparse: a hybrid target sketch can be constructed by aggregating sketches from different event sources.
Example: combining transactions (weighted more heavily) with product views into one sketch:
transaction_sketch = sketch(
items = future["transactions"]["article_id"],
weights = sequential_decay(events = future["transactions"], gamma = 0),
)
view_sketch = sketch(
items = future["product_views"]["article_id"],
weights = sequential_decay(events = future["product_views"], gamma = 0),
)
hybrid_sketch = 10 * transastion_sketch + view_sketch
This approach enriches the representation by incorporating broader interaction signals, making the hybrid sketch a more reliable proxy for the limited transaction data.
End-to-end example of a recommendation target function
Please refer to the recipe linked below for an example of target function for a retail industry use case: recommend products for the next basket that a shopper will likely buy.
Updated 19 days ago