I implemented the LSH path and interface integration. My teammate built the random-projection forest and data preprocessing.
Making an algorithm usable
Steam Game Similarity is an interactive comparison of three approaches to finding related games: brute-force cosine search, a random-projection forest and random-hyperplane locality-sensitive hashing. The application turns those methods into an understandable workflow: choose a game, select a search method and inspect the recommendations.
I implemented the LSH path and the Streamlit interface and integration helpers. My teammate Colby developed the preprocessing and RP Forest. Keeping those responsibilities explicit matters: the shared application compares three methods, while my main algorithmic contribution is the hash-based candidate search. My neighbor-search implementation, LSH source, application helpers.
Retrieve candidates, then compare them precisely
Each game is represented by a normalized feature vector. My LSH implementation creates several sets of random hyperplanes. For each table, the signs of a vector's dot products with those planes form a hash key; vectors with the same key enter the same bucket. Hash construction.
A query follows the same hashing path, collects its matching buckets and deduplicates their members. It then computes cosine similarity for those candidates, sorts the scores and returns the nearest results. The index-based query explicitly removes the input game's ID. This keeps candidate retrieval separate from final ranking and gives both stages a clear responsibility. Query implementation.
The tradeoff is approximation. A relevant game can fall outside every retrieved bucket, and a small candidate set can return fewer than the requested number of results. Adding tables can improve the chance of retrieving a neighbor while increasing index size and query work. Changing the number of planes affects how selectively the buckets divide the data. These choices need to be evaluated together rather than reduced to a single latency number.
What the implementation costs
Let N be the number of games, d the vector dimension, T the table count and P the planes per table. Construction performs O(NTPd) projection work, alongside expected hash-table operations. The inspected defaults are 10 tables and 16 planes per table. LSH construction and defaults.
At query time, let B be the total bucket entries visited before deduplication and C the number of unique candidates. Projection, retrieval and scoring contribute O(TPd + B + Cd). The code then uses a full NumPy sort of the candidate scores, typically adding O(C log C) work. It does not use a top-k heap.
These are source-derived estimates, not benchmark results or a guarantee of sublinear search. If buckets become broad enough that C approaches N, much of the advantage disappears. Memory also includes projection vectors, per-table index entries and bucket keys in addition to the original feature matrix. Implementation details.
The application changes the timing question
The Streamlit helpers cache approximate index construction so interactive queries can reuse it. The brute-force path, however, reloads the matrix and fits a nearest-neighbor model within its helper call. As a result, the displayed timings mix different amounts of preparation and query work. They should not be interpreted as a controlled speedup comparison. Caching and query helpers, loading and brute-force path.
That distinction is useful engineering context: a responsive product workflow and a fair algorithm benchmark answer different questions. A stronger comparison would preload the same data, separate construction from queries, fix seeds and query sets, and measure recall@k alongside candidate counts, memory and latency distributions. The current LSH projections do not use an explicit fixed seed.
Demonstration and remaining work
The live application provides an interactive path through the search methods. A recorded demonstration is available when the hosted app is waking or unavailable. The recording shows the application workflow; it is not a substitute for a repeatable benchmark.
The repository's main evidence is its implementation and demonstration, rather than an automated regression suite. Useful next checks include empty candidate sets, duplicate vectors, self-exclusion and recall against exact neighbors. The project gives me a concrete way to discuss algorithm design, application integration and why a measurement's setup matters as much as its displayed result. Audited source revision.
Source evidence
Implementation and recorded evidence checked on November 5, 2026.
- ContributionLSH neighbor search · contribution
- SourceLSH implementation
- SourceComparison & cache boundaries