2013-10-16 15 views
25

Ich habe Korpora von klassifizierten Texten. Aus diesen erzeuge ich Vektoren. Jeder Vektor entspricht einem Dokument. Vektorkomponenten sind Wortgewichte in diesem Dokument, die als TFIDF-Werte berechnet werden. Als nächstes baue ich ein Modell, in dem jede Klasse von einem einzelnen Vektor dargestellt wird. Modell hat so viele Vektoren wie Klassen in den Korpora. Die Komponente eines Modellvektors wird als Mittelwert aller Komponentenwerte aus Vektoren in dieser Klasse berechnet. Für nicht klassifizierte Vektoren beziehe ich Ähnlichkeit mit einem Modellvektor durch Berechnen von Kosinus zwischen diesen Vektoren.Vector Space Model: Cosine Ähnlichkeit vs Euklidische Entfernung

Fragen:

1) Kann ich die euklidische Entfernung zwischen Vektor nicht klassifiziert und Modell ihrer Ähnlichkeit berechnen?

2) Warum kann die euklidische Distanz nicht als Ähnlichkeitsmaß anstelle des Kosinus des Winkels zwischen zwei Vektoren und umgekehrt verwendet werden?

Danke!

+0

Diese Frage erscheint Wegthema zu sein, weil es über Statistiken, nicht programmieren. Versuchen Sie http://stats.stackexchange.com/. –

Antwort

26

Eine informelle sondern intuitive Art und Weise, um darüber nachzudenken ist, die zwei Komponenten eines Vektors zu berücksichtigen: Richtung und Größe.

Richtung ist die „Präferenz“/„style“/„Gefühl“/„latenter Variable“ des Vektors, während die Größenordnung ist, wie stark sie in diese Richtung ist.

Bei der Klassifizierung von Dokumenten möchten wir sie nach ihrer Gesamtstimmung kategorisieren, also verwenden wir den Winkelabstand.

Der euklidische Abstand ist anfällig dafür, dass Dokumente nach ihrer L2-Norm (Größe, im 2-dimensionalen Fall) anstelle der Richtung gruppiert werden. I.e. Vektoren mit ziemlich unterschiedlichen Richtungen würden geclustert werden, da ihre Abstände vom Ursprung ähnlich sind.

+1

"[mit euklidischer Entfernung] würden Vektoren mit ziemlich verschiedenen Richtungen gruppiert, weil ihre Entfernung vom Ursprung ähnlich ist" -> Wie ist das wahr? Im Extremfall betrachten wir zwei diametral entgegengesetzte Vektoren gleicher Größe: Diese haben einen großen euklidischen Abstand zwischen ihnen, obwohl ihre Entfernung vom Ursprung identisch ist. – xenocyon

+2

@xenocyon Betrachten Sie den Fall, wenn ihre Größe zum Ursprung klein ist – kizzx2

+1

Wenn Sie drei Dokumente mit Sentiment -1, 1, 100 haben, welche zwei sind näher: die ersten beiden oder die zweiten beiden? Ich denke, es ist nur möglich zu antworten, wenn Sie das spezifische Problem kennen, an dem Sie arbeiten. – BallpointBen

17

Ich werde die Fragen in umgekehrter Reihenfolge beantworten. Für Ihre zweite Frage sind Kosinus-Ähnlichkeit und Euklidischer Abstand zwei verschiedene Möglichkeiten, die Vektorähnlichkeit zu messen. Ersteres misst die Ähnlichkeit von Vektoren in Bezug auf den Ursprung, während Letzteres den Abstand zwischen bestimmten Punkten von Interesse entlang des Vektors misst. Sie können entweder isoliert verwenden, sie kombinieren und beide verwenden, oder Sie können eine der vielen anderen Möglichkeiten nutzen, um die Ähnlichkeit zu bestimmen. Weitere Informationen finden Sie unter these Folien aus einer Michael Collins-Vorlesung. Die erste Frage ist nicht sehr klar, aber Sie sollten in der Lage sein, mit jeder Kennzahl einen Abstand zwischen zwei Vektoren zu finden, unabhängig davon, ob Sie Dokumente oder Ihre "Modelle" vergleichen (was traditionellerweise als "0" bezeichnet würde) Cluster, wobei das Modell die Summe aller Cluster ist).

5

Computational Zeit weise (in python):

import time 
import numpy as np 

for i in range(10): 
    start = time.time() 
    for i in range(10000): 
     a, b = np.random.rand(100), np.random.rand(100) 
     np.dot(a, b)/(np.linalg.norm(a) * np.linalg.norm(b)) 
    print 'Cosine similarity took', time.time() - start 

    start = time.time() 
    for i in range(10000): 
     a, b = np.random.rand(100), np.random.rand(100) 
     2 * (1 - np.dot(a, b)/(np.linalg.norm(a) * np.linalg.norm(b))) 
    print 'Euclidean from 2*(1 - cosine_similarity) took', time.time() - start 


    start = time.time() 
    for i in range(10000): 
     a, b = np.random.rand(100), np.random.rand(100) 
     np.linalg.norm(a-b) 
    print 'Euclidean Distance using np.linalg.norm() took', time.time() - start 


    start = time.time() 
    for i in range(10000): 
     a, b = np.random.rand(100), np.random.rand(100) 
     np.sqrt(np.sum((a-b)**2)) 
    print 'Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took', time.time() - start 
    print '--------------------------------------------------------' 

[out]:

Cosine similarity took 0.15826010704 
Euclidean from 2*(1 - cosine_similarity) took 0.179041862488 
Euclidean Distance using np.linalg.norm() took 0.10684299469 
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.113723039627 
-------------------------------------------------------- 
Cosine similarity took 0.161732912064 
Euclidean from 2*(1 - cosine_similarity) took 0.178358793259 
Euclidean Distance using np.linalg.norm() took 0.107393980026 
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.111194849014 
-------------------------------------------------------- 
Cosine similarity took 0.16274189949 
Euclidean from 2*(1 - cosine_similarity) took 0.178978919983 
Euclidean Distance using np.linalg.norm() took 0.106336116791 
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.111373186111 
-------------------------------------------------------- 
Cosine similarity took 0.161939144135 
Euclidean from 2*(1 - cosine_similarity) took 0.177414178848 
Euclidean Distance using np.linalg.norm() took 0.106301784515 
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.11181807518 
-------------------------------------------------------- 
Cosine similarity took 0.162333965302 
Euclidean from 2*(1 - cosine_similarity) took 0.177582979202 
Euclidean Distance using np.linalg.norm() took 0.105742931366 
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.111120939255 
-------------------------------------------------------- 
Cosine similarity took 0.16153883934 
Euclidean from 2*(1 - cosine_similarity) took 0.176836967468 
Euclidean Distance using np.linalg.norm() took 0.106392860413 
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.110891103745 
-------------------------------------------------------- 
Cosine similarity took 0.16018986702 
Euclidean from 2*(1 - cosine_similarity) took 0.177738189697 
Euclidean Distance using np.linalg.norm() took 0.105060100555 
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.110497951508 
-------------------------------------------------------- 
Cosine similarity took 0.159607887268 
Euclidean from 2*(1 - cosine_similarity) took 0.178565979004 
Euclidean Distance using np.linalg.norm() took 0.106383085251 
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.11084485054 
-------------------------------------------------------- 
Cosine similarity took 0.161075115204 
Euclidean from 2*(1 - cosine_similarity) took 0.177822828293 
Euclidean Distance using np.linalg.norm() took 0.106630086899 
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.110257148743 
-------------------------------------------------------- 
Cosine similarity took 0.161051988602 
Euclidean from 2*(1 - cosine_similarity) took 0.181928873062 
Euclidean Distance using np.linalg.norm() took 0.106360197067 
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.111301898956 
-------------------------------------------------------- 
+1

so Rechenzeit weise, sagen Sie Euklidisch ist besser ..? – Aaron

+0

Aus diesen Ergebnissen scheint es keinen signifikanten Unterschied zwischen der Rechenzeit zu geben. Daher kann man sich bei der Entscheidung über die zu verwendende Methode nicht von der Rechenzeit leiten lassen. – Gathide