【笔记】字符串相似度代码分享

目录

  • 一、算法介绍
    • 1、算法
      • 1)基于编辑距离
      • 2)基于标记
      • 3)基于序列
      • 4)基于压缩
      • 5)基于发音
      • 6)简单算法
    • 2、安装
  • 二、代码demo
    • 1、Hamming 距离
    • 2、Levenshtein 距离
    • 3、Damerau-Levenshtein距离
    • 4、Jaro 相似度
    • 5、Jaro-Winkler相似度
    • 6、Smith–Waterman相似度
    • 7、Jaccard 相似度
    • 8、Sørensen-Dice 相似度
    • 9、Tversky 相似度
    • 10、Overlap coefficient相似度
    • 11、Cosine similarity相似度
    • 12、N-gram相似度
    • 13、最长公共子字符串/子序列相似度
    • 14、Ratcliff-Obershelp相似度
  • 三、效果分析
    • 1、中文文本字符串
      • 1)效果最好排序
      • 2)速度最快排序
      • 3)综合排序
    • 2、其他
      • 1)基于压缩的应用场景
      • 2)基于发音的应用场景
      • 3)简单算法的应用场景

一、算法介绍

1、算法

1)基于编辑距离

算法函数
HammingHamminghamming
MLIPNSMlipnsmlipns
LevenshteinLevenshteinlevenshtein
Damerau-LevenshteinDamerauLevenshteindamerau_levenshtein
Jaro-WinklerJaroWinklerjaro_winkler, jaro
Strcmp95StrCmp95strcmp95
Needleman-WunschNeedlemanWunschneedleman_wunsch
GotohGotohgotoh
Smith-WatermanSmithWatermansmith_waterman

2)基于标记

算法函数
Jaccard indexJaccardjaccard
Sørensen–Dice coefficientSorensensorensen, sorensen_dice, dice
Tversky indexTverskytversky
Overlap coefficientOverlapoverlap
Tanimoto distanceTanimototanimoto
Cosine similarityCosinecosine
Monge-ElkanMongeElkanmonge_elkan
Bag distanceBagbag

3)基于序列

算法函数
最长公共子序列相似度LCSSeqlcsseq
最长公共子串相似度LCSStrlcsstr
Ratcliff-Obershelp 相似度RatcliffObershelpratcliff_obershelp

4)基于压缩

使用不同压缩算法的归一化压缩距离。

经典压缩算法:

算法函数
算术编码ArithNCDarith_ncd
RLERLENCDrle_ncd
BWT RLEBWTRLENCDbwtrle_ncd

常见压缩算法:

算法函数
平方根SqrtNCDsqrt_ncd
EntropyNCDentropy_ncd

正在开发的算法,将两个字符串比较为比特数组:

算法函数
BZ2BZ2NCDbz2_ncd
LZMALZMANCDlzma_ncd
ZLibZLIBNCDzlib_ncd

5)基于发音

算法函数
MRAMRAmra
EditexEditexeditex

6)简单算法

算法函数
前缀相似度Prefixprefix
后缀相似度Postfixpostfix
长度距离Lengthlength
身份相似度Identityidentity
矩阵相似度Matrixmatrix

2、安装

仅纯Python实现:

pip install textdistance

带有额外库以实现最大速度:

pip install "textdistance[extras]"

包含所有库(用于基准测试和测试):

pip install "textdistance[benchmark]"

带有特定算法的额外库:

pip install "textdistance[Hamming]"

提供额外库的算法有:DamerauLevenshteinHammingJaroJaroWinklerLevenshtein

二、代码demo

1、Hamming 距离

>> import textdistance as td
>> td.hamming('book', 'look')
1
>> td.hamming.normalized_similarity('book', 'look')
0.75
>> td.hamming('bellow', 'below')
3
>> td.hamming.normalized_similarity('Below', 'Bellow')
0.5

在第一个示例中,有一个不同的字符。这使得距离等于1,归一化相似度等于(4-1)/4 = 75%。在第二个示例中,比较“bellow”和“below”,前三个字母相同,但接下来的三个字母不同。因此,距离是3,归一化相似度是(6-3)/6 = 50%。

2、Levenshtein 距离

>> td.levenshtein('book', 'look')
1
>> td.levenshtein.normalized_similarity('book', 'look')
0.75
>> td.levenshtein('bellow', 'below')
1
>> td.levenshtein.normalized_similarity('Below', 'Bellow')
0.84

在第一个示例中,可以通过替换一个字母来得到另一个单词,因此归一化相似度是(4-1)/4 = 75%。在第二个示例中,有一个插入操作,因此距离是1,归一化相似度是(6-1)/6 = 84%。

3、Damerau-Levenshtein距离

>> td.levenshtein('act', 'cat')
2
>> td.levenshtein.normalized_similarity('act', 'cat')
0.34
>> td.damerau_levenshtein('act', 'cat')
1
>> td.damerau_levenshtein.normalized_similarity('act', 'cat')
0.67

Damerau-Levenshtein距离是Levenshtein 距离的一个变种,应用广泛,如拼写检查和序列分析

4、Jaro 相似度

>> td.jaro('bellow', 'below')
0.94
>> td.jaro('simple', 'plesim')
0
>> td.jaro('jaro', 'ajro')
0.92

在第一个示例中,有5个匹配字符和一个插入(这不是置换操作),因此Jaro 相似度为1/3*(5/6+5/5+6/6)。在第二个示例中,有0个匹配字符,因为共同字符不在max(|s1|, |s2|)/2-1的范围内。这就是为什么相似度为0的原因。在最后一个示例中,有4个匹配字符和第一和第二字母之间的1个置换操作,因此相似度为1/3 * (4/4+4/4+3/4) = 0.91。

5、Jaro-Winkler相似度

>> td.jaro("simple", "since")
0.7
>> t.jaro_winkler("simple", "since")
0.76

由于两个字符串有两个共同的前缀字母。Jaro-Winkler相似度大于Jaro相似度:0.7 + 0.12(1–0.7) = 0.7 + 0.06 = 0.76。

6、Smith–Waterman相似度

>> td.smith_waterman("GATTACA", "GCATGCU")
3
>> td.smith_waterman("GATTACA", "GCATGCU")
0.43

Smith–Waterman算法在生物信息学中特别有用,用于识别生物序列中的相似区域或基序

7、Jaccard 相似度

>> td.jaccard('jaccard similarity'.split(), "similarity jaccard".split())
1
>> td.jaccard('jaccard similarity'.split(), "similarity jaccard jaccard".split())
0.66

类似交并比(Intersection of Union,IoU),对比时并不考虑字符串单词的顺序

8、Sørensen-Dice 相似度

>> td.sorencen('jaccard similarity'.split(), "similarity jaccard".split())
1
>> td.sorencen('jaccard similarity'.split(), "similarity jaccard jaccard".split())
0.8

与前者相比,不考虑重复元素

9、Tversky 相似度

>> td.sorencen('tversky similarity'.split(), "similarity tversky tversky".split())
0.8
>> tversky = td.Tversky(ks=(0.5, 0.5))
>> tversky('tversky similarity'.split(), "similarity tversky tversky".split())
0.8
>> td.jaccard('tversky similarity'.split(), "similarity tversky tversky".split())
0.67
>> tversky = td.Tversky(ks=(1, 1))
>> tversky('tversky similarity'.split(), "similarity tversky tversky".split())
0.67
>> tversky = td.Tversky(ks=(0.2, 0.8))
>> tversky('tversky similarity'.split(), "similarity tversky tversky".split())
0.74

10、Overlap coefficient相似度

>> td.overlap('overlap similarity'.split(), "similarity overlap overlap".split())
1.0

计算集合交集大小与较小集合大小的比例

11、Cosine similarity相似度

>> td.cosine('cosine'.split(), "similarity".split())
0
>> td.cosine('cosine sim'.split(), "cosine sim sim".split())
0.81

12、N-gram相似度

N-gram 相似度是一种基于字符串中连续N个字符的相似度度量方法。它通过将字符串拆分为N-gram(N个连续字符的子串),然后比较这些N-gram的集合来计算两个字符串之间的相似度。下面是用 Python 实现 N-gram 相似度的代码示例:

def ngrams(string, n):
    """将字符串拆分为N-gram"""
    return [string[i:i+n] for i in range(len(string)-n+1)]

def ngram_similarity(str1, str2, n):
    """计算两个字符串的N-gram相似度"""
    ngrams1 = set(ngrams(str1, n))
    ngrams2 = set(ngrams(str2, n))
    
    intersection = ngrams1.intersection(ngrams2)
    union = ngrams1.union(ngrams2)
    
    return len(intersection) / len(union) if union else 0.0

# 示例
str1 = "hello"
str2 = "hallo"
n = 2

similarity = ngram_similarity(str1, str2, n)
print(f"{n}-gram 相似度: {similarity:.2f}")
# 2-gram 相似度: 0.33

13、最长公共子字符串/子序列相似度

>> s1, s2 = "RO PATTERN MATCHING", "RO PRACTICE"
>> td.lcsstr(s1, s2), td.lcsseq(s2, s1), td.lcsseq(s2, s1)
 ('RO P', 'RO PRATC', 'RO PRACI')
>> td.lcsstr.normalized_similarity(s1, s2), td.lcsseq.normalized_similarity(s1, s2)
 (0.21, 0.42)

最长公共子字符串专注于找出两个字符串之间的最长公共子字符串,它通过识别两个字符串共享的最长连续字符序列来衡量字符串之间的相似度
子序列不要求在原始序列中占据连续位置。因此,最长公共子序列总是大于最长公共子字符串

14、Ratcliff-Obershelp相似度

>> s1, s2 = "RO PATTERN MATCHING", "RO PRACTICE"
>> td.ratcliff_obershelp(s1, s2), td.ratcliff_obershelp(s2, s1), len(s1), len(s2)
(0.46, 0.53, 19, 11)

三、效果分析

1、中文文本字符串

在对中文文本字符串进行相似度比较时,效果和速度各有不同的算法可供选择。以下是根据效果最好和速度最快分别排序的算法:

1)效果最好排序

  1. Levenshtein:计算编辑距离,考虑到中文字符的插入、删除和替换,效果较好。
  2. Damerau-Levenshtein:比Levenshtein更进一步,考虑到字符的交换,能更准确地反映一些错别字的相似性。
  3. Jaro-Winkler:考虑字符的匹配和位移,对拼音和形近字有较好的识别效果。
  4. Needleman-Wunsch:常用于序列比对,适合处理长文本,但速度较慢。
  5. Smith-Waterman:和Needleman-Wunsch类似,但更精细,适合局部相似性比对。
  6. Cosine similarity:基于向量空间模型,适合处理词语或短句相似度,但需要预处理成向量表示。
  7. Jaccard index:基于集合的相似度计算,适合分词后的文本比较。

2)速度最快排序

  1. Hamming:适合固定长度的字符串比较,速度极快,但只能比较长度相同的字符串。
  2. Jaccard index:基于集合操作,速度较快,尤其是在分词后的文本上。
  3. Cosine similarity:向量化处理后计算余弦相似度,速度较快,但依赖预处理。
  4. Jaro-Winkler:速度相对较快,适合短文本比较。
  5. Levenshtein:虽然是动态规划算法,但优化后速度也较快,适合中短文本比较。
  6. Damerau-Levenshtein:考虑交换操作,稍慢于Levenshtein,但仍然较快。
  7. Smith-Waterman:局部比对,速度较慢,适合较短文本。
  8. Needleman-Wunsch:全局比对,速度慢,适合处理长文本。

3)综合排序

结合效果和速度,以下是综合排序:

  1. Levenshtein:综合效果和速度,适合大多数情况。
  2. Damerau-Levenshtein:效果好于Levenshtein,速度稍慢,但仍然适用。
  3. Jaro-Winkler:适合拼音和形近字,速度较快。
  4. Cosine similarity:需要预处理,但在向量化后速度较快,效果也不错。
  5. Jaccard index:适合分词后的文本比较,速度快。
  6. Needleman-Wunsch:适合长文本,效果好但速度慢。
  7. Smith-Waterman:适合局部相似性比较,效果好但速度最慢。

选择具体算法时,可以根据文本的长度、预处理的复杂度以及对效果的要求来综合考虑。
英文文本也适用

2、其他

1)基于压缩的应用场景

基于压缩的算法主要用于处理和比较大规模或复杂的数据集,因为它们能够有效地压缩和分析数据。这些算法常用于以下场景:

  1. 大数据分析:在需要处理和比较大量文本数据的场景中,如日志文件、网络爬虫数据等。
  2. 数据压缩和传输:在需要高效压缩和传输数据的应用中,这些算法可以用于优化数据存储和传输效率。
  3. 文本和字符串匹配:用于需要在大文本库中查找相似文本或字符串的场景。

2)基于发音的应用场景

基于发音的算法主要用于处理语音和文本的相似性计算,这在以下场景中尤为有用:

  1. 语音识别和处理:在语音识别系统中,用于比较和识别发音相似的词汇。
  2. 拼写纠正:在文本输入系统中,根据发音相似性来纠正拼写错误。
  3. 名称匹配:用于比较和匹配发音相似的人名、地名等,如客户关系管理系统中匹配相似的客户名字。

3)简单算法的应用场景

简单算法通常用于需要快速、直接比较的场景,这些场景不需要复杂的计算或大量数据处理:

  1. 前缀和后缀匹配:用于文件名或路径的匹配和分类,如查找特定前缀或后缀的文件。
  2. 长度比较:用于需要比较字符串长度的场景,如数据验证和清理。
  3. 身份相似度:用于简单的字符串相等性比较,如用户输入的验证码验证。
  4. 矩阵相似度:用于矩阵数据的比较,如图像处理中的像素矩阵比较。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决mysql数据库连接报错:Authentication plugin ‘caching_sha2_password‘ cannot be loaded

解决mysql数据库连接报错:Authentication plugin ‘caching_sha2_password’ cannot be loaded OperationalError: (2059, “Authentication plugin ‘caching_sha2_password’ cannot be loaded: /usr/lib/mysql/plugin/caching_sha2_password.so: cannot open sha…

人脸重建迁移攻击FRTA:绕过各种未见过的面部识别系统

随着人脸识别系统在安全关键环境中的部署日益增多,威胁行为者正在开发针对各种攻击点的复杂攻击策略。在这些攻击策略中,面部重建攻击是一个主要的威胁。面部重建攻击的主要目的是创建伪造的生物特征图像,这些图像类似于存储的生物特征模板中…

vue中数组出现__ob__: Observer属性,导致不能正确使用问题解决

直接上图,如下图,数组中出现__ob__: Observer属性,导致无法取值。 解决方案为:JSON.parse(JSON.stringify(数组变量名))深拷贝数组,重新生成一个可枚举数组。 // 处理代码如let tempIds JSON.parse(JSON.stringify(i…

实现统计n个数以下质数的个数

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h>int main() {int n 0;scanf("%d", &n);int sum 0;for (int i 1; i < n; i){for (int j 2; j < i; j) {if (i % j 0){sum;break;}}}printf("%d", n - sum-1);return 0; } n为输…

yum命令提示 错误:rpmdb: BDB0113 Thread/process 4153/139708200269632

一、报错信息 [rootDawn yum.repos.d]# yum clean all 错误&#xff1a;rpmdb: BDB0113 Thread/process 4153/139708200269632 failed: BDB1507 Thread died in Berkeley DB library 错误&#xff1a;db5 错误(-30973) 来自 dbenv->failchk&#xff1a;BDB0087 DB_RUNRECOVE…

记录通过Cloudflare部署属于自己的docker镜像源

引言 由于最近国内无法正常拉取docker镜像&#xff0c;然而找了几个能用的docker镜像源发现拉取回来的docker镜像不是最新的版本&#xff0c;部署到Cloudflare里Workers 和 Pages&#xff0c;拉取docker 镜像成功&#xff0c;故记录部署过程。 部署服务 登录Cloudflare后&…

鸿蒙开发HarmonyOS NEXT (三) 熟悉ArkTs

一、自定义组件 1、自定义组件 自定义组件&#xff0c;最基础的结构如下&#xff1a; Component struct Header {build() {} } 提取头部标题部分的代码&#xff0c;写成自定义组件。 1、新建ArkTs文件&#xff0c;把Header内容写好。 2、在需要用到的地方&#xff0c;导入…

如视“VR+AI”实力闪耀2024世界人工智能大会

7月4日&#xff0c;2024世界人工智能大会暨人工智能全球治理高级别会议&#xff08;以下简称为“WAIC 2024”&#xff09;在上海盛大开幕&#xff0c;本届大会由外交部、国家发展和改革委员会、教育部等部门共同主办&#xff0c;围绕“以共商促共享 以善治促善智”主题&#xf…

算法力扣刷题 三十一【150. 逆波兰表达式求值】

前言 栈和队列篇。 记录 三十一【150. 逆波兰表达式求值】 一、题目阅读 给你一个字符串数组 tokens &#xff0c;表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意&#xff1a; 有效的算符为 、-、* 和 / 。 每个操作…

初尝PaddleOCR识别图片中的文字

引言 PaddleOCR是一个基于飞桨深度学习框架的OCR工具包&#xff0c;它集成了丰富的文字检测、识别和后处理算法&#xff0c;能够高效、准确地识别出图片中的文字。 说明 OpenVINO.NET是一个由开源开发者sdcb发布的&#xff0c;一个个强大的工具集&#xff0c;通过优化神经网…

科普文:Linux服务器性能调优概叙

概叙 Java web应用性能分析之服务端慢和优化概叙_cpu飙高java-CSDN博客 Java web应用性能分析之【CPU飙升分析概述】_web页面性能分析cpu占满是因为死循环,还是循环过多-CSDN博客 在我们的软件服务中&#xff0c;软件部署的服务器&#xff0c;一般都是linux服务器&#xff0c…

【每天学会一个渗透测试工具】SQLmap安装教程及使用

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 ✨SQLmap简介 Sqlmap是一款开源的渗透测试工具 &#x1f680;下载及安装 下载地址&#xff1a;http://sqlmap.org/ windo…

两个Activity之间切换时UI部分重叠

书籍 《第一行代码 Android》第三版 开发 环境 Android Studio Jellyfish | 2023.3.1 setContentView android studio自动生成的SecondActivity.kt中自动生成的代码中已经绑定了second_layout.xml的布局资源&#xff0c;通过代码&#xff1a;setContentView(R.layout.secon…

windows@资源管理器中的地址栏@访问共享文件夹的各种方法@管理共享文件夹

文章目录 资源管理器中的地址栏可以访问什么访问共享文件夹&#x1f47a;UNC路径资源管理器打开共享文件夹纯命令行方式访问共享文件夹 共享文件夹相关操作查看所有已经共享的文件夹&#x1f47a;停止某个文件的共享 共享文件夹的访问控制补充匿名访问问题&#x1f60a;强制启用…

【Linux】高级IO——五种IO模型和基本概念 ,非阻塞IO,fcntl,实现非阻塞IO,同步通信和异步通信

文章目录 Linux高级IO1. 五种IO模型1.1 阻塞IO1.2 非阻塞IO1.3 信号驱动IO1.4 IO多路转接1.5 异步IO 2. 同步通信和异步通信3. 阻塞和非阻塞 Linux高级IO 1. 五种IO模型 IO是什么&#xff1f; IO是计算机领域中的缩写&#xff0c;指的是输入/输出&#xff08;Input/Output&…

【vue3|第15期】Vue3模板语法入门指南

日期:2024年7月2日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方,还望各位大佬不吝赐教,谢谢^ - ^ 1.01365 = 37.7834;0.99365 = 0.0255 1.02365 = 1377.4083…

上海网站建设如何做

上海是中国最繁华的城市之一&#xff0c;作为全国的经济、文化和科技中心&#xff0c;网站建设在上海变得越来越重要。如何做好上海网站建设&#xff0c;让网站更加吸引人&#xff0c;成为企业和个人宣传自身的重要平台呢&#xff1f; 首先&#xff0c;要有清晰的定位和目标。在…

IT之旅启航:高考后IT专业预习全攻略

✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您的点赞、关注、收藏、评论&#xff0c;是对我最大…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【密钥生成介绍及算法规格】

密钥生成介绍及算法规格 当业务需要使用HUKS生成随机密钥&#xff0c;并由HUKS进行安全保存时&#xff0c;可以调用HUKS的接口生成密钥。 注意&#xff1a; 密钥别名中禁止包含个人数据等敏感信息。 开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harm…

Java实现电子围栏的小例子

主要需求是实现一个电子围栏判断的小例子其中包括前端和后端的demo代码 引入对应的依赖库 <!--jts库通常用于几何计算和表示地理空间数据--> <dependency><groupId>org.locationtech.jts</groupId><artifactId>jts-core</artifactId><…
最新文章