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

目录

  • 一、算法介绍
    • 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 = 2similarity = 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.mzph.cn/news/866274.shtml

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

相关文章

ctfshow sql注入

开启其他注入 web221 limit注入 给出查询语句 以及过滤逻辑为空 获取数据库名即可 limit 用于控制返回结果行数 limit后面似乎只能跟PROCEDURE ANALYSE( ) 函数了 PROCEDURE ANALYSE( ) 函数用于分析查询结果的函数 参数是用来控制函数的 这个参数的位置 可以放入报错函数 原…

MySQL—创建查看删除备份恢复数据库

创建数据库 创建数据库 LLF_DB01CREATE DATABASE LLF_DB01删除数据库DROP DATABASE LLF_DB01创建一个使用utf8字符集的数据库并带校对规则的数据库CREATE DATABASE hsp_db03 CHARACTER SET utf8 COLLATE utf8_bin 查看、删除数据库 显示所有的数据库SHOW DATABASES显示数据库…

AI PC(智能电脑)技术分析

一文看懂AI PC(智能电脑) 2024年,英特尔、英伟达等芯片巨头革新CPU技术,融入AI算力,为传统PC带来质的飞跃,引领智能计算新时代。 2024年,因此被叫作人工智能电脑(AI PC)…

归一化(normalization)

归一化是指对数据进行标准化处理,使其均值为0,方差为1,从而消除不同特征量纲的影响,使得不同特征之间可以进行比较和计算。对于时间序列数据,归一化的目的是减弱非平稳性,使得模型能够更好地学习数据的规律…

2024 年第十四届 APMCM 亚太地区大学生数学建模竞赛B题超详细解题思路+数据预处理问题一代码分享

B题 洪水灾害的数据分析与预测 亚太中文赛事本次报名队伍约3000队,竞赛规模体量大致相当于2024年认证杯,1/3个妈杯,1/10个国赛。赛题难度大致相当于0.6个国赛,0.8个妈杯。该比例仅供大家参考。 本次竞赛赛题难度A:B:C3:1:4&…

C语言程序是怎么在计算机中运行起来的

hello.c #include <stdio.h>int main(){printf("hello,world\n");return 0; }这段 C语言程序的代码能被编程人员读懂&#xff0c;但是计算机系统读不懂。C语言、C、java 这些高级编程语言本质上还是人类用的语言而不是计算机用的语言。 为了能在计算机上运行这…

无忧易售功能:刊登页面文本翻译,无缝对接全球买家

每一个词语&#xff0c;每一句话&#xff0c;都承载着产品的灵魂和品牌的故事&#xff0c;无忧易售的刊登页面文本翻译服务&#xff0c;一键操作即可将你的产品介绍、详情或广告文案转化为多语言版本&#xff0c;轻松管理&#xff0c;高效发布。 一、Allegro、OZON、Coupang、…

第7章:Electron文件系统操作(2)

7.2 文件对话框 Electron 提供了 dialog 模块用于显示文件打开和保存对话框。 7.2.1 显示文件打开对话框 主进程代码&#xff1a; const { app, BrowserWindow, ipcMain, dialog } require(electron); const path require(path);let mainWindow;const createMainWindow …

盘点2024年最新鼠标连点器推荐

电脑鼠标连点器是一种可以帮助用户自动化点击操作的小工具&#xff0c;广泛应用于游戏、自动化办公和测试等领域。选择一款合适的鼠标连点器能够提高工作和娱乐的效率&#xff0c;避免重复点击带来的疲劳。小编将为您介绍电脑鼠标连点器的产品特点、推荐几款实用的鼠标连点器并…

网络中未授权访问漏洞(Rsync,PhpInfo)

Rsync未授权访问漏洞 Rsync未授权访问漏洞是指Rsync服务配置不当或存在漏洞&#xff0c;导致攻击者可以未经授权访问和操作Rsync服务。Rsync是一个用于文件同步和传输的开源工具&#xff0c;通常在Unix/Linux系统上使用。当Rsync服务未经正确配置时&#xff0c;攻击者可以利用…

Python机器学习-线性回归算法

线性关系 x和y呈一条直线 优点 简单易懂 线性模型具有一定的稳定性。从技术角度,我们在评价模型的优劣好坏时,通常从两个维度去评判,一是模型预测的准确性,二是模型预测的稳健性,两者相辅相成、缺一不可。关于模型预测的准确性,如果模型能够尽可能的拟合了历史数据信息,…

模电基础 - 简介

目录 零 .简介 一. 学习方法 二. 教材推荐 三. 总结 零 .简介 “模电”即模拟电子技术&#xff0c;是电子信息工程、电气工程及其自动化等相关专业的一门关键基础课程。 首先&#xff0c;在半导体器件方面&#xff0c;二极管是一种具有单向导电性的器件&#xff0c;由 P 型…

C# —— 日期对象

DateTime 时间类 存储时间对象 可以获取当前时间 DateTime now DateTime.Now;// 获取当前时间 Console.WriteLine("年:" now.Year);//2023 Console.WriteLine("月:" now.Month);//9 Console.WriteLine("日:" now.Day);//12 Console.WriteLi…

2.2.2 ROS2话题通信之原生消息(C++)

1.发布方实现 功能包cpp01_topic的src目录下&#xff0c;新建C文件demo01_talker_str.cpp&#xff0c;并编辑文件&#xff0c;输入如下内容&#xff1a; /* 需求&#xff1a;以某个固定频率发送文本“hello world!”&#xff0c;文本后缀编号&#xff0c;每发送一条消息&…

算法训练(leetcode)第二十二天 | 491. 非递减子序列、全排列、47. 全排列 II

刷题记录 491. 非递减子序列46. 全排列47. 全排列 II去重写法一去重写法二 491. 非递减子序列 leetcode题目地址 本题对于去重是一个难点&#xff0c;因为题目不允许排序&#xff0c;所以需要加一个笔记数组来判断相同的元素在同一层是否已经使用。使用set、map都可以达到这个…

2024开源之夏记录

研0在家摆烂&#xff0c;防止最后项目完不成&#xff0c;开篇博客督促自己记录每天的进度。

一览 Anoma 上的有趣应用概念

撰文&#xff1a;Tia&#xff0c;Techub News 本文来源香港Web3媒体&#xff1a;Techub News Anoma 的目标是为应用提供通用的意图机器接口&#xff0c;这意味着使用 Anoma&#xff0c;开发人员可以根据意图和分布式意图机编写应用&#xff0c;而不是根据事务和特定状态机进行…

pgsql+mybatis返回主键id

pgsqlmybatis返回主键id PostgreSQL使⽤MyBatis,insert时返回主键MyBatis中普通的insert语句是这样的&#xff1a; <insert id"insert" parameterType"com.xxx.xxx.xxDo">insert into "table_name" (key, value)values (#{key,jdbcTypeV…

Java增加线程后kafka仍然消费很慢

文章目录 一、问题分析二、控制kafka消费速度属性三、案例描述 一、问题分析 Java增加线程通常是为了提高程序的并发处理能力&#xff0c;但如果Kafka仍然消费很慢&#xff0c;可能的原因有&#xff1a; 网络延迟较大&#xff1a;如果网络延迟较大&#xff0c;即使开启了多线…

新手拍短视频的些许建议

1、尽早行动&#xff0c;拒绝完美主义&#xff0c;有手机就能上车&#xff0c;一开始别花太多时间在打磨细节上。总是要准备好了后再做&#xff0c;就总比别人慢一步&#xff0c;可能永远也追不上了&#xff1b; 2、坚持发&#xff0c;度过难熬的启动期就行&#xff0c;不要走…