Domanda

Sto cercando di utilizzare TF-IDF per ordinare i documenti in categorie. Ho calcolato la tf_idf per alcuni documenti, ma ora quando provo a calcolare il coseno somiglianza tra due di questi documenti ho un traceback dicendo:

#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

sta affettando il vettore in modo che len (u) == len (v) l'approccio giusto? Vorrei pensare che coseno di similitudine avrebbe funzionato con vettori di diverse lunghezze.

sto usando questa funzione :

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

Inoltre - è l'ordine dei valori tf_idf nei vettori importanti? Dovrebbero essere ordinati -? O è di nessuna importanza per questo calcolo

È stato utile?

Soluzione

Stai calcolando la somiglianza coseno di vettori termine? vettori termine dovrebbero avere la stessa lunghezza. Se le parole non sono presenti in un documento allora dovrebbe avere un valore pari a 0 per quel termine.

Non sono esattamente sicuro di quello che i vettori si sta applicando similarità del coseno per, ma quando si fa coseno di similitudine poi i vettori dovrebbero sempre essere la stessa lunghezza e l'ordine molto che conta.

Esempio:

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

Qui ci sono due vettori (.3,0,1) e (.7,8,1) e possibile calcolare la similarità del coseno tra di loro. Se confrontato (.3,1) e (.7,8) saresti confrontando il punteggio Doc1 di Baz contro il punteggio Doc2 di Bar, che non avrebbe senso.

Altri suggerimenti

È necessario moltiplicare le voci per le parole corrispondenti nel vettore, quindi ci dovrebbe essere un ordine globale per le parole. Ciò significa che, in teoria, i vettori dovrebbero essere della stessa lunghezza.

In pratica, se un documento è stato visto prima dell'altro, parole del secondo documento possono essere stati aggiunti all'ordine globale dopo il primo documento è stato visto, quindi, anche se i vettori hanno lo stesso ordine, il primo documento può essere più breve, dal momento che non ha voci per le parole che non erano in quel vettore.

Documento 1:. The quick brown fox jumps over the lazy dog ??

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:. Il corridore è stato rapido

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

In questo caso, in teoria, è necessario riempire il vettore del documento 1 con zeri alla fine. In pratica, quando si calcola il prodotto scalare, avete solo bisogno di elementi moltiplicano fino alla fine del vettore 1 (dal omettendo gli elementi supplementari di vettore 2 e moltiplicandoli per zero sono esattamente gli stessi, ma la visita gli elementi aggiuntivi è più lento).

Quindi è in grado di calcolare la grandezza di ogni vettore a parte, e per questo i vettori non hanno bisogno di essere della stessa lunghezza.

Provare a costruire i vettori prima di nutrirli alla funzione 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))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top