3.1 KiB
RANKING — Bike-Tinder
The deck is ordered by predicted taste. Three rungs, in order: the hunt's existing rubric (v1), a cheap explainable boost from swipe clusters (v1.x), then a small learned model (Phase 3). Nothing ever becomes a black box.
Signals
- Like = strong positive (+1). Maybe = weak positive (+0.25, kept in its own bucket). Nope = negative (−1). List-view edits count identically to in-deck swipes; the latest call wins.
- Planned v2 signals: dwell time on card, "open listing" click-outs.
Features (v1)
Per listing: family tier (from the hunt rubric), displacement (cc), price, year, km, km/year, dealer vs private, place/region, keyword flags from title + description (MVI/inspection, whitewalls, spokes, windshield, saddlebags, ABS, bobber/custom), color words (red is known lore), title tokens (make/model). Numeric features normalized; missing values neutral.
- Single-source v1 makes source/region features near-constant — kept in the schema for v2.
Stage 1 — Cold start
Order by the hunt's existing rubric score (family tiers + MVI / whitewalls / windshield / spokes / ABS bonuses + price fit). This is already explainable (reason strings exist in the hunt system). Deck = rubric order until ≥ 20 swipes.
Stage 1.5 — Cheap swipe boost (v1.x, post-launch)
Before any model exists, the importer can nudge score with plain swarm signals — e.g. +N when recent likes cluster in a family, small time-decay otherwise — recomputed each import, zero ML, fully explainable. Ships as v1.x if Glenn wants it; v1 itself stays pure rubric.
Stage 2 — Learned order (Phase 3 roadmap)
- Model: logistic regression on the features above; target = like vs nope (maybes contribute softly positive). Trained on all swipe history including edits.
- Pure-Python or numpy implementation (tiny data — no heavy ML dependency). Params + training metadata live in the DB; versioned.
- Retrain nightly right after import; on-demand retrain available from the app.
- Guardrails:
- Blend: until 100 swipes, deck order = 50% rubric rank + 50% model rank; after, model order with an exploration slice (roughly every 8th card = top-rubric card not yet shown).
- Never hide: everything stays in List; ranking only reorders the deck.
- Sanity: if model like-rate underperforms the rubric baseline (tracked weekly), it reverts to rubric order silently.
Explainability
Each card can show up to 2 chips: top positive contributions for that bike ("low km for the money", "Vulcan family", "red", "MVI"). Chips derive from the live feature contributions; during cold start they come from the rubric's existing reasons.
Evaluation
- Track: swipes/session, like-rate trend, maybe-rate, undo rate, and "liked-item rank" (how deep liked items sat — should trend shallow).
- Notifications (decided 2026-11-10): in-app "new since last visit" badge only — no Conduit pushes. A weekly digest remains possible later if asked for.
Open decisions
- Maybe-handling: weak positive + separate bucket (proposed) vs pure third bucket — confirm with Glenn at Phase 2.
- Distance feature (map-based proximity) — likely v2.