2016-11-03 6 views
0

Ich versuche, die Cosinus Ähnlichkeit zweier Dokumente dargestellt zu finden wie folgt:Kosinusähnlichkeit von Dokumenten mit Gewichten

d1: [(0,1), (3,2), (6, 1)] 
d2: [(1,1), (3,1), (5,4), (6,2)] 

wo jedes Dokument ein Thema-Gewichtsvektor ist, wo Themen das erste Element in dem Tupel sind und das Gewicht ist das zweite Element

Ich bin mir nicht sicher, wie man in diesem Fall mit diesem gewichteten Schema die Kosinusähnlichkeit berechnen soll? Gibt es ein Modul/Paket in Python, das mir so etwas erlauben würde?

Antwort

0

Eine sehr einfache Idee ist einen Vektor der Gewichte zu schaffen, und dann scipy.spatial.distance.cosine verwenden, um den Cosinus-Abstand zu berechnen (die auf 1-Ähnlichkeit gleich):

In [1]: from scipy.spatial.distance import cosine 
In [2]: import numpy as np 
In [3]: d1 = [(0,1), (3,2), (6, 1)] 
In [4]: d2 = [(1,1), (3,1), (5,4), (6,2)] 
In [5]: def get_weights(d): 
    ...:  w = [ 0. ] * N 
    ...:  for i, weight in d: 
    ...:   w[i] = weight 
    ...:  return np.array(w) 
    ...: 

In [6]: w1 = get_weights(d1) 
In [7]: w2 = get_weights(d2) 
In [8]: 1-cosine(w1, w2) 
Out[8]: 0.3481553119113957 
+0

Wenn die Vektoren lang oder es gibt viele mögliche Themen sind dann wollen Sie sie spärlich halten - sonst ist es gefährlich, sie dicht zu machen. – gabe

+0

Stimmt, vorausgesetzt, die Vektoren sind spärlich, und es gibt eine Menge Themen. – mdml

+0

@mdml - Danke, das N Ich nehme an, ist die Gesamtzahl der einzigartigen Themen? Wie kann ich das finden? Die Anzahl der Themen kann von Fall zu Fall variieren, ich würde wahrscheinlich eine Möglichkeit brauchen, sie a priori zu zählen – newdev14

1

Mit einem kurzen Blick doesn es‘ t scheint eine Standardfunktion zu sein, die Eingaben dieses Formulars übernimmt. Sie haben zwei Möglichkeiten, die von dem Problem, der Größe der Arrays und anderen Dingen abhängen. Sie können entweder jeden der beiden Vektoren für die Themengewichtung in spärliche scipy-Vektoren umwandeln und dann sklearns cosine_simularity verwenden (http://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.cosine_similarity.html) ODER Sie können einfach Ihre eigene cosine_similarity schreiben. Die Art, wie ich letzteres tun würde, ist, jeden Vektor so zu einem Diktat (für schnellere Suchvorgänge) zu machen.

import math 

def vect_to_topic_weight(vector): 
    return {a:b for a,b in vector} 

def norm(vector): 
    return math.sqrt(sum(vector[k]**2 for k in vector.iterkeys())) 

def dot(a,b): 
    return sum(a[k]*b.get(k,0) for k in a.iterkeys()) 

# returns the cosine_similarity, with inputs as topic_weight dicts 
def cosine_similarity(a, b): 
    return dot(a,b)/float(norm(a)*norm(b)) 
1

Ja gibt es Pakete in Python, z.B. scikit-learn's cosine sim. documentation here. Im Folgenden werde ich Ihnen eine manuelle Art und Weise gegeben haben, es zu tun:

import numpy as np 

d1 = dict([(0,1), (3,2), (6, 1)]) 
d2 = dict([(1,1), (3,1), (5,4), (6,2)]) 

l = max(d1.keys() + d2.keys()) + 1 ## Number of topics observed 

v1 = np.zeros((l,)) 
for i in xrange(l): 
    if i in d1.keys(): 
     v1[i] = d1[i] 

v2 = np.zeros((l,)) 
for i in xrange(l): 
    if i in d2.keys(): 
     v2[i] = d2[i] 

## now v1 and v2 are 1-d np arrays representing your docs. 

v1 = v1/np.sqrt(np.dot(v1,v1)) ## normalize 
v2 = v2/np.sqrt(np.dot(v2,v2)) ## normalize 

cos_sim = np.dot(v1,v2) ## should get .348155... 
+0

zu bekommen, aber die Anzahl der Themen in Ihrer Formel ist die Summe über beide Dokumente, und nicht die einzigartige Anzahl von Themen ... was ist nötig – newdev14

+0

Sie wahrscheinlich meinen: max (d1.keys() + d2.keys()) + 1? – newdev14

+0

Dein letzter Kommentar ist genau was ich habe. max (d1.tasten() + d2.tasten()) = max ([0,3,6] + [1,3,5,6]) = max ([0,3,6, 1 , 3,5,6]) = 6. Wir wollen +1 b/c Die Anzahl der Themen ist 7 (0 ist ein Thema). – travelingbones

Verwandte Themen