An interviewer asks: "Which product is most like this one? Write cosine similarity with numpy only." The idea in one sentence: describe each product by a row of numbers, then divide the dot product of two rows by their two lengths multiplied; you get 1 for the same direction, 0 for nothing in common and -1 for opposite directions.
Here each row says how many of a product each of 5 customers bought. a @ b is the dot product: it multiplies two rows position by position and adds the results. np.linalg.norm(a) gives back a row's length, the square root of the sum of its squares. np.argmax(scores) gives back the position of the biggest number.
a = np.array([1, 0])
b = np.array([3, 4])
print(a @ b) # 3, from 1*3 + 0*4
print(np.linalg.norm(b)) # 5.0, the square root of 9 + 16
print(np.argmax(np.array([0.2, 0.9, 0.4]))) # 1
The length of a is 1, so the cosine similarity of these two rows is 3 / (1 × 5) = 0.6. Dividing by the lengths removes size: a row with every number doubled still scores 1 with the original. To find the product most like product i, score it against every row and take the biggest score, but rule the product itself out first, since a row always scores 1 with itself.
The script must print:
Mug and Teapot: 0.982 Mug and twice the Mug: 1.0 Mug and Notebook: 0.0 Most like the Mug: Teapot Most like the Pen: Notebook Opposite directions: -1.0 Most like each product: ['Teapot', 'Mug', 'Pen', 'Notebook', 'Mug'] Same as scikit-learn's cosine_similarity on random rows: True
Your task: write cosine(a, b), then finish most_similar(i): a loop that scores row i of bought against every row, and a line that sets the product's own score to -1.
Assignment
Follow the Coding Tutorial to write cosine similarity and use it to find each product's closest match.
Hint
Put the two lengths in parentheses so they multiply before you divide. -1 is the lowest a cosine can be, so a product whose own score is -1 never picks itself.
Free plan: 30 tutor messages. PRO is unlimited.
