如何在Python中计算包含字符串的两个列表的Jaccard相似度?

时间:2017-10-27 13:14:03

标签: python python-3.x similarity

我有两个带用户名的列表,我想计算Jaccard的相似度。可能吗?

This线程显示了如何计算两个字符串之间的Jaccard相似性,但是我想将它应用于两个列表,其中每个元素是一个单词(例如,用户名)。

8 个答案:

答案 0 :(得分:14)

毕竟我最终编写了自己的解决方案:

def jaccard_similarity(list1, list2):
    intersection = len(list(set(list1).intersection(list2)))
    print(list(set(list1).intersection(list2)))
    union = (len(list1) + len(list2)) - intersection
    return float(intersection / union)

答案 1 :(得分:10)

@aventinus我没有足够的声誉来为您的答案添加评论,但为了使事情更清楚,您的解决方案会衡量jaccard_similarity,但该函数被误称为jaccard_distance,实际上是1 - jaccard_similarity

答案 2 :(得分:6)

def jaccard_similarity(list1, list2):
    s1 = set(list1)
    s2 = set(list2)
    return len(s1.intersection(s2)) / len(s1.union(s2))
list1 = ['dog', 'cat', 'cat', 'rat']
list2 = ['dog', 'cat', 'mouse']
jaccard(list1, list2)
>>> 0.5

答案 3 :(得分:4)

假设您的用户名不重复,您可以使用相同的想法:

def jaccard(a, b):
    c = a.intersection(b)
    return float(len(c)) / (len(a) + len(b) - len(c))

list1 = ['dog', 'cat', 'rat']
list2 = ['dog', 'cat', 'mouse']
# The intersection is ['dog', 'cat']
# union is ['dog', 'cat', 'rat', 'mouse]
words1 = set(list1)
words2 = set(list2)
jaccard(words1, words2)
>>> 0.5

答案 4 :(得分:1)

如果您想包含重复的元素,则可以使用Counter,我想这是相对较快的,因为它只是幕后的扩展dict

from collections import Counter
def jaccard_repeats(a, b):
    """Jaccard similarity measure between input iterables,
    allowing repeated elements"""
    _a = Counter(a)
    _b = Counter(b)
    c = (_a - _b) + (_b - _a)
    n = sum(c.values())
    return n/(len(a) + len(b) - n)

list1 = ['dog', 'cat', 'rat', 'cat']
list2 = ['dog', 'cat', 'rat']
list3 = ['dog', 'cat', 'mouse']     

jaccard_repeats(list1, list3)      
>>> 0.75

jaccard_repeats(list1, list2) 
>>> 0.16666666666666666

jaccard_repeats(list2, list3)  
>>> 0.5

答案 5 :(得分:1)

@Aventinus(我也不能发表评论):请注意,Jaccard 是对集合的操作,因此在分母部分也应使用集合(而不是列表)。因此,例如jaccard_similarity('aa', 'ab')应该产生0.5

def jaccard_similarity(list1, list2):
    intersection = len(set(list1).intersection(list2))
    union = len(set(list1)) + len(set(list2)) - intersection

    return intersection / union

请注意,在十字路口中,无需强制先列出。另外,Python 3不需要强制转换为float。

答案 6 :(得分:1)

为了避免在联合(分母)中重复元素,我建议:

def Jaccar_score(lista1, lista2):    
    inter = len(list(set(lista_1) & set(lista_2)))
    union = len(list(set(lista_1) | set(lista_2)))
    return inter/union

答案 7 :(得分:0)

您可以使用Distance

#pip install Distance

import distance

distance.jaccard("decide", "resize")

# Returns
0.7142857142857143