Collaborative filtering over a user–post likes table: factorise the interaction matrix, find similar users, and recommend what they liked.
Served as a small Flask endpoint.
Recommender pivots the likes table into a user–item matrix, then reduces it with
truncated SVD to 10 latent features:
self.svd = TruncatedSVD(n_components=10)
user_item_matrix_svd = self.svd.fit_transform(self.user_item_matrix)
self.user_similarity = cosine_similarity(user_item_matrix_svd)Similarity is computed in the reduced space rather than on raw likes. Two users who like different individual posts within the same underlying topic still come out similar, which is the point of the factorisation — raw cosine similarity on a sparse matrix would call them unrelated.
Recommendations are then a similarity-weighted sum over what everyone else liked, normalised by total similarity, with the top N returned.
Expects a CSV at data/likes.csv (not committed) with one row per interaction:
user_id,post_id,like
1,101,1
1,104,1
2,101,1pivot_table fills unobserved pairs with 0.
pip install -r requirements.txt
python app.pycurl "http://localhost:5000/recommend?user_id=1&top_n=5"{ "recommended_posts": [104, 92, 17, 55, 3] }An unknown user_id returns 400 — this is pure collaborative filtering, so a user with no
interaction history cannot be served. Handling that cold start would mean falling back to
popularity or content-based ranking.
app.py Flask route
src/recommender.py matrix construction, SVD, similarity, ranking
src/main.py CLI entry point
The model is fit once at construction from the whole CSV, so new likes need a restart to take effect, and the user–item matrix is held entirely in memory. Fine at small scale; a real deployment would want incremental updates and a stored factorisation.