vectores similitud resueltos entre ejercicios dimensiones definicion coseno como calculo calcular calculadora angulo java vector trigonometry cosine tf-idf

java - resueltos - ¿Cómo calculo la similitud del coseno de dos vectores?



similitud coseno formula (6)

¿Cómo encuentro la similitud del coseno entre los vectores?

Necesito encontrar la similitud para medir la relación entre dos líneas de texto.

Por ejemplo, tengo dos oraciones como:

sistema para la interfaz de usuario

máquina de interfaz de usuario

... y sus respectivos vectores después de tF-idf, seguido de la normalización usando LSI, por ejemplo [1,0.5] y [0.5,1] .

¿Cómo mido la similitud entre estos vectores?


Cuando estaba trabajando con la extracción de texto hace algún tiempo, estaba usando la biblioteca SimMetrics , que proporciona una amplia gama de métricas diferentes en Java. Si sucedió que necesita más, entonces siempre hay R y CRAN para mirar.

Pero codificarlo a partir de la descripción en la Wikipedia es una tarea bastante trivial, y puede ser un buen ejercicio.


Eche un vistazo a: http://en.wikipedia.org/wiki/Cosine_similarity .

Si tienes vectores A y B.

La similitud se define como:

cosine(theta) = A . B / ||A|| ||B|| For a vector A = (a1, a2), ||A|| is defined as sqrt(a1^2 + a2^2) For vector A = (a1, a2) and B = (b1, b2), A . B is defined as a1 b1 + a2 b2; So for vector A = (a1, a2) and B = (b1, b2), the cosine similarity is given as: (a1 b1 + a2 b2) / sqrt(a1^2 + a2^2) sqrt(b1^2 + b2^2)

Ejemplo:

A = (1, 0.5), B = (0.5, 1) cosine(theta) = (0.5 + 0.5) / sqrt(5/4) sqrt(5/4) = 4/5


Para el código matricial en Java, recomendaría usar la biblioteca Colt . Si tiene esto, el código parece (no probado o incluso compilado):

DoubleMatrix1D a = new DenseDoubleMatrix1D(new double[]{1,0.5}}); DoubleMatrix1D b = new DenseDoubleMatrix1D(new double[]{0.5,1}}); double cosineDistance = a.zDotProduct(b)/Math.sqrt(a.zDotProduct(a)*b.zDotProduct(b))

El código anterior también se puede modificar para usar uno de los métodos Algebra.DEFAULT.norm2() o Algebra.DEFAULT.norm2() para el cálculo de la norma. Exactamente el mismo resultado, que es más legible, depende del gusto.


Para la representación dispersa de vectores usando Map(dimension -> magnitude) Aquí hay una versión scala (Puedes hacer cosas similares en Java 8)

def cosineSim(vec1:Map[Int,Int], vec2:Map[Int,Int]): Double ={ val dotProduct:Double = vec1.keySet.intersect(vec2.keySet).toList .map(dim => vec1(dim) * vec2(dim)).sum val norm1:Double = vec1.values.map(mag => mag * mag).sum val norm2:Double = vec2.values.map(mag => mag * mag).sum return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2)) }


Si quiere evitar depender de bibliotecas de terceros para una tarea tan simple, aquí hay una implementación Java simple:

public static double cosineSimilarity(double[] vectorA, double[] vectorB) { double dotProduct = 0.0; double normA = 0.0; double normB = 0.0; for (int i = 0; i < vectorA.length; i++) { dotProduct += vectorA[i] * vectorB[i]; normA += Math.pow(vectorA[i], 2); normB += Math.pow(vectorB[i], 2); } return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB)); }

Tenga en cuenta que la función asume que los dos vectores tienen la misma longitud. Es posible que desee comprobarlo explícitamente por seguridad.


public class CosineSimilarity extends AbstractSimilarity { @Override protected double computeSimilarity(Matrix sourceDoc, Matrix targetDoc) { double dotProduct = sourceDoc.arrayTimes(targetDoc).norm1(); double eucledianDist = sourceDoc.normF() * targetDoc.normF(); return dotProduct / eucledianDist; } }

Recientemente hice algunas cosas para mi unidad de Recuperación de Información en la Universidad. Utilicé este método de similitud Cosine que usa Jama: Java Matrix Package .

Para obtener el código fuente completo, consulte IR Math con Java: Medidas de similitud , un recurso realmente bueno que cubre unas pocas medidas de similitud diferentes.