Skip to content
BytePatterns

Nearest Documents by Cosine

MediumAI & ML#vector-math#partial-sort~20m

Problem

A help-centre search embeds every article as a vector and embeds the user's question the same way. Given the query vector, a dict from article name to vector, and k, return the k articles with the highest cosine similarity to the query as (name, score) pairs, scores rounded to 3 decimals, best first. Equal scores are ordered by name so the result is stable. A zero vector has no direction, so it is never returned, and a zero query returns nothing. There can be 100,000 articles while k is small, so avoid sorting all of them.

Examples

Input:  query = [1.0, 0.2, 0.0], k = 2, articles = refunds [0.9, 0.1, 0.0], shipping [0.1, 0.9, 0.1],
        returns [0.8, 0.3, 0.1], careers [0.0, 0.1, 0.9], blank [0, 0, 0]
Output: [('refunds', 0.996), ('returns', 0.98)]
Input:  query = [2, 0, 0], k = 2, articles = b [1, 0, 0], a [3, 0, 0], c [0, 1, 0]
Output: [('a', 1.0), ('b', 1.0)]
Why:    length does not matter to cosine, so a and b tie and the name decides
Input:  query = [0, 0, 0], k = 3, the articles from the first example
Output: []
Why:    edge case, a zero query points nowhere

Hints

0 / 3

Stuck on the idea rather than the code? Cosine Similarity covers it.