To compare two items, you look at the users who rated both. Plain cosine similarity on their raw ratings has a problem: a user who rates everything 4 or 5 makes every pair of items look similar, because all their numbers are high.
Adjusted cosine removes each user's generosity before comparing. Subtract that user's mean from both of their ratings, then take the cosine of what's left:
Task: write adjusted_cosine(ratings, item_a, item_b) returning that similarity, rounded to 4 decimal places.
ratings is a list of rows, one per user, one column per item, with None for unrated.0.0.0 — which happens when every contributing user rated both items exactly at their own mean — return 0.0 instead of dividing by zero.The result runs from -1 to 1. Near +1 means users who liked one liked the other; near -1 means they systematically disagreed; near 0 means knowing one tells you nothing.
The word "adjusted" is the whole lesson. Centring per user inside an item-to-item comparison is a slightly odd-looking move, and it's precisely what strips out the one confound that would otherwise dominate: how high a given person's ratings run.