ElasticSearch学习篇19_《检索技术核心20讲》搜推广系统设计思想

news2024/12/27 0:25:03

目录

主要是包含搜推广系统的基本模块简单介绍,另有一些流程、设计思想的分析。

  • 搜索引擎
    • 基本模块
    • 检索流程
      • 查询分析
      • 查询纠错
  • 广告引擎
    • 基于标签倒排索引召回
    • 基于向量ANN检索召回
    • 打分机制:非精确打分+精准深度学习模型打分
    • 索引精简:必要的数据构建索引
  • 推荐引擎
    • 基本模块
    • 基于内容的召回
    • 基于协同过滤的召回
      • 基于用户的协同过滤
      • 基于物品的协同过滤
    • 混合召回+分层打分

搜索引擎

搜索引擎的任务是从万亿级别的网页快速查找需要信息,搜索引擎的检索技术是所有基于文本和关键词的检索系统都是可以学习和参考的。

整个检索系统会设计很多技术,比较重要的有网页抓取、文本分析、检索模型、索引技术、链接分析、反作弊、云存储和云计算等,非常复杂。

基本模块

整个检索系统可以按照功能结构分为3部分,分别是爬虫系统、索引系统、检索系统。

  • 爬虫系统:要求能高效爬取数据,并选用高效的存储,如基于LSM的HBase高效的进行写入和读取。
  • 索引系统:为相关文档建立索引,主要包含3个阶段,
    • 1是文档的预处理,包括相似网页去重、网页质量分析、分词处理这些工作。
    • 2是对文档进行反作弊的处理,来避免一些作弊网页干扰搜索结果。
    • 3是生成索引,生成过程包含三个步骤:索引拆分、索引构建、索引更新
      • 索引拆分:文档数据量很大,全部生成索引不太现实,可以根据离线阶段的文档预处理,区分文档质量,比如高质量和低质量,采用分层思想建立索引,另外尽管区分高低质量数据量比较还是比较大需要索引分片。
      • 索引构建:确认了索引的分片机制之后,可以使用Map Reduce服务,为每个索引分片生成对应的任务,然后生成相应的倒排索引文件,每个倒排索引代表一个分片,支持加载到线上服务器。
      • 索引更新:全量索引结合增量索引的机制完成索引更新,一般使用滚动合并法更新。
  • 检索系统:查询分析、查询纠错、查询推荐、召回、打分选取TopK。

检索流程

查询分析

查询词是搜索引擎进行检索的最核心的信息,但是有时候关键词会有错别字,或者是含糊的不精准的,或者查询的关键词不在建立的索引中,如何保证能较准确的检索?

查询分析就是通过输入的查询词理解用户意图,进行查询词纠正,以及对查询意图不明的查询词进行查询推荐,可以分为三个粒度的分析

  • 分词粒度分析:最基础的查询分析,根据查询词按照不同的粒度分词,影响跟索引key匹配的效果,中文搜索中特有的一个环节。一般采用混合粒度分词,也就是标准的分词 + 整个查询词短语 来取匹配索引中的key,比如疾风亦有归途,会被分词 [疾风、归途、疾风亦有归途]
  • 属性分析:数据的某些属性、权重
  • 需求分析:语意级别的意图分析等
关键词位置信息关联性窗口

思考:中文短语是如何检索的?比如查询 “疾风亦有归途”,在构建倒排索引的时候并没有把这个词当作key,直接搜索倒排索引的时候就会找不到,按照混合分词粒度,会接着按照 [疾风,归途] 检索,如果只是简单地将这两个关键词检索出来的文档列表求交集合并,那我们最终得到的结果并不一定会包含带有"疾风亦有归途"的文档,比如搜索到了"xxxx疾风来了,xxxx很多字xxxx,归途",这种并不是期望的结果。

一种解决方案就是记录 关键词出现在文档中的位置,取交集的时候判断一下两个关键词在同一个文档中的距离,距离越小相关性就越小。比如就像包含两个关键词的内容划进去一个窗口,窗口越小,那么证明越相关。

思考:如果是一个查询词被分为了三个关键词?多个关键词,使用查询窗口如何保证顺序?

一种解决方案是两两进行多次计算,最后累加得到一个值。

查询纠错

查询词有错别字,使用查询纠错以及查询推荐优化搜索结果集,查询纠错一般分为三个步骤

  • 错误判断,主要有下面两种方式
    • 基于规则的错误判断:一般根据人工打标的或者搜索日志进行数据挖掘,得到常见的字典和混淆字典,字典的结构可以是哈希表、前缀树等结构保证高效率检索。按照分词结果,如果无法在字典查到,或者出现在混淆字典里面,那么就认为这个查询词是错误的,需要进行下面的步骤。
    • 基于机器学习和语言模型的错误判断,给查询的词一个上下文置信度,置信度低的话判断为错误,需要进行下面的步骤。
  • 候选召回:得到纠错集合,中文的错误一般两种,同音、形近,根据多个同音、形近字典找出多个匹配的key,查询返回候选集合。还有方式是根据编辑距离、根据机器学习等找出候选集的。
  • 打分排序

广告引擎

广告系统是一个典型的高并发低延迟系统,请求量大,对工程和算法有着强烈的依赖,需要做到千人千面。广告系统中负责检索功能的广告引擎架构。

广告引擎处理一个广告请求的过程,本质上就是根据用户的广告请求信息,找出标签匹配的广告设置,并将广告进行排序返回的过程。

广告基本可以分为两类,搜索类广告、展示类广告

  • 搜索类广告:和搜索词关联性比较紧密,类似上面的搜索
  • 展示类广告:请求主要包含手机用户标签,标签和广告匹配,然后投放推送广告。

以展示类广告为例,用户访问网页的时候,这个时候期望在网页推送广告,从用户访问的请求信息能拿到用户ID、网站地址、广告位置ID等,接着广告系统服务端利用之前收集的用户信息标签(喜好、年龄等),从提前分析构建好的标签-具体广告信息设置key-value索引查出相应的广告,然后排序返回,之后就是监测广告的效果如展示、点击等埋点。

基本的流程和上面搜素引擎流程类似,包含构建索引、召回候选集、排序返回TopK,不同的是广告(展示类)没有关键词限制,因此在构建倒排索引上,更加灵活。

基于标签倒排索引召回

按照标签-广告文档构建倒排索引,如某个广告设置的标签是 “地区:开封”,“年龄:25-30”,“性别:男” 这些,那么key就可以为每个标签项设置一个32为ID,前xxx位表示标签名称(定向类型),后xxx为表示标签具体值,这样上面的三个标签以及值分别对应3个32位的ID,可以用作倒排索引的key。

思考:所有的标签(定向类型)都作为key放入倒排索引吗?

这样做会有个问题,就是对于那些区分度不高的标签,往往倒排索引挂的posting list都是很长的,这样多个posting list取交集的时候效率会比较低。

因此一种解决方案是使用TF-IDF(词频逆文档频率)中计算IDF的方式,找出区分度比较低的标签,不将他们加入到倒排索引,而是将这些标签以及下面的广告单独列表存储,在倒排索引求完差集之后,在使用这个 “过滤列表” 对检索结果进行结果过滤。

思考:标签太多归并的效率低?

按照上面的策略,当前倒排索引key是区分度比较大的标签,比如需要推送 “媒体类型:APP” 和 “媒体类型:PC” 两种标签下的广告,并且这两种标签下的广告基本占了全部广告,此时如果想要推送两种标签的广告,归并的效率不是很高。

因此考虑到方案做一个标签树的结构,将树的子节点是哪些具有少量广告的标签,进一步划分父节点标签的广告集,从而进行倒排索引分片。

下面就是 树 + 倒排索引 的结构,我们根据广告请求上的标签,就能快速定位要找的索引分片,之后,再查分片中的倒排索引就能缩小候选集。

思考:如果使用"媒体类型"作为树形检索的节点,"PC网站"和"APP"作为两个分叉,并且允许广告主选择 “既在PC网站投放,又在APP上投放”,如果少量的广告主使用这种投放,索引分片应该如何调整?

不变的策略,每次都需要归并排序求交集。

或者是单独创建一个分片,把归并的数据存起来,不用每次时时归并。

基于向量ANN检索召回

使用广告引擎摆脱传统的标签模式,可以将广告标识转为向量,同时把用户兴趣也转化为一个向量,这样使用ANN紧邻搜索找到最近的点当作结果返回就可以了。

对于传统标签模式,是不具有语义上下文的,比如 标签为 “喜欢篮球的人” 时,如果一个用户身上的标签只有 “喜欢运动” ,那这个广告不会投放给这个用户,会漏掉一些数据,对于向量的ANN,能弥补这个问题。

向量检索同时也会带来性能的压力,可以使用聚类(用于缩小候选集合,减少计算量) + 倒排索引 + 乘积量化(用于压缩存储空间) 的实现方案优化向量检索的效率

参考往期博客:ElasticSearch学习篇17_《检索技术核心20讲》最邻近检索-局部敏感哈希、乘积量化PQ思路-CSDN博客

打分机制:非精准打分 + 精准的深度学习模型打分

相比于搜索引擎期望最后的TopK结果,区别就是广告引擎期望最后的结果一条最相关的即可,因此对于广告引擎的打分机制,我们会使用复杂的深度学习模型来打分。

往往深度学习模型的任务会比较耗时,而广告引擎又要求很高的性能,因此打分之前的候选集不能太大,为了解决这个问题,使用非精准打分 + 深度学习模型精确打分机制进行打分,合理的使用资源。

具体来说,可以基于简单的机器学习模型(如逻辑回归LR,梯度提升决策树GBDT,因子分解机FM等)配合少量的特征,完成这个非精准打分环节,将候选广告的数量限制在几十的量级,然后在使用深度学习模型来进行精准打分,最后选出分数最高的广告。

索引精简:必要的数据构建索引

一般某个广告的生命周期变化非常快,比如广告会设置限定投放的时间段,所以相比于搜索引擎的数据,往往变化更快。

因此除了在线的召回、打分环节的检索效率之外,广告业务的特点使得我们可以在离线的索引构建环节,通过精简索引来优化效率,比如将所有的广告(不考虑时效性)全部都加载到系统中进行检索,然后后面再来一遍遍历过滤判断,就会带来大量的判断开销。

因此一种解决思路就是把在线的开销挪到离线的索引构建环节,这些过滤条件和广告定向类型(标签)并没有联系,完全可以先把不相关的广告不构建索引,这样在线召回、打分的候选集就会减少。

比如下面的经过一系列过滤条件,最下层的索引是需要当前用到的,这个过程是在离线环节完成的。

这种机制的前提是广告引擎需要提供实时高效的索引更新能力,广告投放的数量不想搜索引擎网页数量那个量级,一般可以全部加载到内存,一般使用全量索引结合增量索引的更新机制,就可以对线上的索引进行实时的更新了。

推荐引擎

不同于搜索、广告系统,可以依靠关键词、广告主创建检索约束条件,推荐系统的外界约束条件非常少,比如只有一个下拉刷新的动作,因此搜索引擎的灵活程度更高。

基本模块

  • 用户画像:离线挖掘用户的兴趣标签,生成完整的用户画像,不通的标签有不同的权重,所有的权重会随着时间的变化衰减,比如用户长时间没有这个行为,标签就会逐渐弱化。
  • 文章画像:给文章打标签,除了提取文章的关键词,还需要对文章的语义内容做分析,比如文章分类、主题提取等
  • 推荐算法:主要的算法基本为两类,分别是基于统计的静态召回算法和个性化召回算法。
    • 基于统计的静态召回算法:比如热文推荐,根据离线对文章的统计数据来进行推荐,比如点击两、评论、收藏、收藏率等,然后在线环节推给用户,比较适合个性化召回算法结果不足时候的补充数据。
    • 个性化召回算法:分为基于内容的召回、基于协同过滤的召回。

基于内容的召回

判断文章内容是否符合用户画像,主要就是对比标签了,参考广告引擎的基于标签倒排索引召回。

另外就是使用向量ANN将标签匹配改为高纬向量空间的最近邻检索,弥补标签匹配检索可能漏掉数据的问题。

优缺点

基于协同过滤的召回

协同过滤是推荐系统中代表性方法,协同过滤和基于内容的召回方法最大的区别就是不依赖内容本身来进行推荐,而是基于大众用户和这篇文章的互动关系来推荐。

分为两大类

  • 传统的基于数据统计的“Memory-based 的协同过滤算法”,也叫做基于邻域的算法,代表算法有基于用户的、基于物品的协同过滤。
  • 基于模型的 “Model-based的协同过滤算法”

基于用户的协同过滤

简单来说就是给用户A推送相似用户B的内容。

举个例子比如将用户A画像相似的用户B看过的文章也推荐给用户A,主要操作是找到和用户A 画像相似的B、C、D、E等,找出他们阅读的文章集合TopK推送给用户A。

具体的流程

  1. 对于寻找画像相似的用户集合,可以将画像的各个标签值转为向量,然后ANN搜索,或者计算余弦相似度。
  2. 然后从相似画像用户集合找出具体的文章,然后按照用户喜欢的程度(点赞、收藏、评论等)加权计算找出TopK然后在推送。

问题:计算找出画像相似用户会非常耗时,如何解决?

推荐系统有两种方案

  • 相似计算放在离线环节:离线为每个用户计算出一个推荐文章列表,然后使用key-value数据库快速查询,优点是比较简单效率比较高,缺点是更新不够及时。
  • 实时阶段使用向量检索来近似地完成更新:第一步寻找相似用户的时候先非精确检索,借助 聚类 + 倒排 + 乘积量化 方案快速检索TopK,然后将这些用户对应的文章列表加权打分排序等。优点:时时性比较好,缺点是检索过程比较复杂,结果不够准确。

基于物品的协同过滤

简单来说就是给用户推送物品的A的相似物品B。

具体的流程

  1. 离线寻找相似物品:根据上面矩阵将物品专为向量,纬度按照用户,各纬度值按照用户喜欢的数量作为值转为向量,然后ANN搜索,根据ItemID为key,相似物品列表为posting list。
  2. 在线推送:只要是用户看过的key,就查倒排列表,然后归并计算TopK。

混合召回+分层打分

采用多种方式

首先,每一个召回通路都会使用自己的非精准打分算法,截取千级别之内的候选集。然后,推荐引擎会合并这多个召回通路截取的几千个结果,也就是使用简单的机器学习模型进行非精准打分,选出最好的上百个结果。最后,推荐引擎会使用精准的深度学习模型,选出最好的几十个结果返回给用户。这就是用户看到的最终的推荐结果了。

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

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

相关文章

【尚筹网】五、管理员维护

【尚筹网】五、管理员维护 任务清单分页管理管理员信息目标思路代码引入 PageHelperAdminMapper 中编写 SQL 语句AdminMapper 接口生成方法AdminServiceAdminHandler页面显示主体在页面上使用 Pagination 实现导航条 关键词查询页面上调整表单在翻页时保持关键词查询条件 单条删…

MySQL 启动失败问题分析与解决方案:`mysqld.service failed to run ‘start-pre‘ task`

目录 前言1. 问题背景2. 错误分析2.1 错误信息详解2.2 可能原因 3. 问题排查与解决方案3.1 检查 MySQL 错误日志3.2 验证 MySQL 配置文件3.3 检查文件和目录权限3.4 手动启动 MySQL 服务3.5 修复 systemd 配置文件3.6 验证依赖环境 4. 进一步优化与自动化处理结语 前言 在日常…

Apache storm UI如何更换默认8080端口

在搭建Apache storm环境的时候,遇到Apache storm UI默认端口是8080,但是这个端口会被其他java程序占用,导致Apache storm UI服务无法启动。报错Exception in thread “main” java.lang.RuntimeException: java.io.IOException: Failed to bi…

FPGA实现串口升级及MultiBoot(十)串口升级SPI FLASH实现

本文目录索引 工程架构example9工程设计Vivado设计Vitis设计example9工程验证1、读取FLASH ID2、擦除整个FLASH3、Blank-Check4、烧写Golden区位流5、读取FLASH内容6、烧写MultiBoot区位流(升级位流)7、MultiBoot区位流(升级位流)启动example10工程设计Vivado设计Vitis设计exam…

图解人工智能:从规则到深度学习的全景解析

🌟作者简介:热爱数据分析,学习Python、Stata、SPSS等统计语言的小高同学~🍊个人主页:小高要坚强的博客🍓当前专栏:Python之机器学习🍎本文内容:图解人工智能:…

Binder架构

一、架构 如上图,binder 分为用户层和驱动层两部分,用户层有客户端(Client)、服务端(Server)、服务管理(ServiceManager)。 从用户空间的角度,使用步骤如下(…

基于springboot中小型制造企业质量管理系统源码和论文

信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的…

Flutter 权限申请

这篇文章是基于permission_handler 10.2.0版本写的 前言 在App开发过程中我们经常要用到各种权限,我是用的是permission_handler包来实现权限控制的。 pub地址:https://pub.dev/packages/permission_handler permission_handler 权限列表 变量 Androi…

MATLAB期末复习笔记(下)

五、数据和函数的可视化 1.MATLAB的可视化对象 图形对象是 MATLAB用来创建可视化数据的组件。每个对象都有一个名为句柄 的唯一标识符。使用该句柄,您可以通过设置对象 属性 来操作现有图形对象的特征 ROOT: :即电脑屏幕 Figure :图窗…

web安全从0到1:burp-suite3

声明! 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&a…

深度学习:梯度下降法

损失函数 L:衡量单一训练样例的效果。 成本函数 J:用于衡量 w 和 b 的效果。 如何使用梯度下降法来训练或学习训练集上的参数w和b ? 成本函数J是参数w和b的函数,它被定义为平均值; 损失函数L可以衡量你的算法效果&a…

Linux:文件系统inode

早期,存储文件的设备是磁盘(当下的市场几乎都是SSD),但大家习惯的把它们都称为磁盘,磁盘是用来表示区分内存的存储设备。而在操作系统看来,这个存储设备的结构就是一个线性结构,这一点很重要。 …

94.【C语言】解析预处理(2)

目录 1.带有副作用的宏参数 代码 一个判断最大值的宏代码 运行结果 分析 "副作用"的解释 2.宏替换规则 解释 3.宏和函数的对比 附一张对比表 承接93.【C语言】解析预处理(1)文章 1.带有副作用的宏参数 代码 一个判断最大值的宏代码 #define MAX(a, b) (…

Linux学习笔记12 systemd的其他命令

前文已经介绍了systemd在系统初始化中起到的作用和服务的管理和配置。这里补充一下systemd的其他工具和系统进程的管理 前文 Linux学习笔记10 系统启动初始化,服务和进程管理(上)-CSDN博客 Linux学习笔记11 系统启动初始化,服务…

vue3+ts+uniapp微信小程序顶部导航栏

这是colorui改的&#xff0c;不用就不用看啦 color-ui(https://docs.xzeu.com/#/) 新建component文件夹创建topNavigation.vue <template><view><view class"cu-custom" :style"height: CustomBar px"><view class"cu-bar…

ubuntu20.04更换安装高版本CUDA以及多个CUDA版本管理

Ubuntu 20.04下多版本CUDA的安装与切换 CUDA安装配置环境变量软连接附上参考博客CUDA安装 cuda官方下载地址 因为我需要安装的是11.1版本的,所以这里按着11.1举例安装 安装命令如下: wget https://developer.download.nvidia.com/compute/cuda/11.1.0/local_installers/cu…

C语言——库函数

常用的函数 https://cplusplus.com/reference/ 没事儿多看看 1 数学函数 #include <math.h> #include <stdio.h> int main() {printf("%lf\n", sqrt(4));//开平方根——>double类型printf("%lf\n", pow(2, 10));//求几次方的——>do…

树莓派远程连接方法

1、树莓派端 在树莓派终端&#xff08;Ctrl键alt键T键&#xff09;输入&#xff1a; ipconfig 查看树莓派的IP&#xff0c;记住这个IP号&#xff0c;都是192.168开头的 注意&#xff0c;这里远程连接需要树莓派和电脑在同一网络之下才可以 2、电脑端 我们在电脑上面下载 M…

qt QProxyStyle详解

1、概述 QProxyStyle是Qt框架中QStyle类的一个子类&#xff0c;它提供了一种代理机制&#xff0c;允许开发者在不直接修改现有样式&#xff08;QStyle&#xff09;实现的情况下&#xff0c;对样式行为进行定制或扩展。通过继承QProxyStyle&#xff0c;开发者可以重写其虚方法&…

TCP三次握手与四次挥手(TCP重传机制,2MSL)超详细!!!计算机网络

本篇是关于3次握手和四次挥手的详细解释~ 如果对你有帮助&#xff0c;请点个免费的赞吧&#xff0c;谢谢汪。&#xff08;点个关注也可以&#xff01;&#xff09; 如果以下内容需要补充和修改&#xff0c;请大家在评论区多多交流~。 目录 1. TCP头部&#xff1a; 2. 三次握手…