Question

Comment puis-je trouver la similitude cosinus entre les vecteurs?

Je dois trouver la similitude pour mesurer la connexité entre les deux lignes de texte.

Par exemple, j'ai deux phrases comme:

  Système

pour l'interface utilisateur

     

machine d'interface d'utilisateur

... et leurs vecteurs respectifs après-idf, tF suivie par la normalisation en utilisant LSI, par exemple Et [1,0.5] [0.5,1].

Comment puis-je mesurer la smiliarity entre ces vecteurs?

Était-ce utile?

La solution

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;
  }
}

Je l'ai fait des trucs tf-idf récemment pour mon unité de recherche d'information à l'Université. J'ai utilisé cette méthode Cosinus similarité qui utilise Jama:. Package Java matrice

Pour le code source complet voir IR Math Java: mesures de similarité , vraiment bonne ressource qui couvre un bon peu différentes mesures de similarité.

Autres conseils

Si vous voulez éviter de se fier bibliothèques tierces pour une tâche simple, voici une implémentation 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));
}

Notez que la fonction suppose que les deux vecteurs ont la même longueur. Vous pouvez vérifier explictly pour la sécurité.

Jetez un oeil à: http://en.wikipedia.org/wiki/Cosine_similarity .

Si vous avez des vecteurs A et B.

La similarité est définie comme suit:

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)

Exemple:

A = (1, 0.5), B = (0.5, 1)

cosine(theta) = (0.5 + 0.5) / sqrt(5/4) sqrt(5/4) = 4/5

Pour le code de matrice en Java, je vous recommande d'utiliser la bibliothèque Colt . Si vous avez cela, le code ressemble (non testé ou même compilé):

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))

Le code ci-dessus peut aussi être modifié pour utiliser l'une des méthodes Blas.dnrm2() ou Algebra.DEFAULT.norm2() pour le calcul de la norme. Exactement le même résultat, ce qui est plus facile à lire dépend des goûts.

Quand je travaillais avec text mining il y a quelque temps, j'utilisais la bibliothèque SimMetrics qui fournit une vaste gamme de paramètres différents en Java. S'il est arrivé que vous avez besoin de plus, alors il y a toujours R et CRAN à regarder.

Mais le coder de la description dans Wikipedia est une tâche plutôt triviale, et peut être un exercice agréable.

Pour la représentation parcimonieuse des vecteurs en utilisant Map(dimension -> magnitude) Voici une version scala (Vous pouvez faire des choses similaires 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))
}
def cosineSimilarity(vectorA: Vector[Double], vectorB: Vector[Double]):Double={
    var dotProduct = 0.0
    var normA = 0.0
    var normB = 0.0
    var i = 0

    for(i <- vectorA.indices){
        dotProduct += vectorA(i) * vectorB(i)
        normA += Math.pow(vectorA(i), 2)
        normB += Math.pow(vectorB(i), 2)
    }

    dotProduct / (Math.sqrt(normA) * Math.sqrt(normB))
}

def main(args: Array[String]): Unit = {
    val vectorA = Array(1.0,2.0,3.0).toVector
    val vectorB = Array(4.0,5.0,6.0).toVector
    println(cosineSimilarity(vectorA, vectorA))
    println(cosineSimilarity(vectorA, vectorB))
}

version scala

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top