Take the 2-minute tour ×


Can you show the vectors here (in a list or something) And then do the math, and let us see how it works?

I'm a beginner.

share|improve this question
the wiki has a reference to a tutorial, did you have a look at that? cosine-similarity-tutorial.html –  Daniel Nov 17 '09 at 4:21

8 Answers 8

up vote 130 down vote accepted

Here are two very short texts to compare:

Text 1: Julie loves me more than Linda loves me

Text 2: Jane likes me more than Julie loves me


me Julie loves Linda than more likes Jane


me 2 2

Julie 1 1

likes 0 1

loves 2 1

Jane 0 1

Linda 1 0

than 1 1

more 1 1


The two vectors are, again:

a: [2, 1, 0, 2, 0, 1, 1, 1]

b: [2, 1, 1, 1, 1, 0, 1, 1]

The cosine of the angle between them is about 0.822.


share|improve this answer
thanks a lot for PERFECT and CLEAR explanation –  Bakhtiyor Feb 7 '11 at 22:09
Is there any way to normalize for document length? –  sinθ Jan 11 at 23:05

I'm guessing you are more interested in getting some insight into "why" the cosine similarity works (why it provides a good indication of similarity), rather than "how" it is calculated (the specific operations used for the calculation). If your interest is with the latter, see the reference indicated by Daniel in this post, as well as a related SO Question.

To explain both the how and even more so the why, it is useful, at first, to simplify the problem and to work only in two dimension. Once you get this in 2D, it is easier to think of it in 3 dimensions, and of course harder to imagine in many more dimensions, but by then we can use linear algebra to do the numeric calculations and also to help us think in terms of lines/vectors / "planes" / "spheres" in n dimensions even though we can't draw these.

So... in two dimensions: with regards to text similarity this means that we would focus on two distinct terms, say the words "London" and "Paris", and we'd count how many times each of these word is find in each of the two documents we wish to compare. This gives us, for each document a point in the the x-y plane, for example if Doc1 had Paris once, and London four times, a point at (1,4) would present this document (with regards to this diminutive evaluation of documents). Or, speaking in terms of vectors, this Doc1 document would be an arrow going from the origin to point (1,4). With this image in mind, let's think about what it means to be similar for two documents and how this relate to the vectors.

VERY similar documents (again with regards to this limited set of dimensions) would have the very same number of references to Paris, AND the very same number of references to London, or maybe, they could have the same ratio of these references (say a Document Doc2, with 2 refs to Paris and 8 Refs to London, would also be very similar, only maybe a longer text or somehow more repetitive of the cities' names, but in same proportion: Maybe both documents are guides about London, only making passing references to Paris (and how uncool that city is ;-) Just kidding!!!). Now less similar documents, may too, include references to both cities, but in different proportions, Maybe Doc2 would only cite Paris Once and London 7 times.

Back to our x-y plane, if we draw these hypothetical documents, we see that when they are VERY similar their vectors overlap (though some vectors may be longer), and as they start to have less in common, these vectors start to diverge, to have bigger angle between them.

Bam! by measuring the angle between the vectors, we can get a good idea of their similarity , and, to make things even easier, by taking the Cosine of this angle, we have a nice 0 to 1 (or -1 to 1, depending what and how we account for) value that is indicative of this similarity. The smaller the angle, the bigger (closer to 1) the cosine value, and also the bigger the similarity.

At the extreme, if Doc1 only cites Paris and Doc2 only cites London, the documents have absolutely nothing in common. Doc1 would have its vector on the x-axis, Doc2 on the y-axis, the angle 90 degrees, Cosine 0. (BTW that's what we mean when we say that two things are orthogonal to one another)

Adding dimensions:
With this intuitive feel for similarity expressed as a small angle (or big cosine), we can now imagine things in 3 dimensions, say bringing in the word "Amsterdam" in the mix. And visualize, quite well, how a document with two references of each would have a vector going in a particular direction and we can see how this direction would compare to a document citing Paris and London 3 times each but not Amsterdam etc.. As said we can try and imagine the this fancy space for 10 or 100 cities, hard to draw, but easy to conceptualize.

I'll wrap up by just saying a few words about the formula itself. As said other references provide good information about the calculations.

Again first in 2 dimensions. The formula for the Cosine of the angle between two vectors is derived from the trigonometric difference (between angle a and angle b)


This formula look very similar to the dot product formula:


Where cos(a) matches the x value and sin(a) the y value, for the first vector. etc. The only problem, is that x, y etc. are not exactly the cos and sin values, for these values need to be read on the unit circle. That's where the denominator of the formula kicks in: by dividing by the product of the lengh of these vectors, the x and y coordinates become normalized.

share|improve this answer
This is also a great answer, thanks! –  TIMEX Nov 17 '09 at 19:45

Here's my implementation in C#.

using System;

namespace CosineSimilarity
	class Program
		static void Main()

			var cosSimilarity = CalculateCosineSimilarity(vecA, vecB);


			var dotProduct = DotProduct(vecA, vecB);
			var magnitudeOfA = Magnitude(vecA);
			var magnitudeOfB = Magnitude(vecB);

			return dotProduct/(magnitudeOfA*magnitudeOfB);

			// I'm not validating inputs here for simplicity.            
			double dotProduct = 0;

			return dotProduct;

		private static double Magnitude(int[] vector)
			return Math.Sqrt(DotProduct(vector, vector));
share|improve this answer


a = c(2,1,0,2,0,1,1,1)

b = c(2,1,1,1,1,0,1,1)


or taking advantage of crossprod() method's performance...


share|improve this answer

For simplicity I am reducing the vector a and b:

Let :
    a : [1, 1, 0]
    b : [1, 0, 1]

Then cosine similarity (Theta):


then inverse of cos 0.5 is 60 degrees.

share|improve this answer


import math
from collections import Counter

def buildVector(iterable1, iterable2):
    counter1 = Counter(iterable1)
    counter2= Counter(iterable2)
    vector1 = [counter1[k] for k in all_items]
    vector2 = [counter2[k] for k in all_items]
    return vector1, vector2

def cosim(v1, v2):
    return dot_product / (magnitude1 * magnitude2)


v1,v2= buildVector(l1, l2)
print (cosim(v1, v2))
share|improve this answer
Nice, clear and neat. –  Navonod May 15 at 11:39
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

* @author Xiao Ma
* mail : 409791952@qq.com
  public class SimilarityUtil {

    Integer temp = null;
    for (String leftWord : left) {
        temp = leftWordCountMap.get(leftWord);
        if (temp == null) {
            leftWordCountMap.put(leftWord, 1);
        } else {
            leftWordCountMap.put(leftWord, temp + 1);
    for (String rightWord : right) {
        temp = rightWordCountMap.get(rightWord);
        if (temp == null) {
            rightWordCountMap.put(rightWord, 1);
        } else {
            rightWordCountMap.put(rightWord, temp + 1);
    int index = 0;
    Integer tempCount = 0;
    for (String uniqueWord : uniqueSet) {
        tempCount = leftWordCountMap.get(uniqueWord);
        tempCount = rightWordCountMap.get(uniqueWord);
    return consineVectorSimilarity(leftVector, rightVector);

 * in-between values indicating intermediate similarity or dissimilarity.
 * a method of normalizing document length during comparison.
 * cannot be greater than 90°.
 * @param leftVector
 * @param rightVector
 * @return
private static double consineVectorSimilarity(int[] leftVector,
        int[] rightVector) {
    if (leftVector.length != rightVector.length)
        return 1;
    double dotProduct = 0;
    double leftNorm = 0;
    double rightNorm = 0;

    double result = dotProduct
    return result;

public static void main(String[] args) {
            "loves", "me" };
            "loves", "me" };


share|improve this answer

This is a simple Python code which implements cosine similarity.

from scipy import linalg, mat, dot
import numpy as np


In [13]: matrix
share|improve this answer

Your Answer


