A search query and a document can each be represented as a vector: a list of numbers describing feature strengths. Cosine similarity compares their directions to produce a score for ranking documents. The same measure can compare dense embeddings that encode the meaning of phrases or items. section 3.1 section 2.3
Calculate it by dividing the vectors’ dot product by the product of their magnitudes: cosine similarity = dot(query, document) / (magnitude(query) × magnitude(document)). The dot product rewards features shared by both vectors; dividing by their lengths scales the result. Compute a score for each document, then sort by score. section 2.3 section 3.1.2
Why matching every query term may still leave a tie
For the query “apple juice,” two documents receive the same cosine score, 0.2828, when compared using their longer term vectors. Restricting all three vectors to the two query-term features gives [1, 1] for each and a score of 1.0 for each document. The absolute scores change because the representations change; neither calculation distinguishes the documents. Feature selection and weighting therefore matter alongside the similarity formula. section 3.1.2 section 3.1.3
Listing 3.1 Calculating cosine similarity between vectors
query_vector = numpy.array( [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) doc1_vector = numpy.array( [0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0]) doc2_vector = numpy.array( [1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1]) def cosine_similarity(vector1, vector2): return dot(vector1, vector2) / (norm(vector1) * norm(vector2)) doc1_score = cosine_similarity(query_vector, doc1_vector) doc2_score = cosine_similarity(query_vector, doc2_vector) print_scores([doc1_score, doc2_score])
Inspect the NumPy vectors and cosine_similarity function to see how query–document scores are computed. section 3.1.2
For semantic comparisons, encode phrases as dense embeddings, normalize each embedding to unit length, and take dot products to obtain cosine similarities. A four-phrase example ranks “it's raining hard” closest to “it is wet outside.” Comparing every phrase with every other phrase creates a square similarity table, so its computation and storage costs grow as the number of phrases grows. section 13.4.3













