文本字面相似度算法回顾整理

概述: 通常大家说的文本相似度多指文本语义的相似度,但是对于部分场景却会非常关注文本字面上的相似度,比如对于内容投放平台需要去判重,这就涉及看文本是否字面大量重复,需要去比较文本的字面相似度。 

梳理了下常用的字面相似度算法: 

文本字面相似度包括:

  • Simhash
  • 序列相似度(Sequence Similarity)
  • Jaccard相似度
  • 余弦相似度(Cosine Similarity)
  • Levenshtein距离
  • N-gram相似度

各种算法的概述: 

1、Simhash相似度
  • 主要思想: Simhash是一种局部敏感哈希算法,旨在快速检测近似重复的文档。它将长文本或文档转换为固定长度的指纹(通常是64位整数),使得相似的文档会产生相似的指纹。SimHash算法是Google在2007年发表的论文《Detecting Near-Duplicates for Web Crawling》中提到的一种指纹生成算法,被应用在Google搜索引擎网页去重的工作之中。

实现步骤:

  • 将文档分割成特征(如词或n-gram)
  • 对每个特征计算哈希值
  • 对每个哈希值的每一位进行加权
  • 合并所有特征的加权结果
  • 对合并结果进行阈值化,得到最终的指纹

应用场景: 

  • 网页去重
  • 文档相似度检测
  • 抄袭检测

对于文本去重这个问题,常见的解决办法有余弦算法、欧式距离、Jaccard相似度、最长公共子串等方法。但是这些方法并不能对海量数据高效的处理。
比如说,在搜索引擎中,会有很多相似的关键词,用户所需要获取的内容是相似的,但是搜索的关键词却是不同的,如“北京好吃的火锅“和”哪家北京的火锅好吃“,是两个可以等价的关键词,然而通过普通的hash计算,会产生两个相差甚远的hash串。而通过SimHash计算得到的Hash串会非常的相近,从而可以判断两个文本的相似程度。

通过对不同文本的SimHash值进而比较海明距离,从而判断两个文本的相似度。海明距离越小,相似度越低(根据 Detecting Near-Duplicates for Web Crawling 论文中所说),一般海明距离为3就代表两篇文章相同。

什么是海明距离呢?

简单的说,海明距离(Hamming distance)可以理解为,两个二进制串之间相同位置不同的个数。

举个例子,[1,1,1,0,0,0]和[1,1,1,1,1,1]的海明距离就是3。

在处理大规模数据的时候,我们一般使用64位的SimHash,正好可以被一个long型存储。这种时候,海明距离在3以内就可以认为两个文本是相似的。

实现代码: 

from simhash import Simhash
def simhash_similarity(text1, text2):"""计算两个文本的Simhash相似度"""hash1 = Simhash(get_features(text1))hash2 = Simhash(get_features(text2))distance = hash1.distance(hash2)return 1 - (distance / 64)  # 64

2、序列相似度(基于最长公共子序列LCS)

主要思想: 通过找到两个序列中最长的公共子序列来衡量它们的相似度。子序列不需要连续,但必须保持原始顺序。

实现步骤:

  1. 构建一个矩阵来存储两个序列的所有子问题的解
  2. 填充矩阵,每个单元格表示到当前位置的LCS长度
  3. 回溯矩阵以构建最长公共子序列
  4. 计算相似度:LCS长度 / max(序列1长度, 序列2长度)

应用场景:

  • 文本比较和差异检测
  • 生物信息学中的DNA序列比对
  • 版本控制系统中的文件比较

实现代码: 

from difflib import SequenceMatcher
def sequence_similarity(text1, text2):"""计算两个文本的序列相似度"""matcher = SequenceMatcher(None, text1, text2)return matcher.ratio()

3、Jaccard相似度

主要思想: 衡量两个集合的相似度,通过计算它们交集的大小除以并集的大小。

实现步骤:

  1. 将文本转换为集合(如单词集或字符集)
  2. 计算两个集合的交集
  3. 计算两个集合的并集
  4. 相似度 = 交集大小 / 并集大小

应用场景:

  • 文档相似度计算
  • 推荐系统
  • 聚类分析

实现代码

def jaccard_similarity(text1, text2):"""计算两个文本的Jaccard相似度"""set1 = set(text1)set2 = set(text2)intersection = set1.intersection(set2)union = set1.union(set2)return len(intersection) / len(union)
4、余弦相似度

主要思想: 将文本表示为向量空间中的点,然后计算这些向量之间的夹角余弦值来衡量相似度。

实现步骤:

  1. 将文本转换为词频向量
  2. 计算两个向量的点积
  3. 计算每个向量的模长
  4. 相似度 = 点积 / (向量1模长 * 向量2模长)

应用场景:

  • 信息检索
  • 文本分类
  • 推荐系统

代码: 

from collections import Counter
def cosine_similarity(text1, text2):"""计算两个文本的余弦相似度"""vec1 = Counter(text1)vec2 = Counter(text2)intersection = set(vec1.keys()) & set(vec2.keys())numerator = sum([vec1[x] * vec2[x] for x in intersection])sum1 = sum([vec1[x]**2 for x in vec1.keys()])sum2 = sum([vec2[x]**2 for x in vec2.keys()])denominator = np.sqrt(sum1) * np.sqrt(sum2)if not denominator:return 0.0return numerator / denominator

5、Levenshtein距离

主要思想: 计算将一个字符串转换为另一个字符串所需的最小编辑操作(插入、删除、替换)次数。

实现步骤:

  1. 创建一个矩阵来存储子问题的解
  2. 初始化第一行和第一列
  3. 填充矩阵,每个单元格表示到当前位置的最小编辑距离
  4. 矩阵右下角的值即为Levenshtein距离

应用场景:

  • 拼写检查
  • DNA序列比对
  • 模糊字符串匹配

代码实现: 

def levenshtein_distance(s1, s2):"""计算两个字符串的Levenshtein距离"""if len(s1) < len(s2):return levenshtein_distance(s2, s1)if len(s2) == 0:return len(s1)previous_row = range(len(s2) + 1)for i, c1 in enumerate(s1):current_row = [i + 1]for j, c2 in enumerate(s2):insertions = previous_row[j + 1] + 1deletions = current_row[j] + 1substitutions = previous_row[j] + (c1 != c2)current_row.append(min(insertions, deletions, substitutions))previous_row = current_rowreturn previous_row[-1]def levenshtein_similarity(text1, text2):"""基于Levenshtein距离计算相似度"""distance = levenshtein_distance(text1, text2)max_length = max(len(text1), len(text2))return 1 - (distance / max_length)def sliding_window_similarity(text1, text2):"""使用滑动窗口计算子集相似度"""try:# 动态选择window_size为较短文本的长度window_size = min(len(text1), len(text2))if len(text1) < len(text2):text1, text2 = text2, text1best_similarity = 0for i in range(len(text1) - window_size + 1):window = text1[i:i+window_size]similarity = 1 - levenshtein_distance(window, text2) / max(len(window), len(text2))best_similarity = max(best_similarity, similarity)return best_similarityexcept Exception as e:logger.error(f"Error calculating sliding_window_similarity Levenshtein similarity: {str(e)}")raise

6、N-gram相似度

主要思想: 将文本分割成连续的n个字符(或词)的序列,然后比较这些序列的重合程度。

实现步骤:

  1. 将文本分割成n-gram
  2. 计算两个文本的n-gram集合的交集
  3. 计算两个文本的n-gram集合的并集
  4. 相似度 = 交集大小 / 并集大小

应用场景:

  • 语言识别
  • 拼写检查
  • 文本分类

代码实现: 

def ngram_similarity(text1, text2, n=3):"""计算n-gram相似度"""def get_ngrams(text, n):return [text[i:i+n] for i in range(len(text)-n+1)]ngrams1 = get_ngrams(text1, n)ngrams2 = get_ngrams(text2, n)common = set(ngrams1) & set(ngrams2)unique = set(ngrams1) | set(ngrams2)return len(common) / len(unique)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/53056.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习记录——day41 运算符重载

运算符默认不支持自定义的类&#xff0c;但是可以通过运算符重载扩展运算符的属于范围 运算符重载&#xff0c;也是实现泛型编程的一种&#xff0c;能够实现“一符多用”&#xff0c;可以使用运算符重载来完成对象与对象之间的符号运算 注&#xff1a;运算符重载仅针对类对象 不…

Python量化交易需要注意的股票交易佣金包含哪些

炒股自动化&#xff1a;申请官方API接口&#xff0c;散户也可以 python炒股自动化&#xff08;0&#xff09;&#xff0c;申请券商API接口 python炒股自动化&#xff08;1&#xff09;&#xff0c;量化交易接口区别 Python炒股自动化&#xff08;2&#xff09;&#xff1a;获取…

Web安全:SQL注入实战测试.(扫描 + 测试)

Web安全&#xff1a;SQL注入实战测试. SQL注入就是 有些恶意用户在提交查询请求的过程中 将SQL语句插入到请求内容中&#xff0c;同时程序的本身对用户输入的内容过于相信&#xff0c;没有对用户插入的SQL语句进行任何的过滤&#xff0c;从而直接被SQL语句直接被服务端执行&am…

【Python】3.基础语法(3)函数

文章目录 1.函数2.语法格式3.函数参数4. 函数返回值5. 变量作用域6.函数执行过程7. 链式调用8.嵌套调用9. 函数递归10. 参数默认值11. 关键字参数 1.函数 编程中的函数, 是一段 可以被重复使用的代码片段。 代码示例: 求数列的和, 不使用函数 # 1. 求 1 - 100 的和 sum 0 f…

“立创EDA专业版”笔记

目录 二、立创EDA专业版 2.0 整体功能 2.0.1 快捷键 2.1 右侧功能栏 2.1.1 过滤 2.2 PCB设计 2.2.1 切换亮度 2.2.2 偏移 2.2.3 单位切换 2.2.4 检查DRC 2.2.5 重新铺铜 2.2.6 布线 2.2.7 锁定 2.2.8 “过滤”设置锁定 2.3 上方菜单栏 2.3.1 保存文件 2.4 元件…

安卓(Android)平台上的MVVM架构:关键知识点、优劣分析及实践示例

​ 一、安卓MVVM架构核心知识点 1.1、架构组成 1.1.1、Model层 承载业务逻辑与数据实体&#xff0c;独立于UI并与ViewModel进行交互&#xff0c;实现数据获取与处理功能。 1.1.2、View层 负责用户界面展示&#xff0c;借助Android XML布局文件及Activity/Fragment等组件&a…

Java学习第六天

Java进阶知识面向对象 static&#xff1a;是静态的意思&#xff0c;可以修饰成员变量&#xff0c;表示该成员变量在内存中只存储一份&#xff0c;可以被共享访问。 静态成员变量&#xff08;有static修饰&#xff0c;属于类&#xff0c;内存中加载一次&#xff09;&#xff1a…

网络安全-安全渗透简介和安全渗透环境准备

文章目录 前言1. 安全渗透简介1.1 什么是安全渗透&#xff1f;1.2 安全渗透所需的工具1.3 渗透测试流程 2. 使用 Kali Linux 进行安全渗透2.1 下载ISO镜像2.2 下载VMware Workstaion软件2.3 Kali Linux简介2.4 准备Kali Linux环境2.5 Kali Linux初始配置2.6 VIM鼠标右键无法粘贴…

从汇编层看64位程序运行——likely提示编译器的优化案例和底层实现分析

大纲 代码分析with_attributes::powno_attributes::pow分析 我们在《Modern C——使用分支预测优化代码性能》一文中介绍了likely提示编译器进行编译优化&#xff0c;但是我们又讲了最终优化不是对分支顺序的调换&#xff0c;那么它到底做了什么样的优化&#xff0c;让整体性能…

Temu、Shein半托管vs全托管?养号测评怎么整?

2024年&#xff0c;跨境电商的市场风向又变了&#xff01;1月4日&#xff0c;阿里旗下的速卖通推出半托管模式&#xff0c;通过免佣金和现金补贴吸引卖家&#xff1b;同月&#xff0c;拼多多的Temu也在美国上线了半托管服务&#xff0c;TikTok Shop和SHEIN紧随其后。这给才流行…

Vue学习笔记 二

4、Vue基础扩展 4.1 插槽 组件的最大特性就是复用性,而用好插槽能大大提高组件的可复用能力在Vue中插槽是很重要的存在,通过插槽,我们可以把父组件中指定的DOM作用到子组件的任意位置,后面我们坐项目用到的组件库比如element-ui,vant-ui都频繁用到的插槽,Vue的插槽主要有…

突发性网络攻击的安全挑战分析

“网络战争对 21 世纪的意义可能就如同闪电战对 20 世纪的意义一样”, 突发性网络攻击作为 网络战争的新兴形式&#xff0c;对于世界来说仍是国家安全领域的新问题&#xff0c;对网络安全治理带来了不可忽视 的严峻挑战。 第一&#xff0c;结合当下的战略背景&#xff0c;突…

MySQL:简述多版本并发控制MVCC

一、MVCC的概念 1、MVCC 数据库并发场景有三种&#xff0c;分别为&#xff1a; &#xff08;1&#xff09;读读&#xff1a;不存在任何问题&#xff0c;也不需要并发控制。 &#xff08;2&#xff09;读写&#xff1a;有线程安全问题&#xff0c;可能会造成事务隔离性问题&am…

最新!yolov10+deepsort的目标跟踪实现

目录 yolov10介绍——实时端到端物体检测 概述 主要功能 型号 性能 方法 一致的双重任务分配&#xff0c;实现无 NMS 培训 效率-精度驱动的整体模型设计 提高效率 精度提升 实验和结果 比较 deepsort介绍&#xff1a; yolov10结合deepsort实现目标跟踪 效果展示…

小程序封装接口请求

1. 安装 wechat-http 包 npm install init -y npm install wechat-http2. 创建 `http.js` 文件 // utils/http.js import WechatHttp from wechat-http; import { handleBusinessError } from ./errorHandling; // 引入你自定义的业务错误处理函数// 初始化 WechatHttp 实例 …

.NET周刊【9月第1期 2024-09-01】

国内文章 【音视频通话】使用asp.net core 8vue3 实现高效音视频通话 https://www.cnblogs.com/1996-Chinese-Chen/p/18384394 该文章描述了使用SRS实现音视频通话和共享桌面的经验。从最初使用nginx的RTMP到研究SRS和ZLMediaKit的过程&#xff0c;再到最终实现功能的详细步…

TF | SD 卡出现无法删除的文件,乱码文件该如何处理 macOS

TF | SD 卡出现无法删除的文件&#xff0c;乱码文件该如何处理 macOS 一、问题描述 最近手头有张用在 Miyoo 掌机上的游戏 TF 卡&#xff0c;在macOS 系统下在回收站中出现了几个特殊文件名的文件&#xff0c;始终无法删除。 二、试着解决 我试过了网上的所有方法都无法删除…

RuoYi-Cloud 部署与配置 [CentOS7]

静态IP设置 # 修改网卡配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33# 修改文件内容 TYPEEthernet PROXY_METHODnone BROWSER_ONLYno BOOTPROTOstatic IPADDR192.168.18.130 NETMASK255.255.255.0 GATEWAY192.168.18.2 DEFROUTEyes IPV4_FAILURE_FATALno IPV6INIT…

Electron桌面应用与文件路径处理:从Git、SourceTree到TortoiseGit的安装与配置

更多内容前往个人网站&#xff1a;孔乙己大叔 在开发Electron桌面应用程序时&#xff0c;正确处理文件路径是一个至关重要的环节。特别是当涉及到需要调用外部程序&#xff08;如Git、SourceTree或TortoiseGit&#xff09;时&#xff0c;确保这些程序安装在正确的位置&#xff…

@Tanstack/vue-query 的使用介绍

Tanstack/vue-query 的使用介绍 前言 在今年的vue conf 会议上&#xff0c;提到了vue-query这个库&#xff0c;这里对它的基本使用做一个介绍。 会议资料地址&#xff1a; https://vueconf.cn/ Tanstack-query的前身是react-query&#xff0c;是一个本地的服务端状态管理的库…