← Back to projects

Case study

Marketplace Discovery Platform

Session feed ranking and hybrid search with offline eval, serving, and a product-style demo.

At a glance

Plain summary for recruiters and visitors. Technical detail follows below.

What it is
I built a marketplace discovery lab with session feed ranking and hybrid search on public event logs. Offline eval beats popularity on the sample holdout.
What I owned
Solo end to end. Ingest, DuckDB features, feed and search rankers, FastAPI serving, pytest contracts, and the frozen portfolio demo.
Why it matters
Shows how buyer-side teams can ship ranked feeds and search with honest baselines before scaling to full catalog traffic.
Try it on this page vs full project
This page runs frozen feed and search chips on a toy catalog. The full FastAPI console and training stack stay on request.
Marketplace Discovery Platform

Problem

Marketplace buyers need relevant session feeds and search results. Teams need honest offline eval before scaling rankers to full traffic.

Method

Built ingest, DuckDB features, feed candidates with two-tower retrieval and LightGBM rerank, plus BM25 hybrid search with intent rules and policy filter. Evaluated with session leave-one-out and curated query sets.

Result

Feed v1 NDCG@10 about 0.42 and Recall@10 about 0.68 on the sample holdout. Search v1 NDCG@10 1.00 on curated queries. Recruiters can try frozen feed and search chips on this page. Full training repo stays on request.

Architecture

How the system is shaped. Full implementation stays private.

  1. Step 1

    Ingest

    Bronze CSV to silver parquet with schema validation and quarantine on bad rows.

  2. Step 2

    Features

    DuckDB views for item popularity decay, member session stats, and catalog joins.

  3. Step 3

    Rank

    Feed track: co-occurrence candidates, two-tower retrieval, LightGBM rerank. Search track: BM25 hybrid retrieve, intent classifier, policy filter, LightGBM rerank.

  4. Step 4

    Serve

    FastAPI with /feed/recommend and /search/rank plus product console. Portfolio demo serves frozen golden outputs on Cloudflare or locally.

Sample holdout metrics (session LOO feed, curated search queries)

RetailRocket-style sample catalog in the portfolio lab. Feed v1 uses candidates, two-tower retrieval, and LightGBM LambdaRank. Search v1 uses BM25 hybrid retrieve, intent rules, policy filter, and LightGBM rerank.

TrackNDCG@10Note
Feed popularity baselineNDCG 0.12Recall 0.36
Feed v1NDCG 0.42Recall 0.68
Search BM25-onlyNDCG 0.99MRR 1.00
Search v1NDCG 1.00MRR 1.00

Algorithm

Two-track discovery with offline eval gates

Train feed and search rankers offline, evaluate with session holdout and curated queries, then serve through a shared catalog registry.

feed_candidates = cooccur(session) + category_pool + popularity
feed_scores = lgbm_rank(two_tower(session), feed_candidates)
search_hits = bm25_hybrid(query) |> policy_filter
search_scores = lgbm_rank(query_features, search_hits)
ship when ndcg@10 beats baseline on frozen splits

Key logic

Compact illustrative snippet (Policy filter before search rerank (illustrative)). Not the full codebase.

def filter_item_ids(item_ids, policy):
    blocked = policy.blocked_categories or set()
    return [i for i in item_ids if catalog[i].category_id not in blocked]

Stack

Recommendation SystemsSearch RankingLightGBMDuckDBFastAPIPrometheusPythonOffline Eval

Try feed and search

Frozen sample catalog from the portfolio lab. Switch between session feed ranking and hybrid search. Full FastAPI serving stack stays on request.

Source code

Full source is available to hiring managers on request. The public page shows architecture, algorithms, and compact proofs only.