我有两个包含用户名的列表,我想计算Jaccard相似度。这可行吗?
这个帖子展示了如何计算两个字符串之间的Jaccard相似度,但我想将其应用于两个列表,其中每个元素都是一个单词(例如,用户名)。
这个帖子展示了如何计算两个字符串之间的Jaccard相似度,但我想将其应用于两个列表,其中每个元素都是一个单词(例如,用户名)。
最终我还是自己写出了解决方案:
def jaccard_similarity(list1, list2):
intersection = len(list(set(list1).intersection(list2)))
union = (len(set(list1)) + len(set(list2))) - intersection
return float(intersection) / union
对于Python 3:
def jaccard_similarity(list1, list2):
s1 = set(list1)
s2 = set(list2)
return float(len(s1.intersection(s2)) / len(s1.union(s2)))
list1 = ['dog', 'cat', 'cat', 'rat']
list2 = ['dog', 'cat', 'mouse']
jaccard_similarity(list1, list2)
>>> 0.5
对于Python2,请使用return len(s1.intersection(s2)) / float(len(s1.union(s2)))
return float(len(s1.intersection(s2))) / len(s1.union(s2))
- seralouk@aventinus 我的声誉不足以在您的答案中添加评论,但为了更清晰地解释,您的解决方案测量了jaccard_similarity
但函数的名称错误地命名为jaccard_distance
,实际上应该是1-jaccard_similarity
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
@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
#pip install Distance
import distance
distance.jaccard("decide", "resize")
# Returns
0.7142857142857143
pip install simphile
from simphile import jaccard_list_similarity
list_a = ['cat', 'cat', 'dog']
list_b = ['dog', 'dog', 'cat']
print(f"Jaccard Similarity: {jaccard_list_similarity(list_a, list_b)}")
Jaccard Similarity: 0.5
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
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
jaccard_similarity([1], [0, 1])
->0.5
和jaccard_similarity([1, 1], [0, 1, 1])
->0.25
,然而第二个应该比第一个更相似,或者至少相似程度应该不亚于第一个,这取决于你如何定义Jaccard相似度。 - Muhammed Hasan Celikunion = (len(set(list1)) + len(set(list2))) - intersection
。 - Amir