April 14, 2026 · 8 min
Embeddings Beat Ratings: Rebuilding a Movie Recommender
- Recommendation
- Transformers
- FAISS
A classic recommender starts from a user × item rating matrix. That works right up until you have cold users, sparse ratings and items you actually need to explain. For Movie-Recommender I took the other route: learn embeddings, then search them.
What's wrong with the rating matrix
Collaborative filtering treats similarity as a statistic over past ratings. Two movies are similar if the same people rated them the same way. That collapses the moment the matrix is sparse — which it always is — and it has literally nothing to say about a new item with zero ratings. Cold start isn't an edge case; for a growing catalogue it's the default state.
Learning the space
A Siamese Transformer encodes two items at once, and a contrastive loss pulls similar movies together while pushing dissimilar ones apart. What comes out is a space where "similar" is a geometric property of the items themselves — themes, tone, structure — rather than a statistic over who rated what.
The contrastive setup matters. Hard negatives — movies that share a genre but not a sensibility — teach the model where the real boundary is. Easy negatives teach it nothing, because everything is already far apart in a fresh vector space.
Searching it cheaply
Once items are vectors, recommendation is nearest-neighbour search. FAISS indexes the catalogue and returns candidates in milliseconds, so the expensive part — training the encoder — happens offline and serving stays cheap. The index is also cheap to rebuild, which means retraining the encoder doesn't mean re-architecting the service.
What it buys you
A new movie has recommendations on day one because it is embedded, not rated. The recommendation doesn't depend on anyone having watched it yet — only on what the movie is. And because the space is continuous, "more like this, but calmer" becomes a walk through the vectors instead of a pile of filter rules.
The honest trade-offs
Embedding-based recommenders inherit the encoder's blind spots: if the encoder can't see a quality dimension, the space can't represent it. The strongest setup I've found is hybrid — embeddings for candidate generation, a lightweight ranker over both embedding features and behavioral signals for the final ordering. Geometry gets you in the neighborhood; behavior closes the sale.
thanks for reading — more soon ✦