引入语义标签过滤:利用标签相似度增强检索

news/2024/9/19 7:01:03/文章来源:https://www.cnblogs.com/little-horse/p/18415818

引入语义标签过滤:利用标签相似度

增强检索

传统的标签搜索缺乏灵活性。如果我们要过滤恰好包含给定标签的样本,可能会出现这样的情况,特别是对于只包含几千个样本的数据库,

可能没有任何(或只有少数)与我们的查询匹配的样本。

两种搜索的不同之处在于搜索结果的稀缺性

传统的标签搜索是如何工作的?

传统系统采用一种称为 Jaccard 相似性的算法(通常通过 minhash 算法执行),该算法能够计算两组元素之间的相似性(在我们的示例中,这些元素是标记)。如前所述,搜索一点也不灵活(集合要么包含,要么不包含查询的标签)。

一个简单的 AND 位操作的例子(这不是 Jaccard 相似,但可以是一个近似的过滤方法的想法)

是否能做得更好?

相反,如果我们不只是从匹配的标签中过滤样本,而是考虑样本中所有不相同但与我们选择的标签相似的其他标签,会怎么样?我们可以使算法更加灵活,将结果扩展到非完美匹配,但仍然是好的匹配。我们将直接将语义相似性应用于标签,而不是文本。

语义标签搜索

如前所述,这种新方法试图将语义搜索的功能与标签过滤系统相结合。要构建这个算法,我们只需要做一件事:

  • 一个标记样本的数据库

这里使用参考数据是 Steam 游戏库的开源集合(可从 Kaggle )-大约40,000 个样本,这是一个很好的样本量来测试我们的算法。从显示的数据框中我们可以看到,每个游戏都有几个分配的标签,在我们的数据库中有超过 400 个唯一的标签。

现在有了原始数据,我们可以继续,算法处理步骤如下:

  1. 提取标签关系
  2. 编码查询和样本
  3. 使用向量检索执行语义标签搜索
  4. 验证

本文只探讨这种新方法背后的数学原理。

1.提取标签关系

想到的第一个问题是我们如何找到标签之间的关系。请注意,有几种算法用于获得相同的结果:

  • 使用统计方法

我们可以用来提取标签关系的最简单的可使用方法被称为共现矩阵。

  • 使用深度学习

最先进的都是基于 Embeddings 神经网络(比如过去的 Word2Vec,现在常用的是使用transformers,比如 llm),可以提取样本之间的语义关系。创建一个神经网络来提取标签关系(以自动编码器的形式)是一种可能性,在面对某些情况时通常是可取的。

  • 使用预训练模型

因为标签是使用人类语言定义的,所以可以使用现有的预训练模型来计算已经存在的相似度。这可能会快得多,也不那么麻烦。然而,每个数据集都有其独特性。使用预训练的模型会忽略客户的行为。

算法的选择可能取决于很多因素,特别是当我们必须处理一个巨大的数据池或者我们有可扩展性问题时。

a.使用Michelangiolo相似度构建共现矩阵

如前所述,使用共现矩阵作为提取这些关系的手段。我的目标是找到每对标签 之间的关系,通过在所有样本集合 (S) 上使用 IoU (Intersection / Union)在整个样本集合上应用以下计数来实现:

公式来计算一对标签之间的相似性

该算法与Jaccard相似度非常相似。虽然它作用于样本,但这里介绍的作用于元素。

Jaccard相似度和Michelangiolo相似度的区别

对于 40000 个样本,提取相似矩阵大约需要一个小时,结果如下:

样本列表 S 中所有唯一标签的共现矩阵

让我们对一些非常常见的标签进行top- 10 样本的人工检查,看看结果是否有意义:

从共现矩阵中提取的样本关系

结果看起来非常有希望!我们从简单的分类数据开始(只能转换为 0 和 1),但我们已经提取了标签之间的语义关系(甚至没有使用神经网络)。

b.使用预训练的神经网络

同样,我们可以使用预训练的编码器提取样本之间的现有关系。然而,这种解决方案忽略了只能从我们的数据中提取的关系,只关注人类语言的现有语义关系。这可能不是一个非常适合在基于零售的数据之上工作的解决方案。

另一方面,通过使用神经网络,我们不需要构建关系矩阵:因此,这是可扩展性的适当解决方案。例如,如果我们必须分析大量 Twitter 数据,我们可以达到 53.300 个标签。从这个数量的标签中计算一个共现矩阵将得到一个大小为 2500,000,000 的稀疏矩阵(相当不实用的壮举)。相反,通过使用输出向量长度为 384 的标准编码器,得到的矩阵的总大小将为 19,200,200。

使用预训练编码器的一组编码标签的快照

2.编码查询和样本

我们的目标是构建一个能够支持语义标签搜索的搜索引擎:以我们一直在构建的格式,唯一能够支持这样一个企业的技术是向量搜索。因此,我们需要找到一种合适的编码算法,将我们的样本和查询都转换成向量。

在大多数编码算法中,我们使用相同的算法对查询和样本进行编码。然而,每个样本包含多个标签,每个标签都由一组不同的关系表示,我们需要在单个向量中捕获这些关系。

协变量编码

此外,我们需要解决前面提到的可伸缩性问题,我们将通过使用 PCA 模块来解决这个问题(当我们使用共现矩阵时,我们可以跳过 PCA,因为不需要压缩我们的向量)。

当标签的数量变得太大时,我们需要放弃计算共现矩阵的可能性,因为它以平方率扩展。因此,我们可以使用预训练的神经网络(PCA 模块的第一步)提取每个现有标签的向量。例如,all-MiniLM-L6-v2 将每个标签转换成长度为 384 的向量。

然后我们可以对得到的矩阵进行转置,并对其进行压缩:我们将对可用的标签索引使用 1 和 0 来初始编码我们的查询/样本,从而得到与我们的初始矩阵(53,300)长度相同的初始向量。此时,我们可以使用预先计算的 PCA 实例将相同的稀疏向量压缩为 384 个像素。

编码样本

在我们的示例中,该过程刚好在 PCA 压缩之后结束(当激活时)。

编码查询:协变量编码

然而,我们的查询需要进行不同的编码:我们需要考虑与每个现有标签相关联的关系。这个过程是通过首先将我们的压缩向量求和到压缩矩阵(所有现有关系的总和)来执行的。现在我们已经得到了一个矩阵(384x384),我们需要对它求平均值,得到我们的查询向量。

因为我们将使用欧几里得搜索,它将首先优先搜索得分最高的特征(理想情况下,是我们使用数字 1 激活的特征),但它也会考虑额外的次要得分。

加权搜索

因为我们是将向量平均在一起,我们甚至可以在这个计算中应用一个权重,向量受到的影响将不同于查询标签。

3.使用向量检索执行语义标签搜索

你可能会问的问题是:为什么我们要经历这种复杂的编码过程,而不是简单地将这对标签输入到一个函数中,然后获得一个分数 ——f(query, sample)?

如果你熟悉基于向量的搜索引擎,你应该已经知道答案了。通过成对执行计算,在只有 40,000 个样本的情况下,所需的计算能力是巨大的(单个查询可能需要长达 10 秒):这不是一个可扩展的实践。然而,如果我们选择执

行 40,000 个样本的向量检索,搜索将在 0.1 秒内完成:这是一个高度可扩展的实践,在我们的情况下是完美的。

4.验证

一个算法要想有效,就需要被验证。目前,我们缺乏适当的数学验证(乍一看,从 M 中平均相似度得分已经显示出非常有希望的结果,但需要进一步的研究来获得有证据支持的客观指标)。

然而,当使用比较示例进行可视化时,现有的结果是相当直观的。以下是两种搜索方法的最热门搜索结果(你所看到的是分配给这个游戏的标签)。

传统标签搜索和语义标签搜索的对比

  1. 传统标签搜索

我们可以看到,传统搜索可能(没有额外的规则,样本是根据所有标签的可用性进行过滤的,而不是排序的)返回一个标签数量较多的样本,但其中许多标签可能不相关。

  • 语义标签搜索

语义标签搜索根据所有标签的相关性对所有样本进行排序,简单来说,它取消了包含不相关标签的样本的资格。

这个新系统的真正优势在于,当传统搜索没有返回足够的样本时,我们可以使用语义标签搜索选择我们想要的尽可能多的样本。

两种搜索的区别在结果的稀缺性面前

在上面的例子中,使用传统的标签过滤不会从 Steam 库中返回任何游戏。然而,通过使用语义标签过滤,我们得到的结果仍然不是完美的,而是与我们的查询匹配的最佳结果。你看到的是匹配我们搜索的前 5 个游戏的标签。

结论

在此之前,如果不采用复杂的方法,如聚类、深度学习或多重 knn 搜索,就不可能同时考虑到它们的语义关系来过滤标签。

该算法提供的灵活性程度应该允许脱离传统的手动标记方法,传统的手动标记方法迫使用户在预定义的标签集之间进行选择,并打开使用 llm 或 vlm

自由地将标签分配给文本或图像的可能性,而不局限于预先存在的结构,为可扩展和改进的搜索方法开辟了新的选择。

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

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

相关文章

娄涵格第一次作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/zjlg/rjjc这个作业的目标 介绍自己。自我评估,期待在课程收获什么,担当什么样的角色姓名-学号 娄涵格-2022329301112自我介绍 1、基本信息 大家好,我的名字是娄涵格,来自浙江台州,目前是浙江理工大学22电气工程及其自…

踩坑日志3:每一个epoch都会重新随机采样,固定batch容易使模型陷入局部解

前几天师弟在机器学习领域看到了一个对样本选择的方法,目的是从特征的角度均匀选择样本。如下图所示,首先初始化将样本的特征进行加和并归一化,迭代取出样本(取值最大的那个样本,再令样本的值乘以1-样本的值更新所有样本)。这般便可以从理论上均匀的取到不同分布的样本,…

动态规划——数学模型精解

动态规划是运筹学的一个分支,主要用于求解多阶段决策过程的优化问题。1950年代初,R.E. Bellman提出了最优性原理,将复杂的多阶段问题分解为一系列单阶段问题逐步求解,开创了动态规划这一方法。1957年,他出版了《Dynamic Programming》,成为该领域的经典著作。动态规划自问…

C#实现系统登录

1, 新建窗口frm_Loginusing System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace WindowsFormsA…

深度学习(FCN)

FCN是全卷积网络,用于做图像语义分割。通常将一般卷积网络最后的全连接层换成上采样或者反卷积网络,对图像的每个像素做分类,从而完成图像分割任务。 网络结构如下:这里并没有完全按照原始网络结构实现,而是尝试upsample和convTranspose2d结合的方式,看看有什么效果。 下…

多线程五-线程通信之wait与notify

wait与notify用于syncronized的线程间通信的一种,wait用来阻塞线程并释放锁,notify用来唤醒线程。他们与condition作用基本一致,但是由于syncronized为jdk实现,阅读源码有难度,所以通过了解其原理,用来帮助我们后续理解condition的源码。 可以通过下面一张图来理解:下面…

帝国cms忘记了后台密码怎么办

如果你忘记了帝国CMS(EmpireCMS)的后台管理员密码,可以通过以下步骤来重置密码: 方法 1: 通过数据库重置密码登录数据库:使用数据库管理工具(如phpMyAdmin)连接到你的数据库。 登录数据库管理界面。找到用户表:通常表名为 phome_enewsuser(具体表名可能有所不同)。 打…

如何恢复对帝国CMS的访问,忘记账号密码的解决方案

如果你忘记了帝国CMS的后台管理员账号和密码,可以通过以下步骤来恢复对系统的访问: 方法 1: 通过数据库重置密码登录数据库:使用数据库管理工具(如phpMyAdmin)连接到你的数据库。 登录数据库管理界面。找到用户表:通常表名为 phome_enewsuser(具体表名可能有所不同)。 …

编程日记 后端tags过滤器

编程日记 后端tags过滤器这样查出来了所有的信息,不对 检查是这个地方有问题改掉 @Overridepublic List<User> searchUsersByTags(List<String> tagNameList) {//1.先查询所有用户QueryWrapper<User> queryWrapper = new QueryWrapper<>();List<Us…

PbootCms忘记后台管理员密码这样找回

如果你忘记了PbootCMS后台管理员的密码,可以通过以下步骤来重置密码: 方法 1: 使用官方提供的密码重置工具下载密码重置工具:下载官方提供的密码重置工具 resetpw.php。 将 resetpw.php 文件上传到网站根目录。访问重置工具:在浏览器中访问 http://[您的域名]/resetpw.php。…

织梦CMS 忘记后台管理员密码的一种解决方法

如果你忘记了织梦CMS(Dedecms)的后台管理员密码,并且拥有对MySQL数据库的操作权限,可以按照以下步骤重置密码: 步骤 1: 登录 MySQL 数据库打开 MySQL 客户端,如 phpMyAdmin 或命令行工具。 登录 MySQL 数据库:sqlmysql -u 用户名 -p输入密码后登录。步骤 2: 选择对应的数…

编程日记 后端使用redis

编程日记 后端使用redis 问题:在写伙伴匹配系统的时候,要使用redis存储数据,需要在xml文件中设置spring.session.tore-type=redis 但是3.x版本的spring不再有这个参数。 那么怎么设置是否使用redis存储呢?只要导入了org.springframework.session包那就启用,不导入就不启用…