¿Cosinidad de similitud de vectores de diferentes longitudes?

Estoy tratando de usar TF-IDF para clasificar los documentos en categorías. He calculado tf_idf para algunos documentos, pero ahora, cuando bash calcular la similitud de coseno entre dos de estos documentos, obtengo un rastreo que dice:

#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á cortando el vector para que len (u) == len (v) sea el enfoque correcto? Pensaría que la similitud de coseno funcionaría con vectores de diferentes longitudes.

Estoy usando esta función :

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

Además, ¿es importante el orden de los valores tf_idf en los vectores? ¿Deberían clasificarse, o no tiene importancia para este cálculo?

Related of "¿Cosinidad de similitud de vectores de diferentes longitudes?"

¿Estás calculando la similitud de coseno de los vectores de términos? Los vectores de términos deben ser de la misma longitud. Si las palabras no están presentes en un documento, debe tener un valor de 0 para ese término.

No estoy exactamente seguro de a qué vectores están aplicando la similitud de coseno, pero cuando se hace una similitud de coseno, entonces los vectores siempre deben tener la misma longitud y el orden es muy importante.

Ejemplo:

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

Aquí tienes dos vectores (.3,0,1) y (.7,8,1) y puedes calcular la similitud del coseno entre ellos. Si comparara (.3,1) y (.7,8) estaría comparando la puntuación Doc1 de Baz con la puntuación Doc2 de Bar, lo que no tendría sentido.

Necesita multiplicar las entradas para las palabras correspondientes en el vector, por lo que debe haber un orden global para las palabras. Esto significa que, en teoría, sus vectores deberían tener la misma longitud.

En la práctica, si un documento se vio antes que el otro, es posible que las palabras del segundo documento se hayan agregado al orden global después de que se haya visto el primer documento, por lo que aunque los vectores tienen el mismo orden, el primer documento puede ser más corto, ya que no tiene entradas para las palabras que no estaban en ese vector.

Documento 1: El zorro marrón rápido saltó sobre el perro perezoso.

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

Documento 2: El corredor fue rápido.

 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 

En este caso, en teoría, debe rellenar el vector del Documento 1 con ceros en el extremo. En la práctica, cuando se calcula el producto de puntos, solo necesita multiplicar los elementos hasta el final del Vector 1 (ya que omitir los elementos adicionales del vector 2 y multiplicarlos por cero es exactamente lo mismo, pero la visita de los elementos adicionales es más lenta).

Luego, puede calcular la magnitud de cada vector por separado, y para eso no es necesario que los vectores tengan la misma longitud.

Intente construir los vectores antes de enviarlos a la función de distancia de cosine:

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