Multi-Objective Recommender System for Marketplaces
A marketplace with 10 million SKUs and 50,000 sellers—the recommender system here doesn't just pick products; it balances relevance, monetization, and seller satisfaction. A typical mistake: sacrificing quality for conversion or vice versa. Recommender systems for marketplaces are a complex engineering product where poor tuning leads to a drop in GMV or seller churn. Our experience shows that the optimal solution is a multi-objective architecture with weights that adjust to business goals.
How Multi-Objective Architecture Resolves the Conflict of Interests?
The key challenge is that the interests of the buyer (finding the right product), the seller (promoting their product), and the platform (earning revenue) often conflict. We implement scoring with multiple objective functions, each with its own weight. For example, relevance—50%, product quality—20%, seller diversity—15%, promoted products—10%, conversion—5%. Weights are selected empirically through A/B tests.
import numpy as np
import pandas as pd
from dataclasses import dataclass
@dataclass
class MarketplaceItem:
item_id: str
seller_id: str
price: float
rating: float
review_count: int
is_promoted: bool
conversion_rate: float
inventory: int
class MarketplaceRecommender:
"""Recommendations with multi-objective balancing"""
def __init__(self, user_model, item_index, seller_index):
self.user_model = user_model
self.item_index = item_index
self.seller_index = seller_index
# Objective function weights
self.weights = {
'relevance': 0.50, # Relevance to user
'quality': 0.20, # Rating and reviews
'seller_diversity': 0.15, # Seller diversity
'promoted': 0.10, # Promoted products
'conversion': 0.05 # Historical CR
}
def recommend(self, user_id: str, context: dict,
n: int = 20) -> list[dict]:
"""Multi-objective recommendations"""
# Retrieval: top candidates by relevance
user_emb = self.user_model.get_user_embedding(user_id)
candidates = self.item_index.search(user_emb, k=200)
# Scoring: multi-objective function
scored = []
seller_count = {}
for item_id, relevance_score in candidates:
item = self._get_item(item_id)
if item is None or item.inventory == 0:
continue
# Product quality
quality_score = (
item.rating / 5.0 * 0.6 +
np.log1p(item.review_count) / 10 * 0.4
)
# Penalty for seller concentration
seller_count[item.seller_id] = seller_count.get(item.seller_id, 0) + 1
seller_diversity = 1 / seller_count[item.seller_id]
# Promoted boost (with limit)
promo_boost = 1.2 if item.is_promoted else 1.0
# Final score
final_score = (
self.weights['relevance'] * relevance_score +
self.weights['quality'] * quality_score +
self.weights['seller_diversity'] * seller_diversity +
self.weights['promoted'] * (promo_boost - 1) +
self.weights['conversion'] * item.conversion_rate
)
scored.append({
'item_id': item_id,
'seller_id': item.seller_id,
'score': final_score,
'relevance': relevance_score,
'quality': quality_score
})
# Sort and return
scored.sort(key=lambda x: x['score'], reverse=True)
return scored[:n]
def _get_item(self, item_id: str) -> MarketplaceItem:
return self.seller_index.get(item_id)
def similar_items_cross_seller(self, item_id: str,
n: int = 6) -> list[dict]:
"""Similar products from other sellers (comparison shopping)"""
item = self._get_item(item_id)
if not item:
return []
similar = self.item_index.search_similar(item_id, k=20)
# Filter: different seller, but similar product
cross_seller = [
s for s in similar
if self._get_item(s[0]) and self._get_item(s[0]).seller_id != item.seller_id
]
return cross_seller[:n]
How to Solve the Cold Start Problem?
New products have no interaction history—standard collaborative filtering does not work. According to Wikipedia on cold start, the problem occurs when a new item has no interactions. Our approach: use content-based boost based on metadata. Products with a high rating (≥4.5) and competitive price receive an initial score of 0.5. Additionally, 8% of traffic is allocated to exploration—the product is shown to a random sample of users. Example exploration strategy
We use 8% of traffic for random display of new products. This allows collecting enough data within 2-3 weeks to switch to a hybrid model.
def handle_new_item_cold_start(self, item: MarketplaceItem,
item_features: dict) -> float:
"""Initial boost for new products"""
base_score = 0.3 # Base position
# Metadata-based boost
if item.rating >= 4.5 and item.review_count >= 10:
base_score += 0.2
if item.price < self._get_category_avg_price(item_features.get('category')):
base_score += 0.1 # Competitive price
# Explore-exploit balance for new products
# Show to 5-10% of traffic to collect data
import random
if random.random() < 0.08: # 8% exploration
return 0.7 + random.random() * 0.3
return base_score
Comparison of Approaches to Interest Balancing — Recommender System Development
| Approach | Objective | Advantages | Disadvantages |
|---|---|---|---|
| Pure relevance | Relevance | High CTR | Ignores monetization, seller dominance |
| Weighted multi-objective | Balance all goals | Flexibility, adjustable to business | Complexity of weight selection |
| Constrained optimization (CCO) | Maximize GMV under constraints | Direct optimization of business metric | Risk of quality reduction under tight constraints |
Multi-objective architecture increases GMV by 1.12-1.2 times compared to pure relevance and boosts CTR by 1.3-1.5 times. This makes it more effective for long-term monetization.
What Does A/B Testing Provide for Recommendations?
Standard metrics: precision@k, recall@k, NDCG are insufficient for a marketplace. We use business metrics: GMV per session, homepage CTR, conversion rate. An A/B test is conducted for at least 2 weeks with 50/50 traffic split. Additionally, we monitor seller satisfaction through a monthly NPS among sellers.
Recommendation Effectiveness Metrics
| Metric | Before Implementation | After Multi-Objective System |
|---|---|---|
| GMV per session | baseline | +12-20% |
| Homepage CTR | baseline | +30-50% |
| Conversion rate | baseline | +5-10% |
Development Process: From Audit to Deployment
- Data audit: analyze interaction logs, product cards, seller profiles. Identify data quality issues and biases (selection bias, popularity bias).
- Architecture design: choose models (embeddings, transformers), define pipeline: batch vs online, select vector DB (ChromaDB, Qdrant).
- Implementation: write production-ready code in PyTorch/Hugging Face, wrap in REST API with p99 latency < 100ms.
- Integration: connect to the storefront, set up data drift monitoring via Weights & Biases.
- A/B testing: run experiment, analyze results, adjust weights.
- Documentation and training: hand over code, model description, maintenance instructions.
What’s Included in Turnkey Development
- Full documentation: architecture description, deployment instructions, maintenance guide.
- Source code of the model and pipeline with comments.
- REST API for storefront integration.
- Setup of data drift monitoring and A/B testing.
- Training of the client's team on the system.
- Technical support during the launch phase.
Timelines and Cost
Timelines: from 4 weeks (MVP) to 3 months (full system). Cost is calculated individually—depends on data volume, integration complexity, and real-time requirements. Get a consultation: we will analyze your data and propose an architecture suited to your business goals. Contact us for a project assessment—our experience includes 20+ implementations for high-turnover marketplaces. We guarantee a transparent process and post-launch support.







