A review site stores each review as a dictionary of word counts, for example {"great": 2, "battery": 1}. Think of every possible word as one position of a very long vector; a review has a count at the positions of its words and 0 everywhere else, so the dictionary only stores the non-zero entries.
Write review_similarity(a, b) that returns the cosine similarity of the two reviews: their dot product divided by the product of their Euclidean lengths. A review with no words (an empty dictionary) points nowhere; if either review is empty, return 0.0.
Because only the direction counts, a short review and a long review that use words in the same proportions have similarity 1.0.
Examples
Input: a = {"great": 2, "battery": 1}, b = {"great": 4, "battery": 2}
Output: 1.0
Explanation: b is twice as long as a, with the words in the same proportions.
Input: a = {"great": 1, "screen": 1}, b = {"great": 1, "battery": 1, "slow": 2}
Output: 0.2886751345948129
Explanation: only "great" is shared, so the dot product is 1. The lengths are the square roots
of 2 and 6, and 1 / sqrt(12) = 0.2887.
Input: a = {"loud": 3}, b = {}
Output: 0.0
Constraints
- each dictionary has at most
10**4words; every count is a whole number with1 <= count <= 1000 - answers are compared with a tolerance of
1e-6
Goals
- Treat a dictionary of word counts as a vector with one position per word
- Compute a dot product that only needs the words both texts share
- Explain why cosine similarity ignores how long each text is