surfmatch / README.md
Yoad22's picture
Upload README.md with huggingface_hub
89e9c57 verified
|
Raw History Blame Contribute Delete
4.44 kB
---
title: SurfMatch
emoji: ๐Ÿ„
colorFrom: blue
colorTo: red
sdk: gradio
sdk_version: '5.9.1'
app_file: app.py
pinned: false
---
# SurfMatch
**Dataset:** Yoad22/surfmatch-dataset - 15,000 synthetic rider profiles, 150-board catalog
**Embedding model:** sentence-transformers/all-mpnet-base-v2 - 768-dimensional embeddings
**Generation model:** Qwen/Qwen3-1.7B - structured custom board spec + rationale
**Space:** https://huggingface.co/spaces/Yoad22/surfmatch
---
## What This Is
A surfboard recommendation app. Tell it your height, weight, skill level, current board,
typical conditions, and what you're trying to achieve, and it returns the 3 closest-matching
boards from a 150-board catalog, plus a 4th board that a small language model designs
specifically for you, including dimensions, tail, fins, construction, and a written rationale.
The app is built to also serve surfers who want to *change* styles, not just riders shopping
within the style they already have.
---
## How It Works
**1. Category** is decided from the rider's stated goal and skill level using a fixed rule,
not from text similarity. Testing embeddings for this decision directly (see Key Results)
showed they aren't reliable enough for it on their own.
**2. Physical fit** combines two real sizing guidelines: heavier and less experienced riders
need more volume, and taller and less experienced riders want relatively more length, each
measured as a percentile within the board's own category (categories differ hugely in scale,
so raw liters or feet aren't comparable across them).
**3. Embedding similarity** (all-mpnet-base-v2) ranks boards within the already-correct
category by how well a rider's profile matches each board's description - the comparison the
model is demonstrably good at.
**4. Diversity** picks the final 3 boards so they differ from each other on tail, fins, or
construction, instead of returning 3 near-identical boards.
**5. The 4th board** is generated by Qwen3-1.7B: given the rider's percentiles and the
category's real dimension ranges, the model is asked to reason about the right sizing in
words first, then commit to dimensions, tail, fins, construction, and a rationale, as
structured JSON. It's explicitly allowed to make unconventional choices (e.g. quad fins on a
longboard) that the fixed 150-board catalog doesn't offer.
---
## Key Results
| Metric | Value |
|---|---|
| Boards in catalog | 150 |
| Rider profiles generated | 15,000 |
| Embedding model hit_rate@1 (vs. 20% random baseline) | 41.6% |
| Embedding model hit_rate@3 (vs. 49% random baseline) | 45.0% |
| Silhouette score by true category (PCA-50 space) | 0.053 |
| Diversity: hit real per-category ceiling on tail | 100.0% |
| Diversity: hit real per-category ceiling on fins | 97.3% |
| Diversity: hit real per-category ceiling on construction | 96.3% |
| Diversity: hit the ceiling on all three at once | 93.7% |
| Custom board JSON parse rate | ~90% |
The embedding model captures real signal about a rider's best-fit category (41.6% top-1
accuracy against a 20% random baseline), but that signal is not clean enough to decide the
category on its own - the silhouette score of 0.053 confirms categories overlap heavily in
embedding space. That's why category is decided by a fixed rule and embeddings are used only
to rank within a category, where they change at least one of the three recommended boards
for roughly half of all riders tested - real, independent work, not a no-op.
---
## An Honest Limitation
The custom board generator's written reasoning (`sizing_reasoning`) explicitly and correctly
describes how a rider's weight and height percentiles should affect the board's dimensions in
nearly every case. But across three separate real experiments at 30-rider scale - raw
numbers, percentile-grounded numbers, and percentile-grounded numbers with forced
reasoning-before-numbers - the model's actual output dimensions barely correlated with
weight or height (correlation near 0 each time), while skill-based sizing worked reliably
and correctly (correlation consistently and correctly signed). In other words: this small
model's stated reasoning is not fully faithful to what actually drives its numeric output.
This is a genuine, tested limitation of a 1.7B-parameter model on this task, documented here
rather than hidden - the skill-based sizing and the category/tail/fins/construction choices
all work as intended.
---