pandas: Berechnen Sie die Jaccard-Ähnlichkeit für jede Zeile basierend auf dem Wert in einer anderen Spalte

Dec 15 2020

Ich habe einen Datenrahmen wie folgt, nur mit mehr Zeilen:

import pandas as pd

data = {'First':  ['First value', 'Second value','Third value'],
'Second': [['old','new','gold','door'], ['old','view','bold','door'],['new','view','world','window']]}

df = pd.DataFrame (data, columns = ['First','Second'])

Um die Jaccard-Ähnlichkeit zu berechnen, habe ich dieses Stück online gefunden (nicht meine Lösung):

def lexical_overlap(doc1, doc2): 
    words_doc1 = set(doc1) 
    words_doc2 = set(doc2)

    intersection = words_doc1.intersection(words_doc2)
    union = words_doc1.union(words_doc2)
    
    return float(len(intersection)) / len(union) * 100

Als Ergebnis möchte ich, dass die Kennzahl jede Zeile der zweiten Spalte als Dokument verwendet und jedes Paar iterativ vergleicht und eine Kennzahl mit dem Zeilennamen aus der ersten Spalte wie folgt ausgibt:

First value and Second value = 80 

First value and Third value  = 95

Second value and Third value = 90

Antworten

AmitAmola Dec 15 2020 at 23:04

Nun, ich würde es so machen:

from itertools import combinations

for val in list(combinations(range(len(df)), 2)):
    firstlist = df.iloc[val[0],1]
    secondlist = df.iloc[val[1],1]
    
    value = round(lexical_overlap(firstlist,secondlist),2)
    
    print(f"{df.iloc[val[0],0]} and {df.iloc[val[1],0]}'s value is: {value}")

Ausgabe:

First value and Second value's value is: 33.33
First value and Third value's value is: 14.29
Second value and Third value's value is: 14.29
1 QuangHoang Dec 15 2020 at 22:54

Da Ihre Daten nicht groß sind, können Sie versuchen, mit einem etwas anderen Ansatz zu senden:

# dummy for each rows
s = pd.get_dummies(df.Second.explode()).sum(level=0).values

# pair-wise jaccard
([email protected])/(s|s[:,None,:]).sum(-1) * 100

Ausgabe:

array([[100.        ,  33.33333333,  14.28571429],
       [ 33.33333333, 100.        ,  14.28571429],
       [ 14.28571429,  14.28571429, 100.        ]])