Pregunta

Estoy intentando utilizar TF-IDF para clasificar los documentos en categorías. He calculado el tf_idf para algunos documentos, pero ahora cuando intento para calcular el coseno similitud entre dos de estos documentos consigo un rastreo diciendo:

#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

es cortar el vector de modo que len (u) == len (v) el enfoque correcto? Me gustaría pensar que la similitud del coseno sería trabajar 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
    u.v / |u||v|.
    """
    return numpy.dot(u, v) / (math.sqrt(numpy.dot(u, u)) * math.sqrt(numpy.dot(v, v))) 

También - es importante el orden de los valores tf_idf en los vectores? ¿Deben ser ordenados -? O es de ninguna importancia para este cálculo

¿Fue útil?

Solución

¿Está el cálculo de la similitud del coseno de vectores plazo? vectores plazo debería ser la misma longitud. Si las palabras no están presentes en un documento, entonces debe tener un valor de 0 para ese término.

No estoy exactamente seguro de lo que está solicitando vectores similitud del coseno para hacerlo pero cuando similitud del coseno a continuación, sus vectores siempre deben tener la misma longitud y el orden mucho que importa.

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 puede calcular el coseno similitud entre ellos. Si se compara (.3,1) y (.7,8) que estaría comparando la puntuación Doc1 de Baz contra la puntuación Doc2 de Bar, que no tendría sentido.

Otros consejos

Se necesita multiplicar las entradas para las palabras correspondientes en el vector, lo que debería haber un orden global de las palabras. Esto significa que, en teoría, sus vectores deben tener la misma longitud.

En la práctica, si un documento fue visto antes que el otro, las palabras en el segundo documento pueden haber sido añadido a la orden global después fue visto el primer documento, por lo que a pesar de que los vectores tienen el mismo orden, el primer documento puede estar 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 se necesita para rellenar el vector Documento 1 con ceros en el extremo. En la práctica, cuando se calcula el producto escalar, sólo tiene que elementos se multiplican hasta el final del vector 1 (ya que la omisión de los elementos adicionales del vector 2 y multiplicándolos por cero son exactamente lo mismo, pero visitar los elementos extra es más lento).

A continuación, se puede calcular la magnitud de cada vector separado, y para que los vectores no necesitan ser de la misma longitud.

Intenta construir los vectores antes de alimentar a la función 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))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top