Python:Jaccard 相似度和距离
👇 连享会 · 推文导航 | www.lianxh.cn
🍎 Stata:Stata基础 | Stata绘图 | Stata程序 | Stata新命令 📘 论文:数据处理 | 结果输出 | 论文写作 | 数据分享 💹 计量:回归分析 | 交乘项-调节 | IV-GMM | 时间序列 | 面板数据 | 空间计量 | Probit-Logit | 分位数回归 ⛳ 专题:SFA-DEA | 生存分析 | 爬虫 | 机器学习 | 文本分析 🔃 因果:DID | RDD | 因果推断 | 合成控制法 | PSM-Matching 🔨 工具:工具软件 | Markdown | Python-R-Stata 🎧 课程:公开课-直播 | 计量专题 | 关于连享会
连享会 · 2022 空间计量专题
作者:梁淑珍 (华侨大学)
邮箱:13514084150@163.com
编者按:本文主要整理自「Jaccard similarity and Jaccard distance in Python」,特此致谢!
温馨提示: 文中链接在微信中无法生效。请点击底部「阅读原文」。或直接长按/扫描如下二维码,直达原文:
目录
1. 前言
2. Jaccard 相似度的定义
3. Jaccard 相似度的计算
4. Jaccard 距离的定义
5. Jaccard 距离的计算
6. 非对称二元变量的相似度和距离
7. Python 计算 Jaccard 相似度
8. Python 计算 Jaccard 距离
9. Python 计算非对称二元变量
10. Python 计算中文 Jaccard 相似度
11. 相关推文
1. 前言
Jaccard 相似度,广泛应用于数据之间相似程度的计算,如集合相似度、文本相似度等。本文的 Python 实例需要使用到 scipy
、sklearn
和 numpy
三个模块,具体安装命令如下:
pip install scipy
pip install sklearn
pip install numpy
2. Jaccard 相似度的定义
Jaccard 相似度 (又称 Jaccard 相似系数,或 Jaccard 指数),是用来计算两个集合之间相似度的统计量,并且可以拓展至文本相似度的计算。在 Python 中,主要用 Jaccard 相似度来计算两个集合或非对称二元变量的相似度。在数学上,Jaccard 相似度可以表示为交集与并集之比。以集合 A 和集合 B 为例:
Jaccard 相似度的计算公式为:
公式的分子部分为两个集合的交集,如下图黄色部分所示:
公式的分母部分为两个集合的并集,如下图黄色部分所示:
在数学上,Jaccard 相似度可以理解为上图交集元素个数与并集元素个数之比,具体地:
如果两个集合相等,例如 和 ,那么 Jaccard 相似度为 1; 如果两个集合元素完全不同,例如 和 ,那么 Jaccard 相似度为 0; 如果两个集合有部分相同元素,例如 和 ,那么 Jaccard 相似度介于 0 和 1。
3. Jaccard 相似度的计算
考虑以下两个集合: 和 ,在图中可以表示为:
第一步:找到两个集合的交集。在本例中,。
第二步:找到两个集合的并集。在本例中,。
第三步:计算比率。
4. Jaccard 距离的定义
与 Jaccard 相似度不同,Jaccard 距离测量的是两个集合不相似程度。在数学上,可以表示为交集的补集与并集之比。同样以集合 A 和集合 B 为例:
Jaccard 距离的公式为:
Jaccard 距离的分子还能表示为:
可以更直观地理解为两个集合间的差异,如下图黄色部分所示:
Jaccard 距离的分母与 Jaccard 相似度相同,均为两个集合的并集。
在数学上,Jaccard 距离可以理解为集合差异元素个数与并集元素个数之比。具体地:
如果两个集合相等,例如 和 ,那么 Jaccard 距离为 0; 如果两个集合元素完全不同,例如 和 ,那么 Jaccard 距离为 1; 如果两个集合有部分相同元素,例如 和 ,那么 Jaccard 距离介于 0 和 1。
5. Jaccard 距离的计算
考虑以下两个集合: 和 ,在图中可以表示为:
第一步:找到两个集合交集的补集。
第二步:找到两个集合的并集。在本例中,。
第三步:计算比率。
6. 非对称二元变量的相似度和距离
本节将讨论 Jaccard 相似度和 Jaccard 距离在非对称二元变量上的具体应用。
二元变量,顾名思义只有两个类别或状态。当取值为 0 时,表示该状态不出现;当取值为 1 时,表示该状态出现。例如,smoker 表示患者对象,1 表示患者抽烟,0 表示患者不抽烟。如果是对称二元变量,则其两种属性具有相同的权重,即不同状态用 0 或 1 编码并无偏好 (例如,用 0 和 1 编码表示性别变量)。
非对称二元变量的两种结果重要程度不同。例如核酸检测的结果分为阳性和阴性,阳性结果用 1 进行编码 (几率更低,结果更重要),阴性结果用 0 进行编码。给定两个非对称二元变量对象,两个对象都取 1 的情况比两个对象都取 0 更重要、更有意义。
假设现有两个 n 维向量 A 和 B,Jaccard 相似度的计算公式为:
Jaccard 距离的计算公式为:
其中,
表示两个向量对应分量均为 1 的数量; 表示两个向量对应分量分别为 0 和 1 的数量; 表示两个向量对应分量分别为 1 和 0 的数量; 表示两个向量对应分量均为 0 的数量。
并且 。
我们通过一个简易案例进行理解,例如一家商店销售 6 种商品 (苹果、西红柿、鸡蛋、牛奶、咖啡、糖),现有两个顾客的购买记录:
顾客 A 购买:苹果、牛奶和咖啡 顾客 B 购买:鸡蛋、牛奶和咖啡
通过上面的信息,可以构造下列矩阵:
Apple | Tomato | Eggs | Milk | Coffee | Sugar | |
---|---|---|---|---|---|---|
A | 1 | 0 | 0 | 1 | 1 | 1 |
B | 0 | 0 | 1 | 1 | 1 | 0 |
对于每一种商品而言,购买决策是一个二元变量,1 表示购买,0 表示不购买。接着,我们分两步计算 Jaccard 相似度和 Jaccard 距离:
第一步:寻找 M 值
数量 | 说明 | |
---|---|---|
(M_{11}) | 2 | A 和 B 都买了牛奶和咖啡 |
(M_{01}) | 1 | A 没买鸡蛋,B 买了鸡蛋 |
(M_{10}) | 2 | A 买了苹果和糖,但 B 都没买 |
(M_{00}) | 1 | A 和 B 都没买西红柿 |
且 ,与商品数相同,得到验证。
第二步:代入公式,则
Jaccard相似度:
Jaccard 距离:
7. Python 计算 Jaccard 相似度
在 Python 中定义两个集合:
A = {1, 2, 3, 5, 7}
B = {1, 2, 4, 8, 9}
构建函数计算 Jaccard 相似度,将集合 A 和集合 B 当做参数传入函数:
def jaccard_similarity(A, B):
# 求集合 A 和集合 B 的交集
nominator = A.intersection(B)
# 求集合 A 和集合 B 的并集
denominator = A.union(B)
# 计算比率
similarity = len(nominator)/len(denominator)
return similarity
similarity = jaccard_similarity(A, B)
print(similarity)
结果为 0.25,与手动计算的结果相同。
8. Python 计算 Jaccard 距离
使用相同的数据计算 Jaccard 距离:
def jaccard_distance(A, B):
#Find symmetric difference of two sets
nominator = A.symmetric_difference(B)
#Find union of two sets
denominator = A.union(B)
#Take the ratio of sizes
distance = len(nominator)/len(denominator)
return distance
distance = jaccard_distance(A, B)
print(distance)
结果为 0.75,与手动计算的结果相同。
9. Python 计算非对称二元变量
# 导入模块
import numpy as np
from scipy.spatial.distance import jaccard
from sklearn.metrics import jaccard_score
根据矩阵创建两个向量:
Apple | Tomato | Eggs | Milk | Coffee | Sugar | |
---|---|---|---|---|---|---|
A | 1 | 0 | 0 | 1 | 1 | 1 |
B | 0 | 0 | 1 | 1 | 1 | 0 |
A = np.array([1,0,0,1,1,1])
B = np.array([0,0,1,1,1,0])
similarity = jaccard_score(A, B)
distance = jaccard(A, B)
print(f'Jaccard similarity is equal to: {similarity}')
print(f'Jaccard distance is equal to: {distance}')
得到的结果为:
Jaccard similarity is equal to: 0.4
Jaccard distance is equal to: 0.6
10. Python 计算中文 Jaccard 相似度
import pandas as pd
import jieba
import re
# 调用数据
data = pd.read_excel("https://file.lianxh.cn/data/m/mda.xlsx")
stopwords = pd.read_csv("https://file.lianxh.cn/data/c/cn_stopwords.txt", names=["stopwords"])
# 定义分词函数def cut_words(text):
def cut_words(text):
words_list = []
text = re.sub("[\W\d]", "", text) # 替换符号和数字
words = jieba.lcut(text)
for word in words:
if word not in list(stopwords["stopwords"]):
words_list.append(word)
return" ".join(words_list)
# 对文本分词
data["BusDA"] = data["BusDA"].apply(cut_words)
data
# 定义 jaccard 相似度函数
def jaccard_similarity(list1, list2):
s1 = set(list1)
s2 = set(list2)
return float(len(s1.intersection(s2)) / len(s1.union(s2)))
jaccard_similarity(data["BusDA"][1], data["BusDA"][1])
11. 相关推文
Note:产生如下推文列表的 Stata 命令为:
lianxh python, m
安装最新版lianxh
命令:
ssc install lianxh, replace
专题:专题课程 Stata+Python:同花顺里爬取创历史新高的股票 专题:数据分享 Python+Stata:如何获取中国气象历史数据 专题:文本分析-爬虫 Python:计算管理层讨论与分析的余弦相似度 Stata+Python:爬取创历史新高股票列表 Python:爬取东方财富股吧评论进行情感分析 VaR 风险价值: Stata 及 Python 实现 支持向量机:Stata 和 Python 实现 Python爬虫: 《经济研究》研究热点和主题分析 专题:Python-R-Matlab Stata+Python:导入超大Excel文档的新思路-以国泰安为例 Stata-Python交互-10:Stata17 新特性之PyStata的配置与应用 Python:多进程、多线程及其爬虫应用 Python:爬取动态网站 Python爬取静态网站:以历史天气为例 Python:绘制动态地图-pyecharts Python爬虫1:小白系列之requests和json Python爬虫2:小白系列之requests和lxml Python爬虫:爬取华尔街日报的全部历史文章并翻译 Python爬虫:从SEC-EDGAR爬取股东治理数据-Shareholder-Activism Python:爬取巨潮网公告 Python:爬取上市公司公告-Wind-CSMAR Python: 6 小时爬完上交所和深交所的年报问询函 Python: 使用正则表达式从文本中定位并提取想要的内容
课程推荐:因果推断实用计量方法
主讲老师:邱嘉平教授
🍓 课程主页:https://gitee.com/lianxh/YGqjp
New! Stata 搜索神器:
lianxh
和songbl
GIF 动图介绍
搜: 推文、数据分享、期刊论文、重现代码 ……
👉 安装:
. ssc install lianxh
. ssc install songbl
👉 使用:
. lianxh DID 倍分法
. songbl all
🍏 关于我们
连享会 ( www.lianxh.cn,推文列表) 由中山大学连玉君老师团队创办,定期分享实证分析经验。 直通车: 👉【百度一下: 连享会】即可直达连享会主页。亦可进一步添加 「知乎」,「b 站」,「面板数据」,「公开课」 等关键词细化搜索。