Dokumentähnlichkeit messen

21

Um (Text-) Dokumente zu gruppieren, müssen Sie die Ähnlichkeit zwischen Dokumentenpaaren messen.

Zwei Alternativen sind:

  1. Vergleichen Sie Dokumente als Termvektoren mit Cosine Similarity - und TF / IDF als Gewichtungen für Terme.

  2. Vergleichen Sie die Wahrscheinlichkeitsverteilung jedes Dokuments mit f-Divergenz, z. B. Kullback-Leibler-Divergenz

Gibt es einen intuitiven Grund, eine Methode der anderen vorzuziehen (bei einer durchschnittlichen Dokumentgröße von 100 Begriffen)?

Joel
quelle

Antworten:

23

Bei Textdokumenten können die Merkmalsvektoren unter allen Standarddarstellungen (Wortkiste oder TF-IDF usw.) sehr hochdimensional und dünn sein. Das Messen von Abständen direkt unter einer solchen Darstellung ist möglicherweise nicht zuverlässig, da bekannt ist, dass in sehr großen Dimensionen der Abstand zwischen zwei beliebigen Punkten gleich aussieht. Eine Möglichkeit, damit umzugehen, besteht darin, die Datendimensionalität mithilfe von PCA oder LSA ( Latent Semantic Analysis , auch als Latent Semantic Indexing bezeichnet ) zu reduzieren und anschließend die Abstände im neuen Raum zu messen. Die Verwendung von so etwas wie LSA gegenüber PCA ist vorteilhaft, da es eine aussagekräftige Darstellung im Sinne von "semantischen Konzepten" abgesehen von der Messung von Entfernungen in einem Raum mit niedrigeren Dimensionen geben kann.

Das Vergleichen von Dokumenten auf der Grundlage der Wahrscheinlichkeitsverteilungen erfolgt normalerweise, indem zuerst die Themenverteilung jedes Dokuments berechnet wird (unter Verwendung einer latenten Dirichlet-Zuordnung ) und dann eine Art von Divergenz (z. B. KL-Divergenz) zwischen den Themenverteilungen von Dokumentenpaaren berechnet wird. In gewisser Weise ist es tatsächlich so, als würde man zuerst LSA durchführen und dann die Abstände im LSA-Raum unter Verwendung der KL-Divergenz zwischen den Vektoren messen (anstelle der Cosinus-Ähnlichkeit).

KL-Divergenz ist ein Abstandsmaß für den Vergleich von Verteilungen. Daher ist es möglicherweise vorzuziehen, wenn die Dokumentendarstellung in Form einer Verteilung erfolgt (was häufig tatsächlich der Fall ist - z. B. Dokumente, die wie in LDA als Verteilung über Themen dargestellt werden). Beachten Sie auch, dass bei einer solchen Darstellung die Einträge im Merkmalsvektor eins ergeben würden (da Sie das Dokument im Grunde genommen als eine Verteilung über Themen oder semantische Konzepte behandeln).

Siehe auch einen verwandten Thread hier .

Ebenholz1
quelle
Vielen Dank. Müssen Sie bei der LDA die Themen im Voraus kennen? In unserem Fall wissen wir nicht, zu welchem ​​Thema jedes Dokument gehört, und wir werden das Ähnlichkeitsmaß verwenden, um Clustering (EMG-Means oder GAAC) durchzuführen
Joel
@ ebony1 Netter Hinweis auf LSA, eine ähnliche Antwort habe ich vor einiger Zeit unter stats.stackexchange.com/questions/369/…
chl
1
@Joel: Nein, LDA geht nicht davon aus, dass Sie die Themen für jedes Dokument vorher kennen. Übrigens, um klar zu sein, repräsentiert LDA jedes Dokument als eine Mischung von Themen, nicht nur nach einem einzigen Thema. So trägt jedes Thema zu einem Bruchteil in den Dokumenten bei (und die einzelnen Brüche summieren sich zu 1). Grundsätzlich geht LDA davon aus, dass jedes Wort im Dokument von einem bestimmten Thema generiert wird.
Ebenholz1
@ebony - danke! Müssen Sie bei der LDA die Anzahl der diskreten Themen kennen, wenn die Gefahr besteht, dass Sie die Frage umformulieren und mich wiederholen?
Joel
Ja. Es gibt jedoch LDA-Varianten (HDP-LDA), bei denen die Anzahl der Themen nicht angegeben werden muss. Siehe dieses Papier: cse.buffalo.edu/faculty/mbeal/papers/hdp.pdf
ebony1
0

Möglicherweise möchten Sie diesen Onlinedienst auf Ähnlichkeit mit Kosinusdokumenten testen: http://www.scurtu.it/documentSimilarity.html

import urllib,urllib2
import json
API_URL="http://www.scurtu.it/apis/documentSimilarity"
inputDict={}
inputDict['doc1']='Document with some text'
inputDict['doc2']='Other document with some text'
params = urllib.urlencode(inputDict)    
f = urllib2.urlopen(API_URL, params)
response= f.read()
responseObject=json.loads(response)  
print responseObject
Vitalie
quelle
2
Bitte machen Sie nähere Angaben.
Xi'an