All work
RECOMMENDER SYSTEMS · COLLABORATIVE FILTERING

Amazon Recommendation System

Four generations of recommender on 65K Amazon Electronics ratings — from a popularity baseline through user- and item-based KNN to matrix factorization. Tuned SVD wins, and stays personalized exactly where KNN breaks on sparse data.

0.8808
best RMSE (tuned SVD)
65K
ratings analyzed
4
model generations
Surprise
+ scikit-learn stack
The problem
Recommend the right product from a matrix that is 99.3% empty.

1,540 users × 5,689 products makes ~8.76 million possible pairs — with only 65,290 actual ratings. Almost every prediction a recommender makes here is about a user-product pair it has never seen.

The result
0.8808 RMSE — tuned SVD beat every KNN variant.

Matrix factorization won on both error and ranking quality (precision@10 of 0.855), ahead of item-item KNN at 0.9615 and user-user KNN at ~1.00.

The insight
On sparse data, KNN quietly stops personalizing.

When a user has no rated neighbors — the common case at 99.3% sparsity — KNN falls back to global averages and the recommendation stops being personal. SVD's latent factors keep predictions individual even for pairs it never observed.

The tuning
GridSearchCV cut item-item KNN error from 0.9950 → 0.9615.

Systematic hyperparameter search improved every model family — recall@10 rose from 0.845 to 0.878 for item-item KNN, and SVD's epochs, learning rate and regularization produced the final 0.8808.

The build
Four model generations, one honest evaluation.

Popularity baseline → user-user KNN → item-item KNN → SVD, all judged on the same protocol: RMSE plus precision, recall and F1 at top-10 — built with Surprise, scikit-learn and pandas.

01The problem

Recommender systems are judged on data they will never see. The dataset here is 65,290 Amazon Electronics ratings spanning 1,540 users and 5,689 products — which sounds substantial until you multiply it out. Those users and products form roughly 8.76 million possible pairs, so the ratings that actually exist fill 0.7% of the matrix. Everything else is empty.

That sparsity is the whole problem, not a footnote to it. A model that scores well on the ratings it has seen is easy; the question is what happens for a user and a product that have never met. At 99.3% sparsity, that's almost every recommendation the system will ever make.

02The approach

Four generations of recommender, each one answering a weakness in the last, all judged under an identical protocol:

Each model was scored on RMSE plus precision, recall and F1 at top-10 — error and ranking quality together, because a recommender that predicts ratings accurately can still put the wrong ten things on the page. Every family then went through GridSearchCV, so the comparison is between tuned models rather than defaults. Built with Surprise, scikit-learn and pandas.

03The results

Tuned SVD won on both axes — 0.8808 RMSE with precision@10 of 0.855. Item-item KNN followed at 0.9615, and user-user KNN trailed at roughly 1.00, barely distinguishable from predicting the average.

Tuning mattered, and it mattered unevenly. GridSearchCV moved item-item KNN from 0.9950 to 0.9615 and lifted its recall@10 from 0.845 to 0.878; searching SVD's epochs, learning rate and regularization produced the final 0.8808. The ordering of the model families held before and after tuning — hyperparameters sharpened each approach without rescuing the weaker ones.

04What I learned

On sparse data, KNN quietly stops personalizing. This is the finding that actually changed how I read the numbers. When a user has no rated neighbors — the common case at 99.3% sparsity — a neighborhood model has nothing to average over and falls back to a global mean. It still returns a prediction, and the RMSE still looks reasonable, but the recommendation has stopped being about that person. SVD's latent factors keep predictions individual even for pairs it never observed, which is why the gap widens exactly where recommendations matter most.

A metric can pass while the product fails. Nothing in the RMSE column announces that a model has degenerated into recommending averages. You only see it by asking what the model does for its hardest users, not its average one — which is a habit worth carrying into any system judged on aggregate error.

Want the details?

The full notebook — the four model generations, the tuning runs and the top-10 evaluation — is on GitHub.