¿Alguien puede dar un ejemplo de similitud de cosenos, de una manera gráfica muy simple? [cerrado]
Artículo sobre similitud del coseno en Wikipedia
¿Puedes mostrar los vectores aquí (en una lista o algo así) y luego hacer los cálculos y ver cómo funciona?
Aquí dos textos muy breves para comparar:
Julie loves me more than Linda loves me
Jane likes me more than Julie loves me
Queremos saber qué tan similares son estos textos, puramente en términos de recuento de palabras (e ignorando el orden de las palabras). Comenzamos haciendo una lista de las palabras de ambos textos:
me Julie loves Linda than more likes Jane
Ahora contamos el número de veces que aparece cada una de estas palabras en cada texto:
me 2 2
Jane 0 1
Julie 1 1
Linda 1 0
likes 0 1
loves 2 1
more 1 1
than 1 1
Sin embargo, no nos interesan las palabras en sí. Sólo nos interesan esos dos vectores verticales de conteos. Por ejemplo, hay dos instancias de "yo" en cada texto. Vamos a decidir qué tan cerca están estos dos textos calculando una función de esos dos vectores, es decir, el coseno del ángulo entre ellos.
Los dos vectores son, nuevamente:
a: [2, 0, 1, 1, 0, 2, 1, 1]
b: [2, 1, 1, 0, 1, 1, 1, 1]
El coseno del ángulo entre ellos es aproximadamente 0,822.
Estos vectores son de 8 dimensiones. Una virtud de utilizar la similitud del coseno es claramente que convierte una pregunta que está más allá de la capacidad humana de visualizar en una que puede serlo. En este caso, puede pensar en esto como un ángulo de aproximadamente 35 grados, que es una cierta "distancia" del cero o una concordancia perfecta.
Supongo que está más interesado en obtener una idea de " por qué " funciona la similitud del coseno (por qué proporciona una buena indicación de similitud), en lugar de " cómo " se calcula (las operaciones específicas utilizadas para el cálculo). Si te interesa esto último, consulta la referencia indicada por Daniel en este post, así como una pregunta SO relacionada .
Para explicar tanto el cómo como aún más el por qué, conviene, en un principio, simplificar el problema y trabajar sólo en dos dimensiones. Una vez que obtienes esto en 2D, es más fácil pensar en tres dimensiones y, por supuesto, más difícil imaginarlo en muchas más dimensiones, pero para entonces podemos usar álgebra lineal para hacer los cálculos numéricos y también para ayudarnos a pensar en términos. de líneas / vectores / "planos" / "esferas" en n dimensiones, aunque no podamos dibujarlas.
Entonces, en dos dimensiones : con respecto a la similitud del texto, esto significa que nos centraríamos en dos términos distintos, digamos las palabras "Londres" y "París", y contaríamos cuántas veces cada una de estas palabras se encuentra en cada uno de los dos documentos que deseamos comparar. Esto nos da, para cada documento, un punto en el plano xy. Por ejemplo, si Doc1 tuviera París una vez y Londres cuatro veces, un punto en (1,4) presentaría este documento (con respecto a esta diminuta evaluación de documentos). O, hablando en términos de vectores, este documento Doc1 sería una flecha que va desde el origen hasta el punto (1,4). Con esta imagen en mente, pensemos en lo que significa que dos documentos sean similares y cómo esto se relaciona con los vectores.
Documentos MUY similares (de nuevo con respecto a este conjunto limitado de dimensiones) tendrían el mismo número de referencias a París, Y el mismo número de referencias a Londres, o tal vez podrían tener la misma proporción de estas referencias. Un documento, Doc2, con 2 referencias a París y 8 referencias a Londres, también sería muy similar, sólo que quizás con un texto más largo o de alguna manera más repetitivo de los nombres de las ciudades, pero en la misma proporción. Quizás ambos documentos sean guías sobre Londres, haciendo solo referencias pasajeras a París (y lo poco cool que es esa ciudad ;-) ¡¡¡Es broma!!!.
Ahora bien, documentos menos similares también pueden incluir referencias a ambas ciudades, pero en proporciones diferentes. Quizás Doc2 sólo citaría París una vez y Londres siete veces.
Volviendo a nuestro plano xy, si dibujamos estos documentos hipotéticos, vemos que cuando son MUY similares, sus vectores se superponen (aunque algunos vectores pueden ser más largos), y a medida que comienzan a tener menos en común, estos vectores comienzan a divergir, para tener un ángulo más amplio entre ellos.
Al medir el ángulo entre los vectores, podemos tener una buena idea de su similitud y, para hacer las cosas aún más fáciles, al tomar el coseno de este ángulo, tenemos un buen valor de 0 a 1 o -1 a 1 que es indicativo de esta similitud, dependiendo de qué y cómo tengamos en cuenta. Cuanto más pequeño sea el ángulo, mayor (más cercano a 1) será el valor del coseno y también mayor será la similitud.
En el extremo, si Doc1 sólo cita París y Doc2 sólo cita Londres, los documentos no tienen absolutamente nada en común. Doc1 tendría su vector en el eje x, Doc2 en el eje y, el ángulo de 90 grados, coseno 0. En este caso diríamos que estos documentos son ortogonales entre sí.
Sumar dimensiones :
con esta sensación intuitiva de similitud expresada como un ángulo pequeño (o coseno grande), ahora podemos imaginar cosas en 3 dimensiones, por ejemplo incorporando la palabra "Amsterdam" a la mezcla, y visualizar bastante bien cómo un documento con dos Las referencias a cada uno tendrían un vector que va en una dirección particular, y podemos ver cómo esta dirección se compararía con un documento que cita a París y Londres tres veces cada uno, pero no a Ámsterdam, etc. Como se dijo, podemos intentar imaginar esta fantasía. espacio para 10 o 100 ciudades. Es difícil de dibujar, pero fácil de conceptualizar.
Terminaré diciendo algunas palabras sobre la fórmula en sí . Como dije, otras referencias brindan buena información sobre los cálculos.
Primero en dos dimensiones. La fórmula para el coseno del ángulo entre dos vectores se deriva de la diferencia trigonométrica (entre el ángulo a y el ángulo b):
cos(a - b) = (cos(a) * cos(b)) + (sin (a) * sin(b))
Esta fórmula es muy similar a la fórmula del producto escalar:
Vect1 . Vect2 = (x1 * x2) + (y1 * y2)
donde cos(a)
corresponde al x
valor y sin(a)
al y
valor, para el primer vector, etc. El único problema es que x
, y
, etc. no son exactamente los valores cos
y sin
, ya que estos valores deben leerse en el círculo unitario. Ahí es donde entra en juego el denominador de la fórmula: al dividir por el producto de la longitud de estos vectores, las coordenadas x
y y
se normalizan.
Aquí está mi implementación en C#.
using System;
namespace CosineSimilarity
{
class Program
{
static void Main()
{
int[] vecA = {1, 2, 3, 4, 5};
int[] vecB = {6, 7, 7, 9, 10};
var cosSimilarity = CalculateCosineSimilarity(vecA, vecB);
Console.WriteLine(cosSimilarity);
Console.Read();
}
private static double CalculateCosineSimilarity(int[] vecA, int[] vecB)
{
var dotProduct = DotProduct(vecA, vecB);
var magnitudeOfA = Magnitude(vecA);
var magnitudeOfB = Magnitude(vecB);
return dotProduct/(magnitudeOfA*magnitudeOfB);
}
private static double DotProduct(int[] vecA, int[] vecB)
{
// I'm not validating inputs here for simplicity.
double dotProduct = 0;
for (var i = 0; i < vecA.Length; i++)
{
dotProduct += (vecA[i] * vecB[i]);
}
return dotProduct;
}
// Magnitude of the vector is the square root of the dot product of the vector with itself.
private static double Magnitude(int[] vector)
{
return Math.Sqrt(DotProduct(vector, vector));
}
}
}
Por simplicidad estoy reduciendo el vector a y b:
Let :
a : [1, 1, 0]
b : [1, 0, 1]
Entonces similitud coseno (Theta):
(Theta) = (1*1 + 1*0 + 0*1)/sqrt((1^2 + 1^2))* sqrt((1^2 + 1^2)) = 1/2 = 0.5
entonces la inversa de cos 0,5 es 60 grados.