Every recommender starts as a single filter and stays there longer than it should. You ship colour matching, it works, the demo looks great, and the product feels dumb the moment a real user touches it. I spent a while working out why, and the answer turned out to be structural rather than a modelling problem.
Disclosure: I work with Clad9, which is the worked example throughout. The argument is about recommender design, not the product.
The domain, quickly
Wardrobe apps digitise your clothes and tell you what to wear. Simple-sounding, and the category has an unusually high failure rate. Two failures dominate, and only one of them is about recommendations.
Failure 1: the ingestion cliff
Before you can recommend anything, you need the inventory. The classic flow was per-item photography — lay the garment flat, shoot, crop, tag with category/colour/season. Two hundred items.
Look at what that does to the user's cost curve. The entire cost is paid before any value is delivered. There is no partial payoff at item 40; a half-digitised wardrobe is useless because the recommender can't reason over a partial set without producing visibly wrong answers. So the user pays a large, front-loaded, unrewarded cost, and predictably most of them quit somewhere in the first twenty items.
The fix isn't motivational, it's architectural: change the ingestion modality. One video pan across the rail, frames extracted, garments detected and segmented, background removed, attributes tagged automatically. Three minutes of user time instead of an afternoon, and the payoff now arrives before the effort rather than after it.
If you're building anything that needs a user-supplied corpus before it can work — a finance app needing transactions, a fitness app needing a training history, a knowledge tool needing documents — this is the first thing to check. Most "engagement problems" in corpus-dependent products are ingestion-cost problems wearing a disguise.
Failure 2: the single-signal recommender
This is the more interesting one.
Once you have the inventory, the obvious v1 is: pick a signal, rank on it, return the top result. In this domain the candidate signals are colour harmony, body proportion, weather, and occasion. Every one of them is defensible on its own, and every single-signal version produces output that users describe as "technically fine but useless."
Watch the failure modes, because they're characteristic:
colour-only → beautifully coordinated, badly cut
proportion-only → flattering shape, palette drains your face
weather-only → correct insulation, wrong formality entirely
occasion-only → right register, might look terrible on you
Each one is right along its own axis and wrong along the others. And here's the part that matters: users don't perceive this as "one dimension is missing." They perceive it as the system being stupid. A recommendation that's 75% correct doesn't read as 75% good; it reads as broken, because the one wrong dimension is the salient one.
Why the problem is conjunctive
The real query isn't a ranking over one dimension. It's a conjunction:
wearable(outfit) :-
palette_compatible(outfit, user.undertone),
silhouette_compatible(outfit, user.proportions),
warmth_appropriate(outfit, forecast),
formality_appropriate(outfit, calendar.event).
Adding predicates does something specific to the result set: each one cuts it, often hard. Over a real wardrobe, colour alone might leave hundreds of candidates — far too many to rank meaningfully, so your top result is essentially arbitrary among near-ties. Add proportion and it drops sharply. Add weather, then occasion, and you're frequently down to single digits.
That's the actual insight, and it's a bit counter-intuitive if you come from search: the constraints aren't a re-ranking problem, they're a pruning problem. With one predicate you're picking arbitrarily from a huge plausible set. With four you can just return the answer, because there's barely a choice left to make.
It also means output shape should change. A single-signal system almost has to return a ranked list, because it can't justify picking one. A conjunctive system can return one outfit, which is what users actually want — a list of five is the decision fatigue they were trying to escape.
The signal everyone skips
Of the four, occasion is the one most products omit, and it's the highest-information one.
Weather is easy: a public API, a scalar, low integration cost. Calendar is annoying: OAuth, permissions, parsing messy event titles, inferring formality from "Standup" vs "Client review — offsite". So teams ship weather and tell themselves it covers context.
It doesn't. Weather is a scalar — it constrains one dimension. Occasion is categorical over formality and prunes far more aggressively. Two users at 14°C, one going to a client pitch and one to the park, get identical recommendations from a weather-only system and correctly conclude it doesn't understand their day.
General lesson: the highest-value signal is often the one that's most annoying to integrate. Ease of integration and information content are frequently anti-correlated, because everyone already took the easy ones.
Undertone, or: your features may not be the user's features
One domain-specific detail with a general moral.
The naive colour model uses hue relationships — complementary, analogous. It's clean and it's insufficient, because whether two garments work together depends on undertone (warm/cool) relative to the wearer's own colouring, not just the hue relationship. Two textbook-complementary colours can look wrong on a specific person. "Blue" isn't even a specification: cobalt and powder blue behave completely differently next to the same burgundy.
So the natural, mathematically tidy feature — hue angle — is the wrong feature. The right one is a warm/cool decomposition relative to a user parameter. The full reasoning is written up here and it's a nice example of a domain where the obvious representation quietly loses information the users can see.
What this looks like shipped
The feature set reads like a normal list — colour analysis, body-aware styling, calendar, try-on, capsule builder. The thing that isn't visible in a list is whether those are four features sitting next to each other or four predicates over one query. From the outside those look identical. From the inside they're completely different systems, and users can tell within a day which one they're using.
The competitive landscape sorts fairly cleanly along this line: several products are excellent single-signal tools, and their reviews say some version of "great at X, gives weird suggestions."
Takeaways if you're building a recommender
- Check your ingestion cost curve. Front-loaded cost with no partial payoff = an abandonment cliff, and no amount of onboarding polish fixes it.
- Count your predicates. One signal means a large near-tie set and an arbitrary top result.
- Prune, don't rank. Enough constraints and the answer falls out.
- Integrate the annoying signal. It's usually annoying because it's information-dense.
- Question your feature representation. The tidy one may be losing exactly what users perceive.
- Let output shape follow confidence. Returning one answer is a claim you can only make if your pruning earns it.
Top comments (0)