NLP文本相似度算法LCS

article/2025/9/11 9:14:43

目录

  • 一、什么是LCS
    • 子序列
    • 最长公共子序列
  • 二、LCS的应用场景
  • 三、LCS的查找方法
    • 1. 动态规划法计算LCS的长度和两字符串的相似度
    • 2. 回溯算法查找LCS
  • 四、代码实现

一、什么是LCS

子序列

子序列:一个序列S任意删除若干个字符得到的新序列T,则T叫做S的子序列

最长公共子序列

最长公共子序列(Longest Common Subsequence):两个序列X和Y的公共子序列中,长度最长的那个,定义为X和Y的最长公共子序列

例如:
字符串12455245576的最长公共子序列为2455
字符串acdfg与adfc的最长公共子序列为adf

二、LCS的应用场景

请添加图片描述文本匹配:即字面匹配,是自然语言处理中一个重要的基础问题,可以应用于大量的NLP任务中,如信息检索、问答系统、复述问题、对话系统、机器翻译等,这些NLP任务在很大程度上可以抽象为文本匹配问题。

局限性

  • 词义局限:“的士”和“出租车”虽然字面上不相似,但实际为同一种交通工具;“苹果”在不同的语境下表示不同的东西,或为水果或为公司
  • 结构局限:“机器学习”和“学习机器”虽然词汇完全重合,但表达的意思不同。
  • 知识局限:“秦始皇打Dota”,这句话虽从词法和句法上看均没问题,但结合知识看这句话是不对的。

语义匹配:结合语义、语境和知识进行的文本匹配
比如 ‘苹果’ 这个词语,要结合上下文的语境才能判断指的是水果还是苹果品牌

多模态

  • 模态:模态指交流的渠道和媒介,包括语言、技术、图像、颜色、音乐等符号系统。
  • 多模态:指的便是除了文本之外,还带有图像、图表等符合话语,或者说任何由一种以上符合编码实现意义的文本
  • 多模态话语分析 :就是分析单一感官的多符号语篇或多感官的多符号语篇。

三、LCS的查找方法

1. 动态规划法计算LCS的长度和两字符串的相似度

已知两个字符串X=‘ABCBDAB’,Y=‘BDCABA’,长度分别为i=7,j=6

构建二维数组C[i,j],以0填充
在这里插入图片描述

将X的每个字符分别和Y的每个字符比较,
1.如果X和Y其中有任意一个字符串长度为0,则C[i,j]=0
2.如果X[i]=Y[j],则C[i,j]取矩阵左上角数值+1,即C[i-1,j-1]+1
3.如果X[i]≠Y[j],则C[i,j]取矩阵上和左数值中较大的一个,即max(C[i-1,j],C[i,j-1])

公式:在这里插入图片描述
矩阵按照公式填满后如下图所示:
在这里插入图片描述

序列X 和Y 的最长公共子序列的长度为 C[i,j]=4

X和Y相似度=最长公共子序列的长度*2 / X和Y的长度之和,即
sim=len(lcs)*2 / len(X)+len(Y)

本例相似度 sim=4*2 / 13 = 0.615

2. 回溯算法查找LCS

在1 中的算法查到了LCS的长度,下边我们讲把LCS查找出来
从上文的中我们发现,真正使得LCS计算长度增加的有效数字,只有下边这种情况

2.如果X[i]=Y[j],则C[i,j]取矩阵左上角数值+1,即C[i-1,j-1]+1

在矩阵中标识出这些数字

在这里插入图片描述
注:C[i-1,j-1]+1=max(C[i-1,j],C[i,j-1]),即 左上角数字+1=上、左数字较大值的情况,不计入有效

从C[i,j] 右下角出发,向左上角 i,j 递减的方向,每个梯度数字选择一个,找出所有满足条件的路径
在这里插入图片描述
找到每条路径路过的有效数字正上方Y中对应的字符,则找到所有的LCS
本例的结果为:BCBA,BCAB,BDAB

四、代码实现

# coding=utf-8
class LCS():def input(self,x, y):#读入待匹配的两个字符串if type(x) != str or type(y) != str:print ('input error')return Noneself.x = xself.y = ydef Compute_LCS(self):xlength = len(self.x)ylength = len(self.y)self.direction_list = [None] * xlength #这个二维列表存着回溯方向for i in range(xlength):self.direction_list[i] = [None] * ylengthself.lcslength_list = [None] * (xlength + 1)#这个二维列表存着当前最长公共子序列长度for j in range(xlength + 1):self.lcslength_list[j] = [None] * (ylength + 1)for i in range(0, xlength + 1):self.lcslength_list[i][0] = 0for j in range(0, ylength + 1):self.lcslength_list[0][j] = 0#下面是进行回溯方向和长度表的赋值for i in range(1, xlength + 1):for j in range(1, ylength + 1):if self.x[i - 1] == self.y[j - 1]:self.lcslength_list[i][j] = self.lcslength_list[i - 1][j - 1] + 1self.direction_list[i - 1][j - 1] = 0  # 左上elif self.lcslength_list[i - 1][j] > self.lcslength_list[i][j - 1]:self.lcslength_list[i][j] = self.lcslength_list[i - 1][j]self.direction_list[i - 1][j - 1] = 1  # 上elif self.lcslength_list[i - 1][j] < self.lcslength_list[i][j - 1]:self.lcslength_list[i][j] = self.lcslength_list[i][j - 1]self.direction_list[i - 1][j - 1] = -1  # 左else:self.lcslength_list[i][j] = self.lcslength_list[i - 1][j]self.direction_list[i - 1][j - 1] = 2  # 左或上self.lcslength=self.lcslength_list[-1][-1]#遍历矩阵for i in range(len(self.lcslength_list)):     for j in range(len(self.lcslength_list[i])):print(self.lcslength_list[i][j], end='\t')print('')sum_len=xlength + ylengthsimilarity=float(float(self.lcslength * 2) / float(sum_len))print('max_len:',self.lcslength,',sum_len:',sum_len,'similarity:',similarity)return self.direction_list, self.lcslength_listdef printLCS(self, curlen, i, j, s):if i == 0 or j == 0:return Noneif self.direction_list[i - 1][j - 1] == 0:if curlen == self.lcslength:s += self.x[i - 1]for i in range(len(s)-1,-1,-1):print (s[i], end=''),print('')elif curlen < self.lcslength:s += self.x[i-1]self.printLCS(curlen + 1, i - 1, j - 1, s)elif self.direction_list[i - 1][j - 1] == 1:self.printLCS(curlen,i - 1, j,s)elif self.direction_list[i - 1][j - 1] == -1:self.printLCS(curlen,i, j - 1,s)else:self.printLCS(curlen,i - 1, j,s)self.printLCS(curlen,i, j - 1,s)def returnLCS(self):#回溯的入口self.printLCS(1,len(self.x), len(self.y),'')if __name__ == '__main__':p = LCS()p.input('ABCBDAB', 'BDCABA')p.Compute_LCS()p.returnLCS()

效果:

0	0	0	0	0	0	0	
0	0	0	0	1	1	1	
0	1	1	1	1	2	2	
0	1	1	2	2	2	2	
0	1	1	2	2	3	3	
0	1	2	2	2	3	3	
0	1	2	2	3	3	4	
0	1	2	2	3	4	4	
max_len: 4 ,sum_len: 13 similarity: 0.6153846153846154
BCBA
BCAB
BDAB

http://chatgpt.dhexx.cn/article/YYry2kfp.shtml

相关文章

文本相似度算法对比分析,判断内容相似的算法有

有哪些算法用于比较两个字符串的相似程度 终于知道怎么判断字符串相似度了 一直不理解&#xff0c;为什么要计算两个字符串的相似度呢rfid。什么叫做两个字符串的相似度。经常看别人的博客&#xff0c;碰到比较牛的人&#xff0c;然后就翻了翻&#xff0c;终于找到了比较全面…

文本相似度算法对比分析,短文本相似度主流算法

如何检查多个word文档内容的相似度 工具/材料&#xff1a;电脑、WORD。第一步&#xff0c;打开电脑进入桌面&#xff0c;打开软件进界面。第二步&#xff0c;打开软件进入后&#xff0c;打开相应的文档。第三步&#xff0c;找到上方菜单栏的审阅点击。第四步&#xff0c;点击后…

文本相似度算法总结

文本匹配算法主要用于搜索引擎&#xff0c;问答系统等&#xff0c;是为了找到与目标文本最相关的文本。例如信息检索可以归结成查询项和文档的匹配&#xff0c;问答系统可以归结为问题和候选答案的匹配&#xff0c;对话系统可以归结为对话和回复的匹配。 一、传统模型 基于字面…

计算文本相似度

&#xfeff;&#xfeff; 计算文本相似度 推荐 2 收藏 简单讲解 上一章有提到过[基于关键词的空间向量模型]的算法&#xff0c;将用户的喜好以文档描述并转换成向量模型&#xff0c;对商品也是这么处理&#xff0c;然后再通过计算商品文档和用户偏好文档的余弦相似度。 文本相…

计算文本相似度的常用算法

文章目录 1. 余弦相似度2. TF-IDF模型2.1 词频TF的计算方法2.2 反文档频率IDF的计算方法2.3 TF-IDF的计算方法 3. 基于语义相似度的计算 —— DSSM4. LSI/LSA模型5. LDA模型6. 编辑距离计算7. 杰卡德系数计算8. Word2Vec计算9. BM25 NLP、数据挖掘领域中&#xff0c;文本分析是…

LCS、LIS

LCS是最长公共子序列的表示&#xff1a; 题目链接 代码也十分简单就不敲了。 LIS是最长上升子序列的英文缩写。 (动态规划) O(n2)O(n2) 状态表示&#xff1a;f[i]表示从第一个数字开始算&#xff0c;以w[i]结尾的最大的上升序列。(以w[i]结尾的所有上升序列中属性为最大值的…

LCMV相关的算法

写这个程序的时候&#xff0c;我们遵循如下的设计过程&#xff1a; 第一&#xff1a;设计LCMV&#xff1b; 第二&#xff1a;降秩LCMV&#xff1b; 第三&#xff1a;自适应降秩LCMV&#xff1b; 下面我首先给你捋一下整个算法的大致思路&#xff1a; 输入信号&#xff1a; …

SCC算法求强连通分量简单讲解证明及实现

目录 强连通分量SCC算法简介两个概念dfs结束时间转置图 SCC算法伪代码描述SCC算法正确性证明引理1&#xff1a;引理2&#xff1a;SCC证明不错找不漏找 代码实现 强连通分量 连通分量要求任意两点可达&#xff0c;而强连通分量要求任意两点互相可达&#xff0c;即必须存在a->…

最长公共子串LCS (Longest Common Subsequence) 算法

三个方法都有所借鉴&#xff0c;但代码部分是自己试着写出来的&#xff0c;虽然最后的运行结果都是正确的&#xff0c;但此过程中难免会有考虑不周全的地方&#xff0c;如发现代码某些地方有误&#xff0c;欢迎指正。同时有新的想法&#xff0c;也可以提出! 采用顺序结构存储串…

常考的经典算法--最长公共子序列(LCS)与最长公共子串(DP)

《1》最长公共子序列&#xff08;LCS&#xff09;与最长公共子串(DP) http://blog.csdn.net/u012102306/article/details/53184446 https://segmentfault.com/a/1190000007963594 http://www.cppblog.com/mysileng/archive/2013/05/14/200265.html 1. 问题描述 子串应该比…

LCS算法学习

LCS的定义 最长公共子序列&#xff0c;即Longest Common Subsequence&#xff0c;LCS。一个序列S任意删除若干个字符得到新序列T&#xff0c;则T叫做S的子序列&#xff1b;两个序列X和Y的公共子序列中&#xff0c;长度最长的那个&#xff0c;定义为X和Y的最长公共子序列。 字符…

算法系列之六:最长公共子序列(LCS)问题(连续子序列)的三种解法

最长公共子序列&#xff08;LCS&#xff09;问题有两种方式定义子序列&#xff0c;一种是子序列不要求不连续&#xff0c;一种是子序列必须连续。上一章介绍了用两种算法解决子序列不要求连续的最终公共子序列问题&#xff0c;本章将介绍要求子序列必须是连续的情况下如何用算法…

Hirschberg的LCS算法实现

解决Longest Common Subsequence(LCS)问题最常用的算法是Dyanmic programing&#xff0c;细节可以参考Ch15.4 of Introduction of Algorithm(2ED), MIT press, p 350。这个算法最大的问题是他的空间复杂度是O(m*n)。这样&#xff0c;当两个序列达到上万个节点时&#xff0c;内存…

SLIC算法

基础知识 在介绍SLIC之前&#xff0c;先来介绍以下Lab颜色空间的介绍。 Lab色彩模型是由亮度(L)要素和与有关色彩的a,b要素组成&#xff0c;L的值由0(黑色)到100(白色)&#xff0c;a表示从洋红色至绿色的范围(a为负值表示绿色而正值表示品红)&#xff0c;b表示从黄色至蓝色的…

动态规划之LCS算法

一、前言 LCS是Longest Common Subsequence的缩写&#xff0c;即最长公共子序列。一个序列&#xff0c;如果是两个或多个已知序列的子序列&#xff0c;且是所有子序列中最长的&#xff0c;则为最长公共子序列。 另外还有个分支问题&#xff1a;最长公共子串。子串的字符位置必…

LCS算法的C++实现

这两天忙里偷闲看了July的团队提供的LCS算法视频&#xff0c;真的如视频标题一样&#xff0c;十分钟搞定LCS算法。 感谢July大神&#xff0c;感谢其团队的邹博。 这里附上视频链接&#xff1a;http://www.julyedu.com/video/play?course17 说是十分钟搞定&#xff0c;其实是…

算法学习 - 最长公共子序列(LCS)C++实现

最长公共子序列 最长公共子序列的问题很简单&#xff0c;就是在两个字符串中找到最长的子序列&#xff0c;这里明确两个含义&#xff1a; 子串&#xff1a;表示连续的一串字符 。子序列&#xff1a;表示不连续的一串字符。 所以这里要查找的是不连续的最长子序列&#xff0c; …

SLIC算法介绍

SLIC&#xff08;simple linear iterativeclustering&#xff09;&#xff0c;即 简单线性迭代聚类 。 &#x1f49b;它是2010年提出的一种思想简单、实现方便的算法&#xff0c;将彩色图像转化为CIELAB颜色空间和XY坐标下的5维特征向量&#xff0c;然后对5维特征向量构造距离度…

LSC算法

1.问题 给定序列 X<x_1,x_2,…,x_m> Y<y_1,y_2,…,y_j> 求X和Y的最长公共子序列(LCS) 2.解析 X<x1,x2,x3,x4…,xi> Y<y1,y2,y3,y4…,yi> 如果Z<z1,z2,z3,z4…,zk>是他们的最长公共子序列 则&#xff1a; &#xff08;1&#xff09;xi yi&…

LCS算法详解

程序员编程艺术第十一章&#xff1a;最长公共子序列(LCS)问题 0、前言 程序员编程艺术系列重新开始创作了&#xff08;前十章&#xff0c;请参考程序员编程艺术第一~十章集锦与总结&#xff09;。回顾之前的前十章&#xff0c;有些代码是值得商榷的&#xff0c;因当时的代码只顾…