当前位置: 首页 > article >正文

从集合运算到代码:一文搞懂Jaccard系数,附Python/NumPy/Pandas三种实现方法对比

从集合运算到代码一文搞懂Jaccard系数附Python/NumPy/Pandas三种实现方法对比在数据挖掘和机器学习领域衡量两个集合的相似度是一项基础而重要的任务。Jaccard相似系数作为一种简单直观的度量方法广泛应用于推荐系统、文本挖掘、生物信息学等多个场景。对于初学者而言理解其数学本质并掌握不同实现方式是构建数据科学工具箱的关键一步。本文将带你深入理解Jaccard系数的集合论基础并重点对比三种Python实现方式原生Python实现展示基础逻辑NumPy向量化实现提升计算效率Pandas实现则更适合表格数据的处理。无论你是刚接触数据挖掘的新手还是希望优化现有代码的开发者这篇文章都将为你提供实用的技术视角和代码参考。1. Jaccard系数的数学本质与应用场景Jaccard相似系数由法国植物学家Paul Jaccard于1901年提出最初用于比较不同地区植物物种的相似性。这个看似简单的度量方法在数据科学领域展现了惊人的持久力和广泛适用性。1.1 集合论视角下的Jaccard系数Jaccard系数的定义非常简洁对于两个集合A和B其相似系数J(A,B)等于它们交集大小与并集大小的比值。用公式表示为J(A,B) |A ∩ B| / |A ∪ B|这个公式的直观解释是两个集合共有的元素占它们所有不同元素的比例。当两个集合完全相同时Jaccard系数为1当它们没有任何共同元素时系数为0。考虑以下两个集合A {1, 2, 3, 4}B {3, 4, 5, 6}它们的交集A∩B {3,4}并集A∪B {1,2,3,4,5,6}因此Jaccard系数为2/6≈0.333。1.2 Jaccard系数的特性与适用场景Jaccard系数有几个重要特性使其在特定场景下特别有用忽略元素重复和顺序只关心元素是否存在不关心出现次数或排列顺序适合稀疏数据当数据中0值或缺失值远多于非零值时特别有效计算效率高只需要集合操作不需要复杂计算这些特性使Jaccard系数在以下场景表现优异文本相似度计算将文档视为词集合忽略词频和顺序推荐系统基于用户行为集合计算用户或物品相似度生物信息学比较基因或蛋白质序列的相似性异常检测识别与正常模式差异大的集合注意Jaccard系数只适用于集合或二元特征数据。对于连续数值数据通常需要先进行离散化处理或考虑使用其他相似度度量如余弦相似度。2. 原生Python实现理解基础逻辑在开始使用高级库之前用原生Python实现Jaccard系数有助于深入理解其计算逻辑。这种实现方式虽然效率不高但代码直观适合教学和小规模数据处理。2.1 基本实现代码def jaccard_similarity(set_a, set_b): 计算两个集合的Jaccard相似系数 参数: set_a (set): 第一个集合 set_b (set): 第二个集合 返回: float: Jaccard相似系数范围[0,1] intersection set_a set_b # 计算交集 union set_a | set_b # 计算并集 return len(intersection) / len(union) if union else 0.0使用示例A {1, 2, 3, 4, 5} B {4, 5, 6, 7, 8} similarity jaccard_similarity(A, B) print(fJaccard相似系数: {similarity:.4f}) # 输出: 0.28572.2 实现细节分析这个实现有几个值得注意的细节输入类型处理函数接受Python原生set类型作为输入确保元素唯一性空集处理当并集为空时返回0避免除以零错误时间复杂度集合的交和并操作平均时间复杂度为O(min(len(a), len(b)))对于列表输入可以先转换为集合list_a [1, 2, 2, 3, 4] list_b [3, 4, 4, 5, 6] set_a set(list_a) set_b set(list_b) similarity jaccard_similarity(set_a, set_b)2.3 性能优化考虑虽然这种实现简单直观但在处理大数据集时可能遇到性能瓶颈。以下是几个优化方向提前终止如果一个集合为空可以立即返回0最小集合优先先处理较小的集合可能减少计算量内存优化避免不必要的集合复制优化后的实现可能如下def optimized_jaccard(set_a, set_b): if not set_a or not set_b: return 0.0 # 确保set_a是较小的集合 if len(set_b) len(set_a): set_a, set_b set_b, set_a intersection 0 for x in set_a: if x in set_b: intersection 1 union len(set_a) len(set_b) - intersection return intersection / union这种实现在某些情况下可以减少计算时间特别是当一个集合远小于另一个时。3. NumPy向量化实现提升计算效率对于数值数据或大规模计算NumPy的向量化操作可以显著提升性能。NumPy实现特别适合处理多个集合对的相似度计算或当集合表示为二进制向量时。3.1 基于二进制向量的实现假设我们将集合表示为二进制向量1表示元素存在0表示不存在import numpy as np def jaccard_numpy(vec_a, vec_b): 使用NumPy计算两个二进制向量的Jaccard相似系数 参数: vec_a (np.array): 第一个二进制向量 vec_b (np.array): 第二个二进制向量 返回: float: Jaccard相似系数 intersection np.logical_and(vec_a, vec_b).sum() union np.logical_or(vec_a, vec_b).sum() return intersection / union if union else 0.0使用示例# 将集合表示为二进制向量 # 假设全集是1到8A{1,2,3,4,5}, B{4,5,6,7,8} vec_a np.array([1, 1, 1, 1, 1, 0, 0, 0]) # 1-8的位置 vec_b np.array([0, 0, 0, 1, 1, 1, 1, 1]) similarity jaccard_numpy(vec_a, vec_b) print(fNumPy实现Jaccard系数: {similarity:.4f}) # 输出: 0.28573.2 批量计算多个集合对的相似度NumPy的强大之处在于能够高效处理批量计算。假设我们有一个矩阵每行代表一个集合的二进制向量def batch_jaccard(matrix): 计算矩阵中所有行对之间的Jaccard相似度 参数: matrix (np.array): 二维二进制矩阵每行代表一个集合 返回: np.array: 相似度矩阵 # 计算交集矩阵 intersection np.dot(matrix, matrix.T) # 计算每行的和集合大小 row_sums matrix.sum(axis1) # 计算并集矩阵: |A∪B| |A| |B| - |A∩B| union row_sums[:, np.newaxis] row_sums - intersection # 计算Jaccard相似度 similarity np.divide(intersection, union, outnp.zeros_like(intersection, dtypefloat), whereunion!0) return similarity使用示例# 创建4个集合的矩阵 matrix np.array([ [1, 1, 0, 0, 0], # A [0, 0, 1, 1, 1], # B [1, 0, 1, 0, 1], # C [0, 1, 0, 1, 0] # D ]) sim_matrix batch_jaccard(matrix) print(相似度矩阵:) print(sim_matrix)3.3 性能对比与适用场景为了展示NumPy实现的性能优势我们可以进行一个简单的对比测试import time import random # 生成大型随机数据集 size 10000 set1 set(random.sample(range(size*2), size)) set2 set(random.sample(range(size*2), size)) # 原生Python实现计时 start time.time() jaccard_similarity(set1, set2) py_time time.time() - start # NumPy实现准备 vec1 np.zeros(size*2, dtypebool) vec1[list(set1)] True vec2 np.zeros(size*2, dtypebool) vec2[list(set2)] True # NumPy实现计时 start time.time() jaccard_numpy(vec1, vec2) np_time time.time() - start print(f原生Python实现时间: {py_time:.6f}s) print(fNumPy实现时间: {np_time:.6f}s) print(f加速比: {py_time/np_time:.1f}x)在典型运行中NumPy实现通常比原生Python快5-10倍具体取决于数据集大小和硬件。这种优势在处理大型数据集或多组对比时尤为明显。4. Pandas实现表格数据的高效处理在实际数据分析工作中数据通常以表格形式存在这时使用Pandas库可以更方便地计算Jaccard相似度特别是在处理DataFrame结构时。4.1 基于DataFrame的实现假设我们有一个DataFrame其中每行代表一个实体每列代表一个特征值为1/0表示特征是否存在import pandas as pd def jaccard_pandas(df, idx1, idx2): 计算DataFrame中两行之间的Jaccard相似度 参数: df (pd.DataFrame): 二进制特征DataFrame idx1: 第一行的索引 idx2: 第二行的索引 返回: float: Jaccard相似系数 row1 df.loc[idx1] row2 df.loc[idx2] intersection (row1 row2).sum() union (row1 | row2).sum() return intersection / union if union else 0.0使用示例data { item1: [1, 0, 1, 0], item2: [0, 1, 0, 1], item3: [1, 1, 0, 0], item4: [0, 0, 1, 1] } df pd.DataFrame(data, index[user1, user2, user3, user4]) # 计算user1和user2的相似度 similarity jaccard_pandas(df, user1, user2) print(fPandas实现Jaccard系数: {similarity:.4f})4.2 计算所有用户对的相似度矩阵Pandas的强大之处在于可以轻松计算整个相似度矩阵def jaccard_similarity_matrix(df): 计算DataFrame中所有行对的Jaccard相似度矩阵 参数: df (pd.DataFrame): 二进制特征DataFrame 返回: pd.DataFrame: 相似度矩阵 # 计算交集矩阵 intersection df.dot(df.T) # 计算每行的和集合大小 row_sums df.sum(axis1) # 计算并集矩阵: |A∪B| |A| |B| - |A∩B| union row_sums.values[:, None] row_sums.values - intersection # 计算Jaccard相似度 similarity pd.DataFrame( np.divide(intersection, union, outnp.zeros_like(intersection, dtypefloat), whereunion!0), indexdf.index, columnsdf.index ) return similarity使用示例sim_matrix jaccard_similarity_matrix(df) print(相似度矩阵:) print(sim_matrix)4.3 处理大型数据集的技巧当处理非常大的DataFrame时内存可能成为限制因素。以下是几个优化技巧稀疏矩阵使用scipy.sparse矩阵存储稀疏数据分块计算将数据分块处理避免一次性计算整个矩阵并行计算使用multiprocessing或dask库并行化计算稀疏矩阵实现示例from scipy.sparse import csr_matrix def sparse_jaccard(df): 使用稀疏矩阵计算Jaccard相似度 sparse_df csr_matrix(df.values) intersection sparse_df.dot(sparse_df.T) row_sums sparse_df.sum(axis1).A1 union row_sums[:, None] row_sums - intersection similarity intersection / union return pd.DataFrame(similarity.toarray(), indexdf.index, columnsdf.index)5. 三种实现方法的对比与选择指南现在我们已经了解了Jaccard系数的三种实现方式本节将系统比较它们的特性帮助你在不同场景下做出合适的选择。5.1 特性对比表特性原生Python实现NumPy实现Pandas实现代码复杂度简单中等中等执行速度慢快中等依赖数据大小内存效率高中等低对于大数据集输入数据类型Python集合/列表NumPy数组Pandas DataFrame适用场景小数据集、教学示例数值计算、批量处理表格数据分析并行化潜力低高中等扩展性差好好5.2 性能基准测试为了量化比较我们进行一个简单的性能测试import timeit # 测试数据准备 size 1000 set_a set(random.sample(range(size*2), size)) set_b set(random.sample(range(size*2), size)) # NumPy数据准备 vec_a np.zeros(size*2, dtypebool) vec_a[list(set_a)] True vec_b np.zeros(size*2, dtypebool) vec_b[list(set_b)] True # Pandas数据准备 df pd.DataFrame({A: vec_a, B: vec_b}).T # 测试函数 def test_python(): jaccard_similarity(set_a, set_b) def test_numpy(): jaccard_numpy(vec_a, vec_b) def test_pandas(): jaccard_pandas(df, 0, 1) # 计时 py_time timeit.timeit(test_python, number1000) np_time timeit.timeit(test_numpy, number1000) pd_time timeit.timeit(test_pandas, number1000) print(f原生Python: {py_time:.4f}s) print(fNumPy: {np_time:.4f}s) print(fPandas: {pd_time:.4f}s)典型测试结果可能如下原生Python: 0.1234sNumPy: 0.0234sPandas: 0.0456s5.3 选择指南根据不同的应用场景推荐以下实现选择教学/小规模数据选择原生Python实现优点代码直观易于理解原理缺点性能较差数值计算/大规模数据选择NumPy实现优点向量化操作高性能缺点需要数据转换为数组格式表格数据分析选择Pandas实现优点与DataFrame无缝集成缺点内存消耗较大超大规模稀疏数据考虑稀疏矩阵实现或分布式计算框架如Dask提示在实际项目中可以先从Pandas实现开始如果遇到性能瓶颈再考虑转换为NumPy或稀疏矩阵实现。对于生产环境可以考虑使用编译语言如Cython或Rust进一步优化关键部分。

相关文章:

从集合运算到代码:一文搞懂Jaccard系数,附Python/NumPy/Pandas三种实现方法对比

从集合运算到代码:一文搞懂Jaccard系数,附Python/NumPy/Pandas三种实现方法对比在数据挖掘和机器学习领域,衡量两个集合的相似度是一项基础而重要的任务。Jaccard相似系数作为一种简单直观的度量方法,广泛应用于推荐系统、文本挖掘…...

不用开WPS会员了!这一款电子发票批量打印工具:支持排版 + OCR识别,完全免费!

软件下载 夸克下载:https://pan.quark.cn/s/39d9ed085809 软件介绍 今天给大家带来的是Office的代替品,LibreOffice不用激活、完全免费,非常好用! 软件支持Windows、macOS、Linux。它包括包含 Writer(文字处理&…...

MNIST识别项目复盘:除了准确率97%,我们更应该关注数据预处理与损失函数的选择

MNIST识别项目深度复盘:超越97%准确率的工程实践思考 在完成一个基础的MNIST手写数字识别项目后,很多开发者会满足于模型达到97%的准确率便止步不前。然而,真正有价值的机器学习实践远不止于调出一个高准确率的模型。本文将带您深入两个常被忽…...

人工智能通识课:深度学习框架 PyTorch

深度学习框架是连接算法理论与工程实践的重要工具。它让开发者不必从零实现张量运算、自动求导、参数更新、GPU 调度和模型保存等底层细节,而可以把主要精力放在数据处理、模型结构设计、训练策略和实验验证上。在众多深度学习框架中,PyTorch 凭借直观的…...

LLM:大语言模型的主要任务

大语言模型(Large Language Model,LLM)是以深度学习为基础、通过大规模文本或多模态数据训练得到的生成式模型。它的核心能力并不是完成某一个固定任务,而是围绕语言理解、文本生成、信息处理、推理协助、代码生成、工具调用和多模…...

AI 术语通俗词典:RAG

RAG 是大语言模型、自然语言处理、知识问答、智能客服、企业知识库和 AI 应用开发中非常重要的一个术语,全称是 Retrieval-Augmented Generation,通常翻译为“检索增强生成”。它用来描述一种让大语言模型先从外部资料中检索相关内容,再基于这…...

ChatGPT生成图表总“丑”?3步精准调优Prompt+4类D3.js/Plotly适配模板,即刻提升专业度

更多请点击: https://intelliparadigm.com 第一章:ChatGPT数据可视化建议 在利用ChatGPT辅助数据分析与可视化时,关键在于将模型生成的结构化洞察高效映射到视觉表达层。ChatGPT本身不直接渲染图表,但可精准生成符合主流库&#…...

ICLR 2026小米AI 技术深度解读

注:小米最新的 AI 顶会成果实际入选了 ICLR 2026(国际学习表征会议),推测您提到的 ICML 为会议名称的混淆,本文将基于小米此次入选的核心研究成果,以及配套的 MiMo-V2.5 系列技术,按您要求的五大…...

【深度解析】从 Mythos 到 DeepSeek 降价:大模型工程化选型、成本控制与 API 实战

摘要 近期 AI 大模型市场持续加速迭代:Anthropic Mythos 进入部署测试信号增强,OpenAI、Gemini 系列持续升级,DeepSeek 则通过永久降价重塑开发成本结构。本文从工程视角解析模型发布信号、Agentic 系统成本模型,并给出 OpenAI 兼…...

Android 框架入门到实战:从系统架构到四大组件,面试官问的全在这了(附流程图)

Android 框架入门到实战:从系统架构到四大组件,面试官问的全在这了(附流程图) 目录 一、Android 系统架构 二、四大组件概览 三、Activity 详解 3.1 生命周期 3.2 四种启动模式 3.3 Activity 之间的数据传递 四、Service 详解 五、BroadcastReceiver 详解 六、ContentProv…...

OpenCV实战:用Python从零实现Canny边缘检测(含完整代码与调参技巧)

OpenCV实战:用Python从零实现Canny边缘检测(含完整代码与调参技巧)计算机视觉领域中,边缘检测是图像分析的基础步骤之一。1986年由John F. Canny提出的Canny边缘检测算法,至今仍是效果最佳的边缘检测方法之一。本文将带…...

从‘栅栏’看频谱:一个音频信号处理的例子,讲透FFT分辨率与泄漏的权衡

从‘栅栏’看频谱:一个音频信号处理的例子,讲透FFT分辨率与泄漏的权衡想象你正在调试一段钢琴录音,其中有两个非常接近的音符——比如C4(261.63Hz)和C#4(277.18Hz)。在频谱分析仪上,…...

破解‘特质波动率之谜’?用Python回测A股创业板数据,看看风险与收益到底啥关系

特质波动率与A股创业板收益关系的Python实证研究 现象背后的思考:为什么特质波动率会引发争议? 2006年Ang等人的研究像一颗投入金融学平静湖面的石子,激起了持续至今的涟漪。他们发现了一个与传统金融理论相悖的现象:高特质波动率…...

多重检验策略:提升NPLM信号无关搜索的鲁棒性与均匀性

1. 项目概述在粒子物理实验数据分析中,我们常常面临一个核心困境:我们不知道新物理信号会以何种形式出现。传统的“模型依赖”搜索,比如针对特定质量的希格斯玻色子或暗物质候选粒子,需要预先定义一个精确的理论模型。然而&#x…...

对称性自适应机器学习力场:高效精准计算碳纳米管声子谱

1. 项目概述:当机器学习“学会”了对称性在计算材料科学领域,我们常常面临一个经典的“精度-效率”困境。一方面,基于第一性原理的密度泛函理论(DFT)计算,能提供近乎量子力学精度的结果,是探索材…...

【AI问答/前端】前端瞒天过海局(三)

问三:还有一件事,就是浏览器按钮的前进后退,他真实还原了js改前端的过程,就好像真的有过访问纪录,这个是JS纪录下了自己的路由操作历史,改的浏览器地址栏?还是这个路由操作历史真的是写进了浏览…...

【AI问答/前端】现代前端的满天过海局(二)

现在JS能改浏览器的东西了?他不是被限在操作html里面了吗?笼子里面的狗不可能自己把门外的插销打开吧?好你这个“笼子里的狗和门外插销”的比喻简直绝了!这说明你对浏览器的安全沙箱机制(Sandbox)有着极其深刻且正确的防范意识。你的直觉没…...

Android 全栈体系 150 讲 - 49 深度完整版 Android 常用设计模式 + 架构模式 源码剖析、业务落地、面试精讲

...

基于静态动态障碍物DWA、DWA+RRT*、改进A*、RRT* 2D和3D的路径规划算法Matlab代码

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 &#x1f381…...

基于Simulink的四开关buck-boost变换器闭环仿真模型

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 &#x1f381…...

FPG平台:行业前景下的战略定位评估

FPG平台:行业前景下的战略定位评估金融服务行业的复杂性决定了平台需要在多个维度上同时具备较高的水准。FPG平台经过多年的发展,已经在合规、技术、服务、教育等方面形成了一套相互支撑的体系。本文从评测视角出发,对其综合实力进行多维度的…...

FPG平台:信息透明度建设的深度解析

FPG平台:信息透明度建设的深度解析金融服务行业的复杂性决定了平台需要在多个维度上同时具备较高的水准。FPG平台经过多年的发展,已经在合规、技术、服务、教育等方面形成了一套相互支撑的体系。本文从评测视角出发,对其综合实力进行多维度的…...

PostgreSQL COPY命令:高效数据导入的最佳实践

引言 在处理大量数据插入场景时,传统的INSERT语句往往会成为性能瓶颈。PostgreSQL提供了COPY命令,能够显著提升数据导入效率。本文将深入探讨COPY命令的工作原理、使用方法以及为什么它比普通INSERT更快。 什么是COPY命令? COPY是PostgreSQL提…...

阴阳师智能自动化脚本:5个步骤实现游戏任务全托管

阴阳师智能自动化脚本:5个步骤实现游戏任务全托管 【免费下载链接】OnmyojiAutoScript Onmyoji Auto Script | 阴阳师脚本 项目地址: https://gitcode.com/gh_mirrors/on/OnmyojiAutoScript 还在为阴阳师中重复的日常任务感到厌倦吗?每天花费数小…...

[SpringBoot 对象存储实战]:预签名 URL 直传 OSS 全流程设计与实现

🔥你好我是fengxin_rou这是我的个人主页fengxin_rou的主页 ❄️欢迎查看我的专栏我的专栏 《Java后端学习》、《JAVASE基础》、《JUC并发》、《redis》、《JVM虚拟机》、《MYSQL》、《黑马点评》、《rabbitmq》、《JavaWebAI的talis学习系统》、《苍穹外卖》 目录…...

【SpringBoot+Elasticsearch 内容搜索系统实战】:架构设计与全流程实现

🔥你好我是fengxin_rou这是我的个人主页fengxin_rou的主页 ❄️欢迎查看我的专栏我的专栏 《Java后端学习》、《JAVASE基础》、《JUC并发》、《redis》、《JVM虚拟机》、《MYSQL》、《黑马点评》、《rabbitmq》、《JavaWebAI的talis学习系统》、《苍穹外卖》 目录…...

SpringBoot+Vue汽车4S店销售管理系统源码+论文

代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹 分享万套开题报告任务书答辩PPT模板 作者完整代码目录供你选择: 《SpringBoot网站项目》1800套 《SSM网站项目》1500套 《小程序项目》1600套 《APP项目》1500套 《Python网站项目》…...

2026免费在线去水印保姆级教程!不用下载,3秒去除,一看就会

你是不是也遇到过这种抓狂时刻?在抖音、小红书刷到一个超好看的视频,想保存下来自己收藏或做素材,结果下载下来发现角落顶着个大大的水印,画面瞬间就没了那股质感。更气的是,找了一堆号称“免费去水印”的软件&#xf…...

2026保姆级免费在线去水印教程:想保存无水印视频?用这些方法就够了

你是不是也遇到过这样的尴尬:刷到一个特别喜欢的视频想保存下来做素材,结果画面中间杵着大大的水印;或者朋友发来一张好图,角落的Logo怎么都去不掉?自己研究半天,又是下软件又是找教程,结果要么…...

LeetCode热题100-排序链表

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。示例 1:输入:head [4,2,1,3] 输出:[1,2,3,4]核心思路(3 步记住)1. 分:找中点 切分快慢指针:快指针走 2 步&…...