2016-05-03 9 views
6

Ich habe einen Datenrahmen wie folgt: Die Form des Rahmens ist (1510, 1399). Die Spalten stellen Produkte dar, die Zeilen repräsentieren die Werte (0 oder 1), die einem Benutzer für ein bestimmtes Produkt zugewiesen wurden. Wie kann ich eine jaccard_similarity_score berechnen?Wie jaccard Ähnlichkeit aus einem Pandas Datenrahmen zu berechnen

enter image description here

Ich habe gegen Produkt einen Platzhalter Datenrahmen

data_ibs = pd.DataFrame(index=data_g.columns,columns=data_g.columns) 

Ich bin nicht sicher, ob die Auflistung Produkt wie data_ibs iterieren obwohl Ähnlichkeiten zu berechnen.

for i in range(0,len(data_ibs.columns)) : 
    # Loop through the columns for each column 
    for j in range(0,len(data_ibs.columns)) : 
......... 

Antwort

17

Kurz und vektorisiert (schnell) Antwort:

Use 'Hamming' aus den paarweise Entfernungen von scikit lernen:

from sklearn.metrics.pairwise import pairwise_distances 
jac_sim = 1 - pairwise_distances(df.T, metric = "hamming") 
# optionally convert it to a DataFrame 
jac_sim = pd.DataFrame(jac_sim, index=df.columns, columns=df.columns) 

Erläuterung:

Angenommen, dies ist Ihr Datensatz:

import pandas as pd 
import numpy as np 
np.random.seed(0) 
df = pd.DataFrame(np.random.binomial(1, 0.5, size=(100, 5)), columns=list('ABCDE')) 
print(df.head()) 

    A B C D E 
0 1 1 1 1 0 
1 1 0 1 1 0 
2 1 1 1 1 0 
3 0 0 1 1 1 
4 1 1 0 1 0 

sklearn des jaccard_similarity_score Unter Verwendung Ähnlichkeit zwischen der Spalte A und B:

from sklearn.metrics import jaccard_similarity_score 
print(jaccard_similarity_score(df['A'], df['B'])) 
0.43 

dies die Anzahl der Zeilen ist, die denselben Wert über Gesamtzahl der Zeilen, 100.

Soweit mir Wissen Sie, es gibt keine paarweise Version von jaccard_similarity_score, aber es gibt paarweise Versionen von Distanzen.

definiert jedoch SciPy Jaccard distance wie folgt:

Gegeben seien zwei Vektoren u und v, die Jaccard Abstand ist der Anteil dieser Elemente u [i] und v [i], die in dem mindestens einen nicht einverstanden von ihnen ist nicht Null.

Also schließt es die Zeilen aus, in denen beide Spalten 0 Werte haben. jaccard_similarity_score nicht. Hamming-Distanz, auf der anderen Seite, ist inline mit der Ähnlichkeitsdefinition:

der Anteil der Vektorelemente zwischen zwei n-Vektoren u und v der nicht übereinstimmen.

Also, wenn Sie jaccard_similarity_score berechnen möchten, können Sie 1 verwenden - Hamming:

from sklearn.metrics.pairwise import pairwise_distances 
print(1 - pairwise_distances(df.T, metric = "hamming")) 

array([[ 1. , 0.43, 0.61, 0.55, 0.46], 
     [ 0.43, 1. , 0.52, 0.56, 0.49], 
     [ 0.61, 0.52, 1. , 0.48, 0.53], 
     [ 0.55, 0.56, 0.48, 1. , 0.49], 
     [ 0.46, 0.49, 0.53, 0.49, 1. ]]) 

In einem Datenrahmen Format:

jac_sim = 1 - pairwise_distances(df.T, metric = "hamming") 
jac_sim = pd.DataFrame(jac_sim, index=df.columns, columns=df.columns) 
# jac_sim = np.triu(jac_sim) to set the lower diagonal to zero 
# jac_sim = np.tril(jac_sim) to set the upper diagonal to zero 

     A  B  C  D  E 
A 1.00 0.43 0.61 0.55 0.46 
B 0.43 1.00 0.52 0.56 0.49 
C 0.61 0.52 1.00 0.48 0.53 
D 0.55 0.56 0.48 1.00 0.49 
E 0.46 0.49 0.53 0.49 1.00 

Sie das gleiche tun kann durch Iteration über Kombinationen von Spalten, aber es wird viel langsamer sein.

+0

Eigentlich glaube ich, ich kann die Jaccard Abstand von 1 minus Jaccard Ähnlichkeit erhalten. – kitchenprinzessin

+0

Natürlich können sich diese aufgrund der Definition ändern. Was ich meinte, war sklearn's jaccard_similarity_score ist nicht gleich 1 - sklearns jaccard distance. Aber es ist gleich 1 - sklearns Hammingdistanz. Die Definition von Wikipedia unterscheidet sich beispielsweise von der von sklearn. – ayhan

+3

Ich kann nicht glauben, dass dies nicht mehr Upvotes hat. Ausgezeichnete Arbeit. Danke – Private