Cinemap is a discovery engine over 140,000+ films and shows that turns every title into a point in a learned 85-dimensional space — fusing 35 LLM-scored emotional dimensions with a social graph of who-makes-what into a GNN. One embedding space; a web feed and a five-tab mobile app built on top of it.
Most recommenders treat a film as a bag of categorical tags. So they hand you more of the same.
Genre says Inception is "sci-fi / action." Even micro-genres like "mind-bender" are still insufficient. The key is marrying micro-genres with emotional feel to capture genuine neighbours.
Two films can share zero genres yet feel like siblings. No metadata field encodes that. Cinemap's bet was to learn it instead.
Concatenate two orthogonal axes of what a film is into a single 85-dimensional embedding. Once a film is a point, every product surface becomes geometry: browse is sampling, similarity is nearest-neighbors, personalization is navigating toward your taste.
An LLM scores every title across 35 continuous emotional dimensions — humour, darkness, tension, awe, existential weight — giving a dense, polarity-rich fingerprint that genres can't express.
Films and the people who make them form a weighted bipartite graph. A spectral embedding over it captures the latent collaborative manifold — the who-works-with-whom signal no field encodes.
The web "For You" feed personalizes client-side from implicit signals — how long you dwell on a trailer, what you skip — with no account. A calibration bar shows the model warming up in real time.
Open any title and the “More Like This” rail is pure geometric retrieval — approximate nearest neighbors in the 85-d space, oversampled and diversity-capped so a single prolific director can't dominate the results.
The mobile app is React Native / Expo. Every discovery surface reads the same query vector — media type, mood sliders, themes, streaming services — and hits a different strategy against the same learned manifold.

A full-bleed, auto-playing feed with the title's emotional radar overlaid and live mood chips.

Drag dots on the radar to filter by feeling — the affective axis turned into a direct-manipulation control.

Curated tags — Cyberpunk, Home Invasion, '70s Paranoia — combined as OR sets and used as a diversity constraint.

A wizard that turns "what do you wish you could watch for the first time?" into seed nodes for the engine.

Curated and user lists — editorial collections sit beside anything the community makes public.

A masonry of posters with a human voice — “movies my friend Mike will enjoy over 4–5 Miller Lites.”

Ratings, streaming, trailer and the signature radar — the affective fingerprint made legible.

Per-country availability with array-overlap filtering, so results respect the services you pay for.
← scroll · drag to explore the surfaces →
Nine of the 35 affective dimensions, drawn as a radar, became Cinemap's defining visual. It's a read-out on every title — and, with draggable dots, a control that filters the catalog by feeling.
Now showing: Inception
A Python representation-learning pipeline ingests the catalog and learns the node embeddings — then every product surface just queries the same space.
Browse without a full-table scan: partition the id-space into strata, probe a few per stratum, and rotate 3 random affective dims per call so every batch is vibe-coherent but fresh.
Similarity, guided and co-watch are ANN in 85-d. Filtered ANN uses a CTE-join pattern to dodge HNSW's pre-filter hijack, with a per-director diversity cap.
A user is a small set of k-means centroids in the same space as the films. ~75% exploitation by proximity, ~25% serendipity capped to one per microgenre.
Cinemap is a solo passion project that I've been working on since 2020. Always looking for feedback, ideas, or to just talk about movies.