2016-07-25 14 views
2

Ich versuche Cosinus Abstand in Python zwischen den Zeilen in der Matrix zu berechnen und ein paar Fragen zu haben.So ich Matrix Matrix erstellen und aus den Listen bevölkern, dann umformen es für Analysezwecke:Kosinusabstand zwischen den Zeilen der Matrix berechnen

s = [] 

for i in range(len(a)): 
    for j in range(len(b_list)): 
     s.append(a[i].count(b_list[j])) 

matr = np.array(s) 
d = matr.reshape((22, 254)) 

der Ausgang d gibt wie ich smth:

array([[0, 0, 0, ..., 0, 0, 0], 
     [2, 0, 0, ..., 1, 0, 0], 
     [2, 0, 0, ..., 0, 0, 0], 
     ..., 
     [0, 0, 0, ..., 0, 0, 0], 
     [0, 0, 0, ..., 0, 0, 0], 
     [1, 0, 0, ..., 0, 0, 0]]) 

Dann möchte ich scipy.spatial.distance.cosine Paket verwenden Cosinus zu jedem anderen aus der ersten Reihe berechnen sonst in die d-Matrix. Wie kann ich das ausführen? Sollte es dafür eine Schleife geben? Nicht zu viel Erfahrung mit Matrix- und Array-Operationen.

Wie kann ich also for-Schleife für die zweite Argument (d [1], d [2], und so weiter) in dieser Konstruktion nicht jedes Mal zu starten:

from scipy.spatial.distance import cosine 
x=cosine (d[0], d[6]) 
+0

Hat dieses Paket nicht eine paarweise Funktion oder zwei? – hpaulj

+0

Ich fürchte nicht - es verwendet Cosinus, die 2 1-D-Arrays als Eingänge wie folgt verwendet: Kosinus (u, v), wo u, v-1-D-Arrays. – HalfPintBoy

+0

Verwenden Sie numpy? –

Antwort

3

Sie können nur eine einfache mit scipy.spatial.distance.cosine for-Schleife:

dists = [] 
for row in matr: 
    dists.append(scipy.spatial.distance.cosine(matr[0,:], row)) 
7

Du hast gesagt, „berechnen Kosinus von der ersten Zeile zu jedem anderen in der d Matrix "[sic]. Wenn ich richtig verstehe, können Sie das tun mit scipy.spatial.distance.cdist, die erste Zeile als erstes Argument übergeben und die übrigen Reihen als das zweite Argument:

In [31]: from scipy.spatial.distance import cdist 

In [32]: matr = np.random.randint(0, 3, size=(6, 8)) 

In [33]: matr 
Out[33]: 
array([[1, 2, 0, 1, 0, 0, 0, 1], 
     [0, 0, 2, 2, 1, 0, 1, 1], 
     [2, 0, 2, 1, 1, 2, 0, 2], 
     [2, 2, 2, 2, 0, 0, 1, 2], 
     [0, 2, 0, 2, 1, 0, 0, 0], 
     [0, 0, 0, 1, 2, 2, 2, 2]]) 

In [34]: cdist(matr[0:1], matr[1:], metric='cosine') 
Out[34]: array([[ 0.65811827, 0.5545646 , 0.1752139 , 0.24407105, 0.72499045]]) 

Sollte sich herausstellen, dass Sie alle berechnen wollen die paarweise Abstände in matr, können Sie scipy.spatial.distance.pdist verwenden.

Zum Beispiel

In [35]: from scipy.spatial.distance import pdist 

In [36]: pdist(matr, metric='cosine') 
Out[36]: 
array([ 0.65811827, 0.5545646 , 0.1752139 , 0.24407105, 0.72499045, 
     0.36039785, 0.27625314, 0.49748109, 0.41498206, 0.2799177 , 
     0.76429774, 0.37117185, 0.41808563, 0.5765951 , 0.67661917]) 

Beachten Sie, dass die ersten fünf zurückgegebenen Werte von pdist sind die gleichen Werte oben mit cdist zurückgegeben.

Zur weiteren Erläuterung der Rückgabewert von pdist finden How does condensed distance matrix work? (pdist)

+0

diese Antwort scheint aber falsch, nicht wahr? Ich würde erwarten, dass die Entfernung für alle "Selbst" -Vergleiche "0" ist. –

+0

@TasosPapastylianou Das von 'pdist' berechnete Ergebnis enthält keinen der 'self'-Vergleiche. Siehe die Beschreibung in dem Link, den ich am Ende meiner Antwort angegeben habe. –

1

Hier ist, wie Sie es sich leicht von Hand berechnen könnte:

from numpy import array as a 
from numpy.random import random_integers as randi 
from numpy.linalg.linalg import norm 
from numpy import set_printoptions 

M = randi(10, size=a([5,5])); # create demo matrix 

# dot products of rows against themselves 
DotProducts = M.dot(M.T);  

# kronecker product of row norms 
NormKronecker = a([norm(M, axis=1)]) * a([norm(M, axis=1)]).T; 

CosineSimilarity = DotProducts/NormKronecker 
CosineDistance = 1 - CosineSimilarity 

set_printoptions(precision=2, suppress=True) 
print CosineDistance 

Ausgabe:

[[-0. 0.15 0.1 0.11 0.22] 
[ 0.15 0. 0.15 0.13 0.06] 
[ 0.1 0.15 0. 0.15 0.14] 
[ 0.11 0.13 0.15 0. 0.18] 
[ 0.22 0.06 0.14 0.18 -0. ]] 

Diese Matrix ist z.B. interpretiert als "der Kosinusabstand zwischen Reihe 3 gegen Reihe 2 (oder gleichwertig, Reihe 2 gegen Reihe 3) ist 0.15".