Question

J'essaie d'utiliser TF-IDF pour trier les documents en catégories. J'ai calculé le tf_idf pour certains documents, mais maintenant quand j'essaie de calculer la similarité Cosinus entre deux de ces documents que je reçois un retraçage en disant:

#len(u)==201, len(v)==246

cosine_distance(u, v)
ValueError: objects are not aligned

#this works though:
cosine_distance(u[:200], v[:200])
>> 0.52230249969265641

est le vecteur tranchage de telle sorte que len (u) == len (v) la bonne approche? Je pense que la similitude cosinus travaillerait avec des vecteurs de longueurs différentes.

J'utilise cette fonction :

def cosine_distance(u, v):
    """
    Returns the cosine of the angle between vectors v and u. This is equal to
    u.v / |u||v|.
    """
    return numpy.dot(u, v) / (math.sqrt(numpy.dot(u, u)) * math.sqrt(numpy.dot(v, v))) 

De plus - est l'ordre des valeurs tf_idf dans les vecteurs importants? Devraient-ils être classés - ou est-il pas d'importance pour ce calcul

Était-ce utile?

La solution

Vous calcul de la similarité cosinus des vecteurs terme? vecteurs terme devraient être de la même longueur. Si les mots ne sont pas présents dans un document, alors il doit avoir une valeur de 0 pour ce terme.

Je ne suis pas sûr de ce que vous appliquez des vecteurs de similarité cosinus pour mais en faisant similitude cosinus alors vos vecteurs doivent toujours être la même longueur et de l'ordre très importe.

Exemple:

Term | Doc1 | Doc2
Foo     .3     .7
Bar  |  0   |  8
Baz  |  1   |  1

Ici vous avez deux vecteurs (.3,0,1) et (.7,8,1) et peut calculer la similarité cosinus entre eux. Si vous compariez (.3,1) et (.7,8) vous seriez comparant le score Doc1 de Baz contre le score Doc2 de Bar qui ne serait pas logique.

Autres conseils

Vous avez besoin de multiplier les entrées des mots correspondant dans le vecteur, donc il devrait y avoir un ordre mondial pour les mots. Cela signifie que, en théorie, vos vecteurs doivent être de la même longueur.

Dans la pratique, si l'on document a été vu avant que l'autre, les mots du second document peuvent avoir été ajoutés à l'ordre mondial après le premier document a été vu, de sorte que même si les vecteurs ont le même ordre, le premier document peut être plus courte, car il ne dispose pas d'entrées pour les mots qui ne sont pas dans ce vecteur.

Document 1:. Le renard brun rapide sauté par-dessus le chien paresseux

Global order:     The quick brown fox jumped over the lazy dog
Vector for Doc 1:  1    1     1    1     1     1    1   1   1

Document 2:. Le coureur a été rapide

Global order:     The quick brown fox jumped over the lazy dog runner was
Vector for Doc 1:  1    1     1    1     1     1    1   1   1
Vector for Doc 2:  1    1     0    0     0     0    0   0   0    1     1

Dans ce cas, en théorie vous devez pad le vecteur document 1 avec des zéros sur la fin. Dans la pratique, lors du calcul du produit scalaire, il vous suffit d'éléments se multiplient jusqu'à la fin de Vector 1 (depuis omettant les éléments supplémentaires du vecteur 2 et les multiplier par zéro sont exactement les mêmes, mais la visite des éléments supplémentaires est plus lent).

Ensuite, vous pouvez calculer l'amplitude de chaque vecteur séparément, et pour que les vecteurs ne doivent pas nécessairement être de la même longueur.

Essayez de construire les vecteurs avant de les nourrir à la fonction cosine_distance:

import math
from collections import Counter
from nltk import cluster

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


l1 = "Julie loves me more than Linda loves me".split()
l2 = "Jane likes me more than Julie loves me or".split()


v1,v2= buildVector(l1, l2)
print(cluster.util.cosine_distance(v1,v2))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top