pandas: calculez la similarité jaccard pour chaque ligne en fonction de la valeur d'une autre colonne

Dec 15 2020

J'ai un dataframe comme suit, uniquement avec plus de lignes:

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'])

Pour calculer la similitude du jaccard, j'ai trouvé cette pièce en ligne (pas ma solution):

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

ce que je voudrais obtenir en conséquence, c'est que la mesure prenne chaque ligne de la deuxième colonne comme doc et compare chaque paire de manière itérative et génère une mesure avec le nom de la ligne de la première colonne quelque chose comme ceci:

First value and Second value = 80 

First value and Third value  = 95

Second value and Third value = 90

Réponses

AmitAmola Dec 15 2020 at 23:04

Eh bien, je le ferais un peu comme ceci:

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}")

Production:

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

Étant donné que vos données ne sont pas volumineuses, vous pouvez essayer de diffuser avec une approche légèrement différente:

# 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

Production:

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